diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index 900100511e..fac66da910 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -243,13 +243,10 @@ void CPUThread::Stop() m_status = Stopped; - if(CPUThread* thr = GetCurrentCPUThread()) + if(static_cast(this) != GetCurrentNamedThread()) { - if(thr->GetId() != GetId()) - ThreadBase::Stop(); - } - else ThreadBase::Stop(); + } Emu.CheckStatus(); diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index 61310b5b6b..c512d083ea 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -68,7 +68,7 @@ private: const u64 old_sc = CPU.m_last_syscall; CPU.m_last_syscall = sc; - SysCalls::DoSyscall((u32)sc); + SysCalls::DoSyscall(CPU, (u32)sc); if(Ini.HLELogging.GetValue()) { @@ -2093,7 +2093,7 @@ private: case 0x1: UNK(fmt::Format("HyperCall %d", CPU.GPR[0])); break; case 0x2: SysCall(); break; case 0x3: - Emu.GetSFuncManager().StaticExecute((u32)CPU.GPR[11]); + Emu.GetSFuncManager().StaticExecute(CPU, (u32)CPU.GPR[11]); if (Ini.HLELogging.GetValue()) { LOG_NOTICE(PPU, "'%s' done with code[0x%llx]! #pc: 0x%x", diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 9c94761a49..0fb4e2867b 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -807,5 +807,3 @@ protected: }; PPUThread& GetCurrentPPUThread(); - -#define declCPU PPUThread& CPU = GetCurrentPPUThread diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 75ea92784c..f7dc30ca73 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -589,7 +589,7 @@ void SPUThread::WriteChannel(u32 ch, const u128& r) return; } - if (!port.eq->events.push(SYS_SPU_THREAD_EVENT_USER_KEY, GetCurrentCPUThread()->GetId(), ((u64)spup << 32) | (v & 0x00ffffff), data)) + if (!port.eq->events.push(SYS_SPU_THREAD_EVENT_USER_KEY, GetId(), ((u64)spup << 32) | (v & 0x00ffffff), data)) { SPU.In_MBox.PushUncond(CELL_EBUSY); return; @@ -627,7 +627,7 @@ void SPUThread::WriteChannel(u32 ch, const u128& r) } // TODO: check passing spup value - if (!port.eq->events.push(SYS_SPU_THREAD_EVENT_USER_KEY, GetCurrentCPUThread()->GetId(), ((u64)spup << 32) | (v & 0x00ffffff), data)) + if (!port.eq->events.push(SYS_SPU_THREAD_EVENT_USER_KEY, GetId(), ((u64)spup << 32) | (v & 0x00ffffff), data)) { LOG_WARNING(Log::SPU, "sys_spu_thread_throw_event(spup=%d, data0=0x%x, data1=0x%x) failed (queue is full)", spup, (v & 0x00ffffff), data); return; @@ -666,7 +666,7 @@ void SPUThread::WriteChannel(u32 ch, const u128& r) return; } - u32 tid = GetCurrentCPUThread()->GetId(); + const u32 tid = GetId(); ef->m_mutex.lock(tid); ef->flags |= (u64)1 << flag; @@ -714,7 +714,7 @@ void SPUThread::WriteChannel(u32 ch, const u128& r) return; } - u32 tid = GetCurrentCPUThread()->GetId(); + const u32 tid = GetId(); ef->m_mutex.lock(tid); ef->flags |= (u64)1 << flag; diff --git a/rpcs3/Emu/SysCalls/ModuleManager.cpp b/rpcs3/Emu/SysCalls/ModuleManager.cpp index f3396ecb7e..c312310e43 100644 --- a/rpcs3/Emu/SysCalls/ModuleManager.cpp +++ b/rpcs3/Emu/SysCalls/ModuleManager.cpp @@ -224,7 +224,7 @@ bool ModuleManager::IsLoadedFunc(u32 id) const return false; } -bool ModuleManager::CallFunc(u32 num) +bool ModuleManager::CallFunc(PPUThread& CPU, u32 num) { func_caller* func = nullptr; { @@ -242,7 +242,7 @@ bool ModuleManager::CallFunc(u32 num) if (func) { - (*func)(); + (*func)(CPU); return true; } return false; diff --git a/rpcs3/Emu/SysCalls/ModuleManager.h b/rpcs3/Emu/SysCalls/ModuleManager.h index a7acec1c22..33034a9739 100644 --- a/rpcs3/Emu/SysCalls/ModuleManager.h +++ b/rpcs3/Emu/SysCalls/ModuleManager.h @@ -18,7 +18,7 @@ public: void AddFunc(ModuleFunc *func); void SetModule(u16 id, Module* module);//insert into m_modules bool IsLoadedFunc(u32 id) const; - bool CallFunc(u32 num); + bool CallFunc(PPUThread& CPU, u32 num); bool UnloadFunc(u32 id); void UnloadModules(); u32 GetFuncNumById(u32 id); diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp index 8db8c9bf91..618be0c3c2 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp @@ -529,8 +529,7 @@ int cellSurMixerStart() int cellSurMixerSetParameter(u32 param, float value) { - declCPU(); - libmixer->Todo("cellSurMixerSetParameter(param=0x%x, value=%f, FPR[1]=%f, FPR[2]=%f)", param, value, (float&)CPU.FPR[1], (float&)CPU.FPR[2]); + libmixer->Todo("cellSurMixerSetParameter(param=0x%x, value=%f)", param, value); return CELL_OK; } @@ -616,28 +615,25 @@ void cellSurMixerBeep(u32 arg) return; } -void cellSurMixerUtilGetLevelFromDB(float dB) +float cellSurMixerUtilGetLevelFromDB(float dB) { // not hooked, probably unnecessary libmixer->Todo("cellSurMixerUtilGetLevelFromDB(dB=%f)", dB); - declCPU(); - (float&)CPU.FPR[0] = 0.0f; + return 0.0f; } -void cellSurMixerUtilGetLevelFromDBIndex(int index) +float cellSurMixerUtilGetLevelFromDBIndex(s32 index) { // not hooked, probably unnecessary libmixer->Todo("cellSurMixerUtilGetLevelFromDBIndex(index=%d)", index); - declCPU(); - (float&)CPU.FPR[0] = 0.0f; + return 0.0f; } -void cellSurMixerUtilNoteToRatio(u8 refNote, u8 note) +float cellSurMixerUtilNoteToRatio(u8 refNote, u8 note) { // not hooked, probably unnecessary libmixer->Todo("cellSurMixerUtilNoteToRatio(refNote=%d, note=%d)", refNote, note); - declCPU(); - (float&)CPU.FPR[0] = 0.0f; + return 0.0f; } void libmixer_init(Module *pxThis) diff --git a/rpcs3/Emu/SysCalls/SC_FUNC.h b/rpcs3/Emu/SysCalls/SC_FUNC.h index 146a44131c..fbb3e676eb 100644 --- a/rpcs3/Emu/SysCalls/SC_FUNC.h +++ b/rpcs3/Emu/SysCalls/SC_FUNC.h @@ -4,7 +4,7 @@ class func_caller { public: - virtual void operator()() = 0; + virtual void operator()(PPUThread& CPU) = 0; virtual ~func_caller(){}; }; @@ -169,13 +169,31 @@ namespace detail { } - virtual void operator()() + virtual void operator()(PPUThread& CPU) { - declCPU(); call(m_call, iterate<0, 0, 0, T...>(CPU)); } }; + template + class func_binder : public func_caller + { + typedef void(*func_t)(PPUThread&, T...); + const func_t m_call; + + public: + func_binder(func_t call) + : func_caller() + , m_call(call) + { + } + + virtual void operator()(PPUThread& CPU) + { + call(m_call, std::tuple_cat(std::tuple(CPU), iterate<0, 0, 0, T...>(CPU))); + } + }; + template class func_binder : public func_caller { @@ -189,9 +207,8 @@ namespace detail { } - virtual void operator()() + virtual void operator()(PPUThread& CPU) { - declCPU(); static_assert(!std::is_pointer::value, "Invalid function result type (pointer)"); static_assert(!std::is_reference::value, "Invalid function result type (reference)"); const bool is_float = std::is_floating_point::value; @@ -201,6 +218,31 @@ namespace detail bind_result::func(CPU, call(m_call, iterate<0, 0, 0, T...>(CPU))); } }; + + template + class func_binder : public func_caller + { + typedef RT(*func_t)(PPUThread&, T...); + const func_t m_call; + + public: + func_binder(func_t call) + : func_caller() + , m_call(call) + { + } + + virtual void operator()(PPUThread& CPU) + { + static_assert(!std::is_pointer::value, "Invalid function result type (pointer)"); + static_assert(!std::is_reference::value, "Invalid function result type (reference)"); + const bool is_float = std::is_floating_point::value; + const bool is_vector = std::is_same::value; + const bind_arg_type t = is_float ? ARG_FLOAT : (is_vector ? ARG_VECTOR : ARG_GENERAL); + + bind_result::func(CPU, call(m_call, std::tuple_cat(std::tuple(CPU), iterate<0, 0, 0, T...>(CPU)))); + } + }; } template diff --git a/rpcs3/Emu/SysCalls/Static.cpp b/rpcs3/Emu/SysCalls/Static.cpp index e662440431..9ea47550cb 100644 --- a/rpcs3/Emu/SysCalls/Static.cpp +++ b/rpcs3/Emu/SysCalls/Static.cpp @@ -179,11 +179,11 @@ void StaticFuncManager::StaticAnalyse(void* ptr, u32 size, u32 base) } } -void StaticFuncManager::StaticExecute(u32 code) +void StaticFuncManager::StaticExecute(PPUThread& CPU, u32 code) { if (code < m_static_funcs_list.size()) { - (*m_static_funcs_list[code]->func)(); + (*m_static_funcs_list[code]->func)(CPU); } else { diff --git a/rpcs3/Emu/SysCalls/Static.h b/rpcs3/Emu/SysCalls/Static.h index 4fd9a6142a..5714148455 100644 --- a/rpcs3/Emu/SysCalls/Static.h +++ b/rpcs3/Emu/SysCalls/Static.h @@ -2,12 +2,14 @@ struct SFunc; +class PPUThread; + class StaticFuncManager { std::vector m_static_funcs_list; public: void StaticAnalyse(void* ptr, u32 size, u32 base); - void StaticExecute(u32 code); + void StaticExecute(PPUThread& CPU, u32 code); void StaticFinalize(); void push_back(SFunc *ele); SFunc *operator[](size_t i); diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index 2019e4c34b..e26f3597ff 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -11,8 +11,6 @@ #include "lv2/sys_event.h" #include "lv2/sys_event_flag.h" #include "lv2/sys_interrupt.h" -//#include "lv2/sys_lwcond.h" -//#include "lv2/sys_lwmutex.h" #include "lv2/sys_memory.h" #include "lv2/sys_mmapper.h" #include "lv2/sys_ppu_thread.h" @@ -37,7 +35,7 @@ namespace detail{ } } -void default_syscall(); +void default_syscall(PPUThread& CPU); static func_caller *null_func = bind_func(default_syscall); static const int kSyscallTableLength = 1024; @@ -153,12 +151,12 @@ static func_caller* sc_table[kSyscallTableLength] = bind_func(sys_cond_signal), //108 (0x06C) bind_func(sys_cond_signal_all), //109 (0x06D) bind_func(sys_cond_signal_to), //110 (0x06E) - null_func,//bind_func(sys_lwcond_create) //111 (0x06F) - null_func,//bind_func(sys_lwcond_destroy) //112 (0x070) - null_func,//bind_func(sys_lwcond_queue_wait) //113 (0x071) + null_func,//bind_func(sys_lwcond_create) //111 (0x06F) // internal, used by sys_lwcond_create + null_func,//bind_func(sys_lwcond_destroy) //112 (0x070) // internal, used by sys_lwcond_destroy + null_func,//bind_func(sys_lwcond_queue_wait) //113 (0x071) // internal, used by sys_lwcond_wait bind_func(sys_semaphore_get_value), //114 (0x072) - null_func,//bind_func(sys_semaphore_...) //115 (0x073) - null_func,//bind_func(sys_semaphore_...) //116 (0x074) + null_func,//bind_func(sys_semaphore_...) //115 (0x073) // internal, used by sys_lwcond_signal, sys_lwcond_signal_to + null_func,//bind_func(sys_semaphore_...) //116 (0x074) // internal, used by sys_lwcond_signal_all null_func,//bind_func(sys_semaphore_...) //117 (0x075) // internal, used by sys_lwmutex_unlock bind_func(sys_event_flag_clear), //118 (0x076) null_func,//bind_func(sys_event_...) //119 (0x077) ROOT @@ -912,9 +910,8 @@ struct SyscallTableCleaner_t } } SyscallTableCleaner_t; -void default_syscall() +void default_syscall(PPUThread& CPU) { - declCPU(); u32 code = (u32)CPU.GPR[11]; //TODO: remove this switch(code) @@ -943,25 +940,24 @@ void default_syscall() return; } -void SysCalls::DoSyscall(u32 code) +void SysCalls::DoSyscall(PPUThread& CPU, u32 code) { //Auto Pause using simple singleton. Debug::AutoPause::getInstance().TryPause(code); if(code < 1024) { - (*sc_table[code])(); + (*sc_table[code])(CPU); return; } - if(Emu.GetModuleManager().CallFunc(code)) + if(Emu.GetModuleManager().CallFunc(CPU, code)) { return; } LOG_ERROR(HLE, "TODO: %s", GetHLEFuncName(code).c_str()); - declCPU(); CPU.GPR[3] = 0; } diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index 514e36ddd6..bfeeed3434 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -60,9 +60,11 @@ public: extern bool dump_enable; +class PPUThread; + class SysCalls { public: - static void DoSyscall(u32 code); + static void DoSyscall(PPUThread& CPU, u32 code); static std::string GetHLEFuncName(const u32 fid); }; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp index 0ab41ee220..7f21a920e7 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp @@ -103,7 +103,7 @@ s32 sys_cond_signal_all(u32 cond_id) while (u32 target = (mutex->protocol == SYS_SYNC_PRIORITY ? cond->m_queue.pop_prio() : cond->m_queue.pop())) { - cond->signaler = GetCurrentCPUThread()->GetId(); + cond->signaler = GetCurrentPPUThread().GetId(); //cond->signal_stamp = get_system_time(); cond->signal.lock(target); Emu.GetCPU().NotifyThread(target); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp index 6dca976a72..c63b93bcfd 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp @@ -2,6 +2,7 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/SysCalls.h" +#include "Emu/SysCalls/Callback.h" #include "Emu/CPU/CPUThreadManager.h" #include "Emu/Cell/PPUThread.h" @@ -11,33 +12,30 @@ static SysCallBase sys_ppu_thread("sys_ppu_thread"); static const u32 PPU_THREAD_ID_INVALID = 0xFFFFFFFFU/*UUUUUUUUUUuuuuuuuuuu~~~~~~~~*/; -void ppu_thread_exit(u64 errorcode) +void ppu_thread_exit(PPUThread& CPU, u64 errorcode) { - PPUThread& thr = GetCurrentPPUThread(); - u32 tid = thr.GetId(); - - if (thr.owned_mutexes) + if (CPU.owned_mutexes) { - sys_ppu_thread.Error("Owned mutexes found (%d)", thr.owned_mutexes); - thr.owned_mutexes = 0; + sys_ppu_thread.Error("Owned mutexes found (%d)", CPU.owned_mutexes); + CPU.owned_mutexes = 0; } - thr.SetExitStatus(errorcode); - thr.Stop(); + CPU.SetExitStatus(errorcode); + CPU.Stop(); } -void sys_ppu_thread_exit(u64 errorcode) +void sys_ppu_thread_exit(PPUThread& CPU, u64 errorcode) { sys_ppu_thread.Log("sys_ppu_thread_exit(0x%llx)", errorcode); - ppu_thread_exit(errorcode); + ppu_thread_exit(CPU, errorcode); } -void sys_internal_ppu_thread_exit(u64 errorcode) +void sys_internal_ppu_thread_exit(PPUThread& CPU, u64 errorcode) { sys_ppu_thread.Log("sys_internal_ppu_thread_exit(0x%llx)", errorcode); - ppu_thread_exit(errorcode); + ppu_thread_exit(CPU, errorcode); } s32 sys_ppu_thread_yield() @@ -83,10 +81,11 @@ s32 sys_ppu_thread_detach(u64 thread_id) return CELL_OK; } -void sys_ppu_thread_get_join_state(u32 isjoinable_addr) +void sys_ppu_thread_get_join_state(PPUThread& CPU, vm::ptr isjoinable) { - sys_ppu_thread.Warning("sys_ppu_thread_get_join_state(isjoinable_addr=0x%x)", isjoinable_addr); - vm::write32(isjoinable_addr, GetCurrentPPUThread().IsJoinable()); + sys_ppu_thread.Warning("sys_ppu_thread_get_join_state(isjoinable_addr=0x%x)", isjoinable.addr()); + + *isjoinable = CPU.IsJoinable(); } s32 sys_ppu_thread_set_priority(u64 thread_id, s32 prio) @@ -113,12 +112,10 @@ s32 sys_ppu_thread_get_priority(u64 thread_id, u32 prio_addr) return CELL_OK; } -s32 sys_ppu_thread_get_stack_information(u32 info_addr) +s32 sys_ppu_thread_get_stack_information(PPUThread& CPU, u32 info_addr) { sys_ppu_thread.Log("sys_ppu_thread_get_stack_information(info_addr=0x%x)", info_addr); - declCPU(); - vm::write32(info_addr, (u32)CPU.GetStackAddr()); vm::write32(info_addr + 4, CPU.GetStackSize()); @@ -203,22 +200,22 @@ s32 sys_ppu_thread_create(vm::ptr> thread_id, u32 entry, u64 arg, s32 return CELL_OK; } -void sys_ppu_thread_once(vm::ptr>> once_ctrl, u32 entry) +void sys_ppu_thread_once(PPUThread& CPU, vm::ptr>> once_ctrl, vm::ptr init) { - sys_ppu_thread.Warning("sys_ppu_thread_once(once_ctrl_addr=0x%x, entry=0x%x)", once_ctrl.addr(), entry); + sys_ppu_thread.Warning("sys_ppu_thread_once(once_ctrl_addr=0x%x, init_addr=0x%x)", once_ctrl.addr(), init.addr()); be_t old = be_t::MakeFromBE(se32(SYS_PPU_THREAD_ONCE_INIT)); if (once_ctrl->compare_exchange_weak(old, be_t::MakeFromBE(se32(SYS_PPU_THREAD_DONE_INIT)))) { - GetCurrentPPUThread().FastCall2(vm::read32(entry), vm::read32(entry + 4)); + init.call(CPU); } } -s32 sys_ppu_thread_get_id(vm::ptr> thread_id) +s32 sys_ppu_thread_get_id(PPUThread& CPU, vm::ptr> thread_id) { sys_ppu_thread.Log("sys_ppu_thread_get_id(thread_id_addr=0x%x)", thread_id.addr()); - *thread_id = GetCurrentPPUThread().GetId(); + *thread_id = CPU.GetId(); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h index f075612f13..0bbe4aabc3 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h @@ -13,18 +13,18 @@ enum ppu_thread_flags : u64 }; // SysCalls -void sys_ppu_thread_exit(u64 errorcode); -void sys_internal_ppu_thread_exit(u64 errorcode); +void sys_ppu_thread_exit(PPUThread& CPU, u64 errorcode); +void sys_internal_ppu_thread_exit(PPUThread& CPU, u64 errorcode); s32 sys_ppu_thread_yield(); s32 sys_ppu_thread_join(u64 thread_id, vm::ptr> vptr); s32 sys_ppu_thread_detach(u64 thread_id); -void sys_ppu_thread_get_join_state(u32 isjoinable_addr); +void sys_ppu_thread_get_join_state(PPUThread& CPU, vm::ptr isjoinable); s32 sys_ppu_thread_set_priority(u64 thread_id, s32 prio); s32 sys_ppu_thread_get_priority(u64 thread_id, u32 prio_addr); -s32 sys_ppu_thread_get_stack_information(u32 info_addr); +s32 sys_ppu_thread_get_stack_information(PPUThread& CPU, u32 info_addr); s32 sys_ppu_thread_stop(u64 thread_id); s32 sys_ppu_thread_restart(u64 thread_id); s32 sys_ppu_thread_create(vm::ptr> thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::ptr threadname); -void sys_ppu_thread_once(vm::ptr>> once_ctrl, u32 entry); -s32 sys_ppu_thread_get_id(vm::ptr> thread_id); +void sys_ppu_thread_once(PPUThread& CPU, vm::ptr>> once_ctrl, vm::ptr init); +s32 sys_ppu_thread_get_id(PPUThread& CPU, vm::ptr> thread_id); s32 sys_ppu_thread_rename(u64 thread_id, vm::ptr name);