From 0fcf767ee9a8db3bf7ba525329a6cad4a6fdf3e3 Mon Sep 17 00:00:00 2001 From: Eladash Date: Sat, 24 Oct 2020 10:48:37 +0300 Subject: [PATCH] SPURS: Implement spursJobchainPopUrgentCommand --- rpcs3/Emu/Cell/Modules/cellSpurs.h | 28 +++++++++--- rpcs3/Emu/Cell/Modules/cellSpursSpu.cpp | 57 +++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 6 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellSpurs.h b/rpcs3/Emu/Cell/Modules/cellSpurs.h index d0214e8c8b..dc991b3ec7 100644 --- a/rpcs3/Emu/Cell/Modules/cellSpurs.h +++ b/rpcs3/Emu/Cell/Modules/cellSpurs.h @@ -465,8 +465,8 @@ struct alignas(128) CellSpursJobChain u8 val2F; // 0x2F atomic_be_t urgentCmds[4]; // 0x30 u8 unk2[0x20]; // 0x50 - be_t sizeJobDescriptor; // 0x70 - atomic_be_t maxGrabbedJob; // 0x72 + atomic_be_t maxGrabbedJob; // 0x70 + be_t sizeJobDescriptor; // 0x72 be_t workloadId; // 0x74 vm::bptr spurs; // 0x78 be_t 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 urgentCmds[4]; // 0x30 - u8 unk2[0x22]; // 0x50 - be_t maxGrabbedJob; // 0x72 + u8 unk2[0x20]; // 0x50 + be_t maxGrabbedJob; // 0x70 + be_t sizeJobDescriptor; // 0x72 be_t workloadId; // 0x74 vm::bptr 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 jobChain; // 0x4A94 + + // TODO +}; + class SpursModuleExit { }; diff --git a/rpcs3/Emu/Cell/Modules/cellSpursSpu.cpp b/rpcs3/Emu/Cell/Modules/cellSpursSpu.cpp index ab4b2f920a..ed8c22962c 100644 --- a/rpcs3/Emu/Cell/Modules/cellSpursSpu.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSpursSpu.cpp @@ -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(0x4a00); + auto kernelCtxt = spu._ptr(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(0x4a00); + const auto jc = vm::unsafe_ptr_cast(+ctxt->jobChain); + + const bool alterQueue = ctxt->unkFlag0; + vm::reservation_op(jc, [&](CellSpursJobChain_x00& op) + { + const auto ls = reinterpret_cast(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); + }); +}