From a7728c9067165c23d0e70000a72fefc11a84612a Mon Sep 17 00:00:00 2001 From: S Gopal Rajagopal Date: Wed, 28 Jan 2015 23:48:06 +0530 Subject: [PATCH] SPURS: Document some parts of taskset policy module --- rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp | 2 +- rpcs3/Emu/SysCalls/Modules/cellSpurs.h | 40 +++++++++--- rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp | 68 ++++++++++++++++++--- 3 files changed, 92 insertions(+), 18 deletions(-) diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp index 99d2d35eea..c9795203f8 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp @@ -2821,7 +2821,7 @@ s64 spursCreateTask(vm::ptr taskset, vm::ptr task_id, vm: } taskset->m.task_info[tmp_task_id].elf_addr.set(elf_addr.addr()); - taskset->m.task_info[tmp_task_id].context_save_storage.set((context_addr.addr() & 0xFFFFFFF8) | alloc_ls_blocks); + taskset->m.task_info[tmp_task_id].context_save_storage_and_alloc_ls_blocks = (context_addr.addr() | alloc_ls_blocks); for (u32 i = 0; i < 2; i++) { taskset->m.task_info[tmp_task_id].args.u64[i] = arg != 0 ? arg->u64[i] : 0; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.h b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h index 196fedd3a8..4ccf224ec7 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h @@ -181,6 +181,12 @@ enum SpursTraceConstants CELL_SPURS_TRACE_SERVICE_WAIT = 0x02, CELL_SPURS_TRACE_SERVICE_EXIT = 0x03, + // Task incident + CELL_SPURS_TRACE_TASK_DISPATCH = 0x01, + CELL_SPURS_TRACE_TASK_YIELD = 0x03, + CELL_SPURS_TRACE_TASK_WAIT = 0x04, + CELL_SPURS_TRACE_TASK_EXIT = 0x05, + // Trace mode flags CELL_SPURS_TRACE_MODE_FLAG_WRAP_BUFFER = 0x1, CELL_SPURS_TRACE_MODE_FLAG_SYNCHRONOUS_START_STOP = 0x2, @@ -335,6 +341,12 @@ struct CellSpursTracePacket be_t ls; } start; + struct + { + be_t incident; + be_t taskId; + } task; + be_t user; be_t guid; be_t stop; @@ -607,7 +619,7 @@ struct CellSpursTaskset { CellSpursTaskArgument args; vm::bptr elf_addr; - vm::bptr context_save_storage; // This is ((context_save_storage_addr & 0xFFFFFFF8) | allocated_ls_blocks) + be_t context_save_storage_and_alloc_ls_blocks; // This is (context_save_storage_addr | allocated_ls_blocks) CellSpursTaskLsPattern ls_pattern; }; @@ -716,7 +728,7 @@ struct CellSpursTaskset2 { CellSpursTaskArgument args; vm::bptr elf_addr; - vm::bptr context_save_storage; // This is ((context_save_storage_addr & 0xFFFFFFF8) | allocated_ls_blocks) + vm::bptr context_save_storage; // This is (context_save_storage_addr | allocated_ls_blocks) CellSpursTaskLsPattern ls_pattern; }; @@ -885,10 +897,11 @@ static_assert(sizeof(SpursKernelMgmtData) == 0x130, "Incorrect size for SpursKer // The SPURS taskset policy module data store. This resides at 0x2700 of the LS. struct SpursTasksetPmMgmtData { - u8 tempArea[0x80]; // 0x2700 - u8 x2780[0x27B8 - 0x2780]; // 0x2780 + u8 tempAreaTaskset[0x80]; // 0x2700 + u8 tempAreaTaskInfo[0x30]; // 0x2780 + be_t x27B0; // 0x27B0 vm::bptr taskset; // 0x27B8 - be_t kernelMgmt; // 0x27C0 + be_t kernelMgmtAddr; // 0x27C0 be_t yieldAddr; // 0x27C4 be_t x27C8; // 0x27C8 be_t spuNum; // 0x27CC @@ -896,9 +909,20 @@ struct SpursTasksetPmMgmtData be_t taskId; // 0x27D4 u8 x27D8[0x2840 - 0x27D8]; // 0x27D8 u8 moduleId[16]; // 0x2840 - u8 x2850[0x2C80 - 0x2850]; // 0x2850 - be_t contextSaveArea[50]; // 0x2C80 - u8 x2FA0[0x3000 - 0x2FA0]; // 0x2FA0 + u8 stackArea[0x2C80 - 0x2850]; // 0x2850 + be_t savedContextLr; // 0x2C80 + be_t savedContextSp; // 0x2C90 + be_t savedContextR80ToR127[48]; // 0x2CA0 + be_t savedContextFpscr; // 0x2FA0 + be_t savedWriteTagGroupQueryMask; // 0x2FB0 + be_t savedSpuWriteEventMask; // 0x2FB4 + be_t tasksetMgmtAddr; // 0x2FB8 + be_t lowestLoadSegmentAddr; // 0x2FBC + be_t x2FC0; // 0x2FC0 + be_t x2FC8; // 0x2FC8 + be_t x2FD0; // 0x2FD0 + be_t taskExitCode; // 0x2FD4 + u8 x2FD8[0x3000 - 0x2FD8]; // 0x2FD8 }; static_assert(sizeof(SpursTasksetPmMgmtData) == 0x900, "Incorrect size for SpursTasksetPmMgmtData"); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp index 624be7e805..e4ebca84a5 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp @@ -865,7 +865,57 @@ bool spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32 return false; } -void spursTasksetDispatch() { +void spursTasksetDispatch(SPUThread & spu) { + auto mgmt = vm::get_ptr(spu.ls_offset + 0x2700); + auto kernelMgmt = vm::get_ptr(spu.ls_offset + 0x100); + + u32 taskId; + u32 isWaiting; + spursTasksetProcessRequest(spu, 5, &taskId, &isWaiting); + if (taskId >= CELL_SPURS_MAX_TASK) { + // TODO: spursTasksetExit(spu); + } + + mgmt->taskId = taskId; + u64 elfAddr = mgmt->taskset->m.task_info[taskId].elf_addr.addr() & 0xFFFFFFFFFFFFFFF8ull; + + // Trace - Task: Incident=dispatch + CellSpursTracePacket pkt; + memset(&pkt, 0, sizeof(pkt)); + pkt.header.tag = CELL_SPURS_TRACE_TAG_TASK; + pkt.data.task.incident = CELL_SPURS_TRACE_TASK_DISPATCH; + pkt.data.task.taskId = taskId; + cellSpursModulePutTrace(&pkt, 0x1F); + + if (isWaiting == 0) { + } + + if (mgmt->taskset->m.enable_clear_ls) { + memset(vm::get_ptr(spu.ls_offset + CELL_SPURS_TASK_TOP), 0, CELL_SPURS_TASK_BOTTOM - CELL_SPURS_TASK_TOP); + } + + // If the entire LS is saved then there is no need to load the ELF as it will be be saved in the context save area + if (mgmt->taskset->m.task_info[taskId].ls_pattern.u64[0] != 0xFFFFFFFFFFFFFFFFull || + (mgmt->taskset->m.task_info[taskId].ls_pattern.u64[0] | 0xFC00000000000000ull) != 0xFFFFFFFFFFFFFFFFull) { + // Load the ELF + // TODO: Load ELF + } + + // Load save context from main memory to LS + u64 context_save_storage = mgmt->taskset->m.task_info[taskId].context_save_storage_and_alloc_ls_blocks & 0xFFFFFFFFFFFFFF80ull; + for (auto i = 6; i < 128; i++) { + bool shouldLoad = mgmt->taskset->m.task_info[taskId].ls_pattern.u64[i < 64 ? 1 : 0] & (0x8000000000000000ull >> i) ? true : false; + if (shouldLoad) { + memcpy(vm::get_ptr(spu.ls_offset + CELL_SPURS_TASK_TOP + ((i - 6) << 11)), + vm::get_ptr((u32)context_save_storage + 0x400 + ((i - 6) << 11)), 0x800); + } + } + + // Trace - GUID + memset(&pkt, 0, sizeof(pkt)); + pkt.header.tag = CELL_SPURS_TRACE_TAG_GUID; + pkt.data.guid = 0; // TODO: Put GUID of taskId here + cellSpursModulePutTrace(&pkt, 0x1F); } void spursTasksetProcessPollStatus(SPUThread & spu, u32 pollStatus) { @@ -917,20 +967,20 @@ void spursTasksetEntry(SPUThread & spu) { memset(mgmt, 0, sizeof(*mgmt)); mgmt->taskset.set(arg); memcpy(mgmt->moduleId, "SPURSTASK MODULE", 16); - mgmt->kernelMgmt = spu.GPR[3]._u32[3]; - mgmt->yieldAddr = 0xA70; - mgmt->spuNum = kernelMgmt->spuNum; - mgmt->dmaTagId = kernelMgmt->dmaTagId; - mgmt->taskId = 0xFFFFFFFF; + mgmt->kernelMgmtAddr = spu.GPR[3]._u32[3]; + mgmt->yieldAddr = 0xA70; + mgmt->spuNum = kernelMgmt->spuNum; + mgmt->dmaTagId = kernelMgmt->dmaTagId; + mgmt->taskId = 0xFFFFFFFF; spursTasksetInit(spu, pollStatus); // TODO: Dispatch } - mgmt->contextSaveArea[0] = spu.GPR[0]; - mgmt->contextSaveArea[1] = spu.GPR[1]; + mgmt->savedContextLr = spu.GPR[0]; + mgmt->savedContextSp = spu.GPR[1]; for (auto i = 0; i < 48; i++) { - mgmt->contextSaveArea[i + 2] = spu.GPR[80 + i]; + mgmt->savedContextR80ToR127[i] = spu.GPR[80 + i]; } // TODO: Process syscall