mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-16 03:38:38 +12:00
declCPU removed, PPUThread& is passed as argument
Added experimental feature: passing PPUThread& to syscall
This commit is contained in:
parent
8cc09d1c91
commit
626133c0eb
15 changed files with 111 additions and 81 deletions
|
@ -243,13 +243,10 @@ void CPUThread::Stop()
|
||||||
|
|
||||||
m_status = Stopped;
|
m_status = Stopped;
|
||||||
|
|
||||||
if(CPUThread* thr = GetCurrentCPUThread())
|
if(static_cast<NamedThreadBase*>(this) != GetCurrentNamedThread())
|
||||||
{
|
{
|
||||||
if(thr->GetId() != GetId())
|
|
||||||
ThreadBase::Stop();
|
ThreadBase::Stop();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
ThreadBase::Stop();
|
|
||||||
|
|
||||||
Emu.CheckStatus();
|
Emu.CheckStatus();
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ private:
|
||||||
const u64 old_sc = CPU.m_last_syscall;
|
const u64 old_sc = CPU.m_last_syscall;
|
||||||
|
|
||||||
CPU.m_last_syscall = sc;
|
CPU.m_last_syscall = sc;
|
||||||
SysCalls::DoSyscall((u32)sc);
|
SysCalls::DoSyscall(CPU, (u32)sc);
|
||||||
|
|
||||||
if(Ini.HLELogging.GetValue())
|
if(Ini.HLELogging.GetValue())
|
||||||
{
|
{
|
||||||
|
@ -2093,7 +2093,7 @@ private:
|
||||||
case 0x1: UNK(fmt::Format("HyperCall %d", CPU.GPR[0])); break;
|
case 0x1: UNK(fmt::Format("HyperCall %d", CPU.GPR[0])); break;
|
||||||
case 0x2: SysCall(); break;
|
case 0x2: SysCall(); break;
|
||||||
case 0x3:
|
case 0x3:
|
||||||
Emu.GetSFuncManager().StaticExecute((u32)CPU.GPR[11]);
|
Emu.GetSFuncManager().StaticExecute(CPU, (u32)CPU.GPR[11]);
|
||||||
if (Ini.HLELogging.GetValue())
|
if (Ini.HLELogging.GetValue())
|
||||||
{
|
{
|
||||||
LOG_NOTICE(PPU, "'%s' done with code[0x%llx]! #pc: 0x%x",
|
LOG_NOTICE(PPU, "'%s' done with code[0x%llx]! #pc: 0x%x",
|
||||||
|
|
|
@ -807,5 +807,3 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
PPUThread& GetCurrentPPUThread();
|
PPUThread& GetCurrentPPUThread();
|
||||||
|
|
||||||
#define declCPU PPUThread& CPU = GetCurrentPPUThread
|
|
||||||
|
|
|
@ -589,7 +589,7 @@ void SPUThread::WriteChannel(u32 ch, const u128& r)
|
||||||
return;
|
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);
|
SPU.In_MBox.PushUncond(CELL_EBUSY);
|
||||||
return;
|
return;
|
||||||
|
@ -627,7 +627,7 @@ void SPUThread::WriteChannel(u32 ch, const u128& r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check passing spup value
|
// 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);
|
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;
|
return;
|
||||||
|
@ -666,7 +666,7 @@ void SPUThread::WriteChannel(u32 ch, const u128& r)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 tid = GetCurrentCPUThread()->GetId();
|
const u32 tid = GetId();
|
||||||
|
|
||||||
ef->m_mutex.lock(tid);
|
ef->m_mutex.lock(tid);
|
||||||
ef->flags |= (u64)1 << flag;
|
ef->flags |= (u64)1 << flag;
|
||||||
|
@ -714,7 +714,7 @@ void SPUThread::WriteChannel(u32 ch, const u128& r)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 tid = GetCurrentCPUThread()->GetId();
|
const u32 tid = GetId();
|
||||||
|
|
||||||
ef->m_mutex.lock(tid);
|
ef->m_mutex.lock(tid);
|
||||||
ef->flags |= (u64)1 << flag;
|
ef->flags |= (u64)1 << flag;
|
||||||
|
|
|
@ -224,7 +224,7 @@ bool ModuleManager::IsLoadedFunc(u32 id) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModuleManager::CallFunc(u32 num)
|
bool ModuleManager::CallFunc(PPUThread& CPU, u32 num)
|
||||||
{
|
{
|
||||||
func_caller* func = nullptr;
|
func_caller* func = nullptr;
|
||||||
{
|
{
|
||||||
|
@ -242,7 +242,7 @@ bool ModuleManager::CallFunc(u32 num)
|
||||||
|
|
||||||
if (func)
|
if (func)
|
||||||
{
|
{
|
||||||
(*func)();
|
(*func)(CPU);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -18,7 +18,7 @@ public:
|
||||||
void AddFunc(ModuleFunc *func);
|
void AddFunc(ModuleFunc *func);
|
||||||
void SetModule(u16 id, Module* module);//insert into m_modules
|
void SetModule(u16 id, Module* module);//insert into m_modules
|
||||||
bool IsLoadedFunc(u32 id) const;
|
bool IsLoadedFunc(u32 id) const;
|
||||||
bool CallFunc(u32 num);
|
bool CallFunc(PPUThread& CPU, u32 num);
|
||||||
bool UnloadFunc(u32 id);
|
bool UnloadFunc(u32 id);
|
||||||
void UnloadModules();
|
void UnloadModules();
|
||||||
u32 GetFuncNumById(u32 id);
|
u32 GetFuncNumById(u32 id);
|
||||||
|
|
|
@ -529,8 +529,7 @@ int cellSurMixerStart()
|
||||||
|
|
||||||
int cellSurMixerSetParameter(u32 param, float value)
|
int cellSurMixerSetParameter(u32 param, float value)
|
||||||
{
|
{
|
||||||
declCPU();
|
libmixer->Todo("cellSurMixerSetParameter(param=0x%x, value=%f)", param, value);
|
||||||
libmixer->Todo("cellSurMixerSetParameter(param=0x%x, value=%f, FPR[1]=%f, FPR[2]=%f)", param, value, (float&)CPU.FPR[1], (float&)CPU.FPR[2]);
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,28 +615,25 @@ void cellSurMixerBeep(u32 arg)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cellSurMixerUtilGetLevelFromDB(float dB)
|
float cellSurMixerUtilGetLevelFromDB(float dB)
|
||||||
{
|
{
|
||||||
// not hooked, probably unnecessary
|
// not hooked, probably unnecessary
|
||||||
libmixer->Todo("cellSurMixerUtilGetLevelFromDB(dB=%f)", dB);
|
libmixer->Todo("cellSurMixerUtilGetLevelFromDB(dB=%f)", dB);
|
||||||
declCPU();
|
return 0.0f;
|
||||||
(float&)CPU.FPR[0] = 0.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cellSurMixerUtilGetLevelFromDBIndex(int index)
|
float cellSurMixerUtilGetLevelFromDBIndex(s32 index)
|
||||||
{
|
{
|
||||||
// not hooked, probably unnecessary
|
// not hooked, probably unnecessary
|
||||||
libmixer->Todo("cellSurMixerUtilGetLevelFromDBIndex(index=%d)", index);
|
libmixer->Todo("cellSurMixerUtilGetLevelFromDBIndex(index=%d)", index);
|
||||||
declCPU();
|
return 0.0f;
|
||||||
(float&)CPU.FPR[0] = 0.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cellSurMixerUtilNoteToRatio(u8 refNote, u8 note)
|
float cellSurMixerUtilNoteToRatio(u8 refNote, u8 note)
|
||||||
{
|
{
|
||||||
// not hooked, probably unnecessary
|
// not hooked, probably unnecessary
|
||||||
libmixer->Todo("cellSurMixerUtilNoteToRatio(refNote=%d, note=%d)", refNote, note);
|
libmixer->Todo("cellSurMixerUtilNoteToRatio(refNote=%d, note=%d)", refNote, note);
|
||||||
declCPU();
|
return 0.0f;
|
||||||
(float&)CPU.FPR[0] = 0.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void libmixer_init(Module *pxThis)
|
void libmixer_init(Module *pxThis)
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
class func_caller
|
class func_caller
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void operator()() = 0;
|
virtual void operator()(PPUThread& CPU) = 0;
|
||||||
virtual ~func_caller(){};
|
virtual ~func_caller(){};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -169,13 +169,31 @@ namespace detail
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void operator()()
|
virtual void operator()(PPUThread& CPU)
|
||||||
{
|
{
|
||||||
declCPU();
|
|
||||||
call<void>(m_call, iterate<0, 0, 0, T...>(CPU));
|
call<void>(m_call, iterate<0, 0, 0, T...>(CPU));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename... T>
|
||||||
|
class func_binder<void, PPUThread&, T...> : 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<void>(m_call, std::tuple_cat(std::tuple<PPUThread&>(CPU), iterate<0, 0, 0, T...>(CPU)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename RT, typename... T>
|
template<typename RT, typename... T>
|
||||||
class func_binder : public func_caller
|
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<RT>::value, "Invalid function result type (pointer)");
|
static_assert(!std::is_pointer<RT>::value, "Invalid function result type (pointer)");
|
||||||
static_assert(!std::is_reference<RT>::value, "Invalid function result type (reference)");
|
static_assert(!std::is_reference<RT>::value, "Invalid function result type (reference)");
|
||||||
const bool is_float = std::is_floating_point<RT>::value;
|
const bool is_float = std::is_floating_point<RT>::value;
|
||||||
|
@ -201,6 +218,31 @@ namespace detail
|
||||||
bind_result<RT, t>::func(CPU, call<RT>(m_call, iterate<0, 0, 0, T...>(CPU)));
|
bind_result<RT, t>::func(CPU, call<RT>(m_call, iterate<0, 0, 0, T...>(CPU)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename RT, typename... T>
|
||||||
|
class func_binder<RT, PPUThread&, T...> : 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<RT>::value, "Invalid function result type (pointer)");
|
||||||
|
static_assert(!std::is_reference<RT>::value, "Invalid function result type (reference)");
|
||||||
|
const bool is_float = std::is_floating_point<RT>::value;
|
||||||
|
const bool is_vector = std::is_same<RT, u128>::value;
|
||||||
|
const bind_arg_type t = is_float ? ARG_FLOAT : (is_vector ? ARG_VECTOR : ARG_GENERAL);
|
||||||
|
|
||||||
|
bind_result<RT, t>::func(CPU, call<RT>(m_call, std::tuple_cat(std::tuple<PPUThread&>(CPU), iterate<0, 0, 0, T...>(CPU))));
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RT, typename... T>
|
template<typename RT, typename... T>
|
||||||
|
|
|
@ -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())
|
if (code < m_static_funcs_list.size())
|
||||||
{
|
{
|
||||||
(*m_static_funcs_list[code]->func)();
|
(*m_static_funcs_list[code]->func)(CPU);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,12 +2,14 @@
|
||||||
|
|
||||||
struct SFunc;
|
struct SFunc;
|
||||||
|
|
||||||
|
class PPUThread;
|
||||||
|
|
||||||
class StaticFuncManager
|
class StaticFuncManager
|
||||||
{
|
{
|
||||||
std::vector<SFunc *> m_static_funcs_list;
|
std::vector<SFunc *> m_static_funcs_list;
|
||||||
public:
|
public:
|
||||||
void StaticAnalyse(void* ptr, u32 size, u32 base);
|
void StaticAnalyse(void* ptr, u32 size, u32 base);
|
||||||
void StaticExecute(u32 code);
|
void StaticExecute(PPUThread& CPU, u32 code);
|
||||||
void StaticFinalize();
|
void StaticFinalize();
|
||||||
void push_back(SFunc *ele);
|
void push_back(SFunc *ele);
|
||||||
SFunc *operator[](size_t i);
|
SFunc *operator[](size_t i);
|
||||||
|
|
|
@ -11,8 +11,6 @@
|
||||||
#include "lv2/sys_event.h"
|
#include "lv2/sys_event.h"
|
||||||
#include "lv2/sys_event_flag.h"
|
#include "lv2/sys_event_flag.h"
|
||||||
#include "lv2/sys_interrupt.h"
|
#include "lv2/sys_interrupt.h"
|
||||||
//#include "lv2/sys_lwcond.h"
|
|
||||||
//#include "lv2/sys_lwmutex.h"
|
|
||||||
#include "lv2/sys_memory.h"
|
#include "lv2/sys_memory.h"
|
||||||
#include "lv2/sys_mmapper.h"
|
#include "lv2/sys_mmapper.h"
|
||||||
#include "lv2/sys_ppu_thread.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 func_caller *null_func = bind_func(default_syscall);
|
||||||
|
|
||||||
static const int kSyscallTableLength = 1024;
|
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), //108 (0x06C)
|
||||||
bind_func(sys_cond_signal_all), //109 (0x06D)
|
bind_func(sys_cond_signal_all), //109 (0x06D)
|
||||||
bind_func(sys_cond_signal_to), //110 (0x06E)
|
bind_func(sys_cond_signal_to), //110 (0x06E)
|
||||||
null_func,//bind_func(sys_lwcond_create) //111 (0x06F)
|
null_func,//bind_func(sys_lwcond_create) //111 (0x06F) // internal, used by sys_lwcond_create
|
||||||
null_func,//bind_func(sys_lwcond_destroy) //112 (0x070)
|
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)
|
null_func,//bind_func(sys_lwcond_queue_wait) //113 (0x071) // internal, used by sys_lwcond_wait
|
||||||
bind_func(sys_semaphore_get_value), //114 (0x072)
|
bind_func(sys_semaphore_get_value), //114 (0x072)
|
||||||
null_func,//bind_func(sys_semaphore_...) //115 (0x073)
|
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)
|
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
|
null_func,//bind_func(sys_semaphore_...) //117 (0x075) // internal, used by sys_lwmutex_unlock
|
||||||
bind_func(sys_event_flag_clear), //118 (0x076)
|
bind_func(sys_event_flag_clear), //118 (0x076)
|
||||||
null_func,//bind_func(sys_event_...) //119 (0x077) ROOT
|
null_func,//bind_func(sys_event_...) //119 (0x077) ROOT
|
||||||
|
@ -912,9 +910,8 @@ struct SyscallTableCleaner_t
|
||||||
}
|
}
|
||||||
} SyscallTableCleaner_t;
|
} SyscallTableCleaner_t;
|
||||||
|
|
||||||
void default_syscall()
|
void default_syscall(PPUThread& CPU)
|
||||||
{
|
{
|
||||||
declCPU();
|
|
||||||
u32 code = (u32)CPU.GPR[11];
|
u32 code = (u32)CPU.GPR[11];
|
||||||
//TODO: remove this
|
//TODO: remove this
|
||||||
switch(code)
|
switch(code)
|
||||||
|
@ -943,25 +940,24 @@ void default_syscall()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SysCalls::DoSyscall(u32 code)
|
void SysCalls::DoSyscall(PPUThread& CPU, u32 code)
|
||||||
{
|
{
|
||||||
//Auto Pause using simple singleton.
|
//Auto Pause using simple singleton.
|
||||||
Debug::AutoPause::getInstance().TryPause(code);
|
Debug::AutoPause::getInstance().TryPause(code);
|
||||||
|
|
||||||
if(code < 1024)
|
if(code < 1024)
|
||||||
{
|
{
|
||||||
(*sc_table[code])();
|
(*sc_table[code])(CPU);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Emu.GetModuleManager().CallFunc(code))
|
if(Emu.GetModuleManager().CallFunc(CPU, code))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LOG_ERROR(HLE, "TODO: %s", GetHLEFuncName(code).c_str());
|
LOG_ERROR(HLE, "TODO: %s", GetHLEFuncName(code).c_str());
|
||||||
declCPU();
|
|
||||||
CPU.GPR[3] = 0;
|
CPU.GPR[3] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,9 +60,11 @@ public:
|
||||||
|
|
||||||
extern bool dump_enable;
|
extern bool dump_enable;
|
||||||
|
|
||||||
|
class PPUThread;
|
||||||
|
|
||||||
class SysCalls
|
class SysCalls
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void DoSyscall(u32 code);
|
static void DoSyscall(PPUThread& CPU, u32 code);
|
||||||
static std::string GetHLEFuncName(const u32 fid);
|
static std::string GetHLEFuncName(const u32 fid);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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()))
|
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_stamp = get_system_time();
|
||||||
cond->signal.lock(target);
|
cond->signal.lock(target);
|
||||||
Emu.GetCPU().NotifyThread(target);
|
Emu.GetCPU().NotifyThread(target);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "Emu/Memory/Memory.h"
|
#include "Emu/Memory/Memory.h"
|
||||||
#include "Emu/System.h"
|
#include "Emu/System.h"
|
||||||
#include "Emu/SysCalls/SysCalls.h"
|
#include "Emu/SysCalls/SysCalls.h"
|
||||||
|
#include "Emu/SysCalls/Callback.h"
|
||||||
|
|
||||||
#include "Emu/CPU/CPUThreadManager.h"
|
#include "Emu/CPU/CPUThreadManager.h"
|
||||||
#include "Emu/Cell/PPUThread.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~~~~~~~~*/;
|
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();
|
if (CPU.owned_mutexes)
|
||||||
u32 tid = thr.GetId();
|
|
||||||
|
|
||||||
if (thr.owned_mutexes)
|
|
||||||
{
|
{
|
||||||
sys_ppu_thread.Error("Owned mutexes found (%d)", thr.owned_mutexes);
|
sys_ppu_thread.Error("Owned mutexes found (%d)", CPU.owned_mutexes);
|
||||||
thr.owned_mutexes = 0;
|
CPU.owned_mutexes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
thr.SetExitStatus(errorcode);
|
CPU.SetExitStatus(errorcode);
|
||||||
thr.Stop();
|
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);
|
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);
|
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()
|
s32 sys_ppu_thread_yield()
|
||||||
|
@ -83,10 +81,11 @@ s32 sys_ppu_thread_detach(u64 thread_id)
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sys_ppu_thread_get_join_state(u32 isjoinable_addr)
|
void sys_ppu_thread_get_join_state(PPUThread& CPU, vm::ptr<s32> isjoinable)
|
||||||
{
|
{
|
||||||
sys_ppu_thread.Warning("sys_ppu_thread_get_join_state(isjoinable_addr=0x%x)", isjoinable_addr);
|
sys_ppu_thread.Warning("sys_ppu_thread_get_join_state(isjoinable_addr=0x%x)", isjoinable.addr());
|
||||||
vm::write32(isjoinable_addr, GetCurrentPPUThread().IsJoinable());
|
|
||||||
|
*isjoinable = CPU.IsJoinable();
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 sys_ppu_thread_set_priority(u64 thread_id, s32 prio)
|
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;
|
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);
|
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, (u32)CPU.GetStackAddr());
|
||||||
vm::write32(info_addr + 4, CPU.GetStackSize());
|
vm::write32(info_addr + 4, CPU.GetStackSize());
|
||||||
|
|
||||||
|
@ -203,22 +200,22 @@ s32 sys_ppu_thread_create(vm::ptr<be_t<u64>> thread_id, u32 entry, u64 arg, s32
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sys_ppu_thread_once(vm::ptr<std::atomic<be_t<u32>>> once_ctrl, u32 entry)
|
void sys_ppu_thread_once(PPUThread& CPU, vm::ptr<std::atomic<be_t<u32>>> once_ctrl, vm::ptr<void(*)()> 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<u32> old = be_t<u32>::MakeFromBE(se32(SYS_PPU_THREAD_ONCE_INIT));
|
be_t<u32> old = be_t<u32>::MakeFromBE(se32(SYS_PPU_THREAD_ONCE_INIT));
|
||||||
if (once_ctrl->compare_exchange_weak(old, be_t<u32>::MakeFromBE(se32(SYS_PPU_THREAD_DONE_INIT))))
|
if (once_ctrl->compare_exchange_weak(old, be_t<u32>::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<be_t<u64>> thread_id)
|
s32 sys_ppu_thread_get_id(PPUThread& CPU, vm::ptr<be_t<u64>> thread_id)
|
||||||
{
|
{
|
||||||
sys_ppu_thread.Log("sys_ppu_thread_get_id(thread_id_addr=0x%x)", thread_id.addr());
|
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;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,18 +13,18 @@ enum ppu_thread_flags : u64
|
||||||
};
|
};
|
||||||
|
|
||||||
// SysCalls
|
// SysCalls
|
||||||
void sys_ppu_thread_exit(u64 errorcode);
|
void sys_ppu_thread_exit(PPUThread& CPU, u64 errorcode);
|
||||||
void sys_internal_ppu_thread_exit(u64 errorcode);
|
void sys_internal_ppu_thread_exit(PPUThread& CPU, u64 errorcode);
|
||||||
s32 sys_ppu_thread_yield();
|
s32 sys_ppu_thread_yield();
|
||||||
s32 sys_ppu_thread_join(u64 thread_id, vm::ptr<be_t<u64>> vptr);
|
s32 sys_ppu_thread_join(u64 thread_id, vm::ptr<be_t<u64>> vptr);
|
||||||
s32 sys_ppu_thread_detach(u64 thread_id);
|
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<s32> isjoinable);
|
||||||
s32 sys_ppu_thread_set_priority(u64 thread_id, s32 prio);
|
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_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_stop(u64 thread_id);
|
||||||
s32 sys_ppu_thread_restart(u64 thread_id);
|
s32 sys_ppu_thread_restart(u64 thread_id);
|
||||||
s32 sys_ppu_thread_create(vm::ptr<be_t<u64>> thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::ptr<const char> threadname);
|
s32 sys_ppu_thread_create(vm::ptr<be_t<u64>> thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::ptr<const char> threadname);
|
||||||
void sys_ppu_thread_once(vm::ptr<std::atomic<be_t<u32>>> once_ctrl, u32 entry);
|
void sys_ppu_thread_once(PPUThread& CPU, vm::ptr<std::atomic<be_t<u32>>> once_ctrl, vm::ptr<void(*)()> init);
|
||||||
s32 sys_ppu_thread_get_id(vm::ptr<be_t<u64>> thread_id);
|
s32 sys_ppu_thread_get_id(PPUThread& CPU, vm::ptr<be_t<u64>> thread_id);
|
||||||
s32 sys_ppu_thread_rename(u64 thread_id, vm::ptr<const char> name);
|
s32 sys_ppu_thread_rename(u64 thread_id, vm::ptr<const char> name);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue