SPURS: Implement spursJobchainPopUrgentCommand

This commit is contained in:
Eladash 2020-10-24 10:48:37 +03:00 committed by Ivan
parent 1e7bf218e0
commit 0fcf767ee9
2 changed files with 79 additions and 6 deletions

View file

@ -465,8 +465,8 @@ struct alignas(128) CellSpursJobChain
u8 val2F; // 0x2F
atomic_be_t<u64> urgentCmds[4]; // 0x30
u8 unk2[0x20]; // 0x50
be_t<u16> sizeJobDescriptor; // 0x70
atomic_be_t<u16> maxGrabbedJob; // 0x72
atomic_be_t<u16> maxGrabbedJob; // 0x70
be_t<u16> sizeJobDescriptor; // 0x72
be_t<u32> workloadId; // 0x74
vm::bptr<CellSpurs, u64> spurs; // 0x78
be_t<s32> error; // 0x80
@ -487,14 +487,19 @@ struct alignas(128) CellSpursJobChain_x00
u8 unk0[0x3]; // 0x20
b8 isHalted; // 0x23
b8 autoReadyCount; // 0x24
u8 unk1[0x7]; // 0x25
u8 unk1[0x3]; // 0x25
u8 initSpuCount; // 0x28
u8 unk5; // 0x29
u8 tag1; // 0x2A
u8 tag2; // 0x2B
u8 val2C; // 0x2C
u8 val2D; // 0x2D
u8 jmVer; // 0x2D
u8 val2E; // 0x2E
u8 val2F; // 0x2F
be_t<u64> urgentCmds[4]; // 0x30
u8 unk2[0x22]; // 0x50
be_t<u16> maxGrabbedJob; // 0x72
u8 unk2[0x20]; // 0x50
be_t<u16> maxGrabbedJob; // 0x70
be_t<u16> sizeJobDescriptor; // 0x72
be_t<u32> workloadId; // 0x74
vm::bptr<CellSpurs, u64> spurs; // 0x78
};
@ -1257,6 +1262,17 @@ struct SpursTasksetContext
CHECK_SIZE(SpursTasksetContext, 0x900);
struct SpursJobChainContext
{
u8 tempAreaJobChain[0x80]; // 0x4A00
u8 unk0[3]; // 0x4A80
b8 unkFlag0; // 0x4A83
u8 unk1[0x10]; // 0x4A84
vm::bptr<CellSpursJobChain> jobChain; // 0x4A94
// TODO
};
class SpursModuleExit
{
};

View file

@ -75,6 +75,12 @@ static s32 spursTasksetProcessSyscall(spu_thread& spu, u32 syscallNum, u32 args)
static void spursTasksetInit(spu_thread& spu, u32 pollStatus);
static s32 spursTasksetLoadElf(spu_thread& spu, u32* entryPoint, u32* lowestLoadAddr, u64 elfAddr, bool skipWriteableSegments);
//
// SPURS jobchain policy module functions
//
bool spursJobChainEntry(spu_thread& spu);
void spursJobchainPopUrgentCommand(spu_thread& spu);
//----------------------------------------------------------------------------
// SPURS utility functions
//----------------------------------------------------------------------------
@ -2046,3 +2052,54 @@ s32 spursTasksetLoadElf(spu_thread& spu, u32* entryPoint, u32* lowestLoadAddr, u
return CELL_OK;
}
//----------------------------------------------------------------------------
// SPURS taskset policy module functions
//----------------------------------------------------------------------------
bool spursJobChainEntry(spu_thread& spu)
{
const auto ctxt = spu._ptr<SpursJobChainContext>(0x4a00);
auto kernelCtxt = spu._ptr<SpursKernelContext>(spu.gpr[3]._u32[3]);
auto arg = spu.gpr[4]._u64[1];
auto pollStatus = spu.gpr[5]._u32[3];
// TODO
return false;
}
void spursJobchainPopUrgentCommand(spu_thread& spu)
{
const auto ctxt = spu._ptr<SpursJobChainContext>(0x4a00);
const auto jc = vm::unsafe_ptr_cast<CellSpursJobChain_x00>(+ctxt->jobChain);
const bool alterQueue = ctxt->unkFlag0;
vm::reservation_op(jc, [&](CellSpursJobChain_x00& op)
{
const auto ls = reinterpret_cast<CellSpursJobChain_x00*>(ctxt->tempAreaJobChain);
struct alignas(16) { v128 first, second; } data;
std::memcpy(&data, &op.urgentCmds, sizeof(op.urgentCmds));
if (!alterQueue)
{
// Read the queue, do not modify it
}
else
{
// Move FIFO queue contents one command up
data.first._u64[0] = data.first._u64[1];
data.first._u64[1] = data.second._u64[0];
data.second._u64[0] = data.second._u64[1];
data.second._u64[1] = 0;
}
// Writeback
std::memcpy(&ls->urgentCmds, &data, sizeof(op.urgentCmds));
std::memcpy(&ls->isHalted, &op.unk0[0], 1); // Maybe intended to set it to false
ls->unk5 = 0;
ls->sizeJobDescriptor = op.maxGrabbedJob;
std::memcpy(&op, ls, 128);
});
}