diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp index 92737bae4a..7562cd0806 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp @@ -4,6 +4,7 @@ #include "Emu/SysCalls/Callback.h" #include "Emu/Cell/SPUThread.h" +#include "Emu/SysCalls/lv2/sys_ppu_thread.h" #include "Emu/SysCalls/lv2/sys_memory.h" #include "Emu/SysCalls/lv2/sys_process.h" #include "Emu/SysCalls/lv2/sys_semaphore.h" @@ -76,8 +77,8 @@ s64 spursInit( memset(spurs.get_ptr(), 0, CellSpurs::size1 + isSecond * CellSpurs::size2); spurs->m.revision = revision; spurs->m.sdkVersion = sdkVersion; - spurs->m.unk1 = 0xffffffffull; - spurs->m.unk2 = 0xffffffffull; + spurs->m.ppu0 = 0xffffffffull; + spurs->m.ppu1 = 0xffffffffull; spurs->m.flags = flags; memcpy(spurs->m.prefix, prefix, prefixSize); spurs->m.prefixSize = (u8)prefixSize; @@ -149,6 +150,7 @@ s64 spursInit( if (flags & SAF_UNKNOWN_FLAG_8) tgt |= 0xC02; if (flags & SAF_UNKNOWN_FLAG_9) tgt |= 0x800; auto tg = spu_thread_group_create(name + "CellSpursKernelGroup", nSpus, spuPriority, tgt, container); + assert(tg); spurs->m.spuTG = tg->m_id; name += "CellSpursKernel0"; @@ -189,6 +191,22 @@ s64 spursInit( assert(sys_event_port_connect_local(port, queue) == CELL_OK); + name = std::string(prefix, prefixSize); + + PPUThread* ppu0 = nullptr; +#ifdef PRX_DEBUG + ppu0 = ppu_thread_create(vm::read32(libsre_rtoc - 0x7E60), spurs.addr(), ppuPriority, 0x4000, true, false, name + "SpursHdlr0"); +#endif + assert(ppu0); + spurs->m.ppu0 = ppu0->GetId(); + + PPUThread* ppu1 = nullptr; +#ifdef PRX_DEBUG + ppu1 = ppu_thread_create(vm::read32(libsre_rtoc - 0x7E24), spurs.addr(), ppuPriority, 0x8000, true, false, name + "SpursHdlr1"); +#endif + assert(ppu1); + spurs->m.ppu1 = ppu1->GetId(); + return CELL_OK; #endif } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.h b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h index a01e1591de..a85c4c928d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h @@ -186,8 +186,8 @@ struct CellSpurs be_t unk9; // 0xD10 u8 unk10; // 0xD14 u8 unknown5[0xD20 - 0xD15]; - be_t unk1; // 0xD20 - be_t unk2; // 0xD28 + be_t ppu0; // 0xD20 + be_t ppu1; // 0xD28 be_t spuTG; // 0xD30 be_t spus[8]; // 0xD34 u8 unknown3[0xD5C - 0xD54]; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp index c63b93bcfd..f9cd0f3ec2 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp @@ -147,6 +147,39 @@ s32 sys_ppu_thread_restart(u64 thread_id) return CELL_OK; } +PPUThread* ppu_thread_create(u32 entry, u64 arg, s32 prio, u32 stacksize, bool is_joinable, bool is_interrupt, const std::string& name) +{ + PPUThread& new_thread = *(PPUThread*)&Emu.GetCPU().AddThread(CPU_THREAD_PPU); + + u32 id = new_thread.GetId(); + new_thread.SetEntry(entry); + new_thread.SetPrio(prio); + new_thread.SetStackSize(stacksize); + //new_thread.flags = flags; + new_thread.m_has_interrupt = false; + new_thread.m_is_interrupt = is_interrupt; + new_thread.SetName(name); + + sys_ppu_thread.Notice("*** New PPU Thread [%s] (%s, entry=0x%x): id = %d", name.c_str(), + is_interrupt ? "interrupt" : + (is_joinable ? "joinable" : "non-joinable"), entry, id); + + if (!is_interrupt) + { + new_thread.Run(); + new_thread.GPR[3] = arg; + new_thread.Exec(); + } + else + { + new_thread.InitStack(); + new_thread.InitRegs(); + new_thread.DoRun(); + } + + return &new_thread; +} + s32 sys_ppu_thread_create(vm::ptr> thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::ptr threadname) { sys_ppu_thread.Log("sys_ppu_thread_create(thread_id_addr=0x%x, entry=0x%x, arg=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname_addr=0x%x('%s'))", @@ -171,32 +204,9 @@ s32 sys_ppu_thread_create(vm::ptr> thread_id, u32 entry, u64 arg, s32 default: sys_ppu_thread.Error("sys_ppu_thread_create(): unknown flags value (0x%llx)", flags); return CELL_EPERM; } - PPUThread& new_thread = *(PPUThread*)&Emu.GetCPU().AddThread(CPU_THREAD_PPU); - - *thread_id = new_thread.GetId(); - new_thread.SetEntry(entry); - new_thread.SetPrio(prio); - new_thread.SetStackSize(stacksize); - //new_thread.flags = flags; - new_thread.m_has_interrupt = false; - new_thread.m_is_interrupt = is_interrupt; - new_thread.SetName(threadname ? threadname.get_ptr() : ""); - - sys_ppu_thread.Notice("*** New PPU Thread [%s] (flags=0x%llx, entry=0x%x): id = %d", new_thread.GetName().c_str(), flags, entry, new_thread.GetId()); - - if (!is_interrupt) - { - new_thread.Run(); - new_thread.GPR[3] = arg; - new_thread.Exec(); - } - else - { - new_thread.InitStack(); - new_thread.InitRegs(); - new_thread.DoRun(); - } + std::string name = threadname ? threadname.get_ptr() : ""; + *thread_id = ppu_thread_create(entry, arg, prio, stacksize, is_joinable, is_interrupt, name)->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 0bbe4aabc3..4b79c4f7e9 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h @@ -1,5 +1,7 @@ #pragma once +class PPUThread; + enum { SYS_PPU_THREAD_ONCE_INIT, @@ -12,6 +14,9 @@ enum ppu_thread_flags : u64 SYS_PPU_THREAD_CREATE_INTERRUPT = 0x2, }; +// Aux +PPUThread* ppu_thread_create(u32 entry, u64 arg, s32 prio, u32 stacksize, bool is_joinable, bool is_interrupt, const std::string& name); + // SysCalls void sys_ppu_thread_exit(PPUThread& CPU, u64 errorcode); void sys_internal_ppu_thread_exit(PPUThread& CPU, u64 errorcode);