CellSpurs initialization

This commit is contained in:
Nekotekina 2014-09-19 15:27:51 +04:00
parent 5ad68cfe30
commit dbd49a55c6
4 changed files with 62 additions and 29 deletions

View File

@ -4,6 +4,7 @@
#include "Emu/SysCalls/Callback.h" #include "Emu/SysCalls/Callback.h"
#include "Emu/Cell/SPUThread.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_memory.h"
#include "Emu/SysCalls/lv2/sys_process.h" #include "Emu/SysCalls/lv2/sys_process.h"
#include "Emu/SysCalls/lv2/sys_semaphore.h" #include "Emu/SysCalls/lv2/sys_semaphore.h"
@ -76,8 +77,8 @@ s64 spursInit(
memset(spurs.get_ptr(), 0, CellSpurs::size1 + isSecond * CellSpurs::size2); memset(spurs.get_ptr(), 0, CellSpurs::size1 + isSecond * CellSpurs::size2);
spurs->m.revision = revision; spurs->m.revision = revision;
spurs->m.sdkVersion = sdkVersion; spurs->m.sdkVersion = sdkVersion;
spurs->m.unk1 = 0xffffffffull; spurs->m.ppu0 = 0xffffffffull;
spurs->m.unk2 = 0xffffffffull; spurs->m.ppu1 = 0xffffffffull;
spurs->m.flags = flags; spurs->m.flags = flags;
memcpy(spurs->m.prefix, prefix, prefixSize); memcpy(spurs->m.prefix, prefix, prefixSize);
spurs->m.prefixSize = (u8)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_8) tgt |= 0xC02;
if (flags & SAF_UNKNOWN_FLAG_9) tgt |= 0x800; if (flags & SAF_UNKNOWN_FLAG_9) tgt |= 0x800;
auto tg = spu_thread_group_create(name + "CellSpursKernelGroup", nSpus, spuPriority, tgt, container); auto tg = spu_thread_group_create(name + "CellSpursKernelGroup", nSpus, spuPriority, tgt, container);
assert(tg);
spurs->m.spuTG = tg->m_id; spurs->m.spuTG = tg->m_id;
name += "CellSpursKernel0"; name += "CellSpursKernel0";
@ -189,6 +191,22 @@ s64 spursInit(
assert(sys_event_port_connect_local(port, queue) == CELL_OK); 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; return CELL_OK;
#endif #endif
} }

View File

@ -186,8 +186,8 @@ struct CellSpurs
be_t<u32> unk9; // 0xD10 be_t<u32> unk9; // 0xD10
u8 unk10; // 0xD14 u8 unk10; // 0xD14
u8 unknown5[0xD20 - 0xD15]; u8 unknown5[0xD20 - 0xD15];
be_t<u64> unk1; // 0xD20 be_t<u64> ppu0; // 0xD20
be_t<u64> unk2; // 0xD28 be_t<u64> ppu1; // 0xD28
be_t<u32> spuTG; // 0xD30 be_t<u32> spuTG; // 0xD30
be_t<u32> spus[8]; // 0xD34 be_t<u32> spus[8]; // 0xD34
u8 unknown3[0xD5C - 0xD54]; u8 unknown3[0xD5C - 0xD54];

View File

@ -147,6 +147,39 @@ s32 sys_ppu_thread_restart(u64 thread_id)
return CELL_OK; 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<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)
{ {
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'))", 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<be_t<u64>> 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; 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); std::string name = threadname ? threadname.get_ptr() : "";
*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();
}
*thread_id = ppu_thread_create(entry, arg, prio, stacksize, is_joinable, is_interrupt, name)->GetId();
return CELL_OK; return CELL_OK;
} }

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
class PPUThread;
enum enum
{ {
SYS_PPU_THREAD_ONCE_INIT, SYS_PPU_THREAD_ONCE_INIT,
@ -12,6 +14,9 @@ enum ppu_thread_flags : u64
SYS_PPU_THREAD_CREATE_INTERRUPT = 0x2, 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 // SysCalls
void sys_ppu_thread_exit(PPUThread& CPU, u64 errorcode); void sys_ppu_thread_exit(PPUThread& CPU, u64 errorcode);
void sys_internal_ppu_thread_exit(PPUThread& CPU, u64 errorcode); void sys_internal_ppu_thread_exit(PPUThread& CPU, u64 errorcode);