SPURS: Document some parts of taskset policy module

This commit is contained in:
S Gopal Rajagopal 2015-01-28 23:48:06 +05:30
parent 2e2f92f4f6
commit a7728c9067
3 changed files with 92 additions and 18 deletions

View File

@ -2821,7 +2821,7 @@ s64 spursCreateTask(vm::ptr<CellSpursTaskset> taskset, vm::ptr<u32> task_id, vm:
} }
taskset->m.task_info[tmp_task_id].elf_addr.set(elf_addr.addr()); 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++) for (u32 i = 0; i < 2; i++)
{ {
taskset->m.task_info[tmp_task_id].args.u64[i] = arg != 0 ? arg->u64[i] : 0; taskset->m.task_info[tmp_task_id].args.u64[i] = arg != 0 ? arg->u64[i] : 0;

View File

@ -181,6 +181,12 @@ enum SpursTraceConstants
CELL_SPURS_TRACE_SERVICE_WAIT = 0x02, CELL_SPURS_TRACE_SERVICE_WAIT = 0x02,
CELL_SPURS_TRACE_SERVICE_EXIT = 0x03, 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 // Trace mode flags
CELL_SPURS_TRACE_MODE_FLAG_WRAP_BUFFER = 0x1, CELL_SPURS_TRACE_MODE_FLAG_WRAP_BUFFER = 0x1,
CELL_SPURS_TRACE_MODE_FLAG_SYNCHRONOUS_START_STOP = 0x2, CELL_SPURS_TRACE_MODE_FLAG_SYNCHRONOUS_START_STOP = 0x2,
@ -335,6 +341,12 @@ struct CellSpursTracePacket
be_t<u16> ls; be_t<u16> ls;
} start; } start;
struct
{
be_t<u32> incident;
be_t<u32> taskId;
} task;
be_t<u64> user; be_t<u64> user;
be_t<u64> guid; be_t<u64> guid;
be_t<u64> stop; be_t<u64> stop;
@ -607,7 +619,7 @@ struct CellSpursTaskset
{ {
CellSpursTaskArgument args; CellSpursTaskArgument args;
vm::bptr<u64, 1, u64> elf_addr; vm::bptr<u64, 1, u64> elf_addr;
vm::bptr<u64, 1, u64> context_save_storage; // This is ((context_save_storage_addr & 0xFFFFFFF8) | allocated_ls_blocks) be_t<u64> context_save_storage_and_alloc_ls_blocks; // This is (context_save_storage_addr | allocated_ls_blocks)
CellSpursTaskLsPattern ls_pattern; CellSpursTaskLsPattern ls_pattern;
}; };
@ -716,7 +728,7 @@ struct CellSpursTaskset2
{ {
CellSpursTaskArgument args; CellSpursTaskArgument args;
vm::bptr<u64, 1, u64> elf_addr; vm::bptr<u64, 1, u64> elf_addr;
vm::bptr<u64, 1, u64> context_save_storage; // This is ((context_save_storage_addr & 0xFFFFFFF8) | allocated_ls_blocks) vm::bptr<u64, 1, u64> context_save_storage; // This is (context_save_storage_addr | allocated_ls_blocks)
CellSpursTaskLsPattern ls_pattern; 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. // The SPURS taskset policy module data store. This resides at 0x2700 of the LS.
struct SpursTasksetPmMgmtData struct SpursTasksetPmMgmtData
{ {
u8 tempArea[0x80]; // 0x2700 u8 tempAreaTaskset[0x80]; // 0x2700
u8 x2780[0x27B8 - 0x2780]; // 0x2780 u8 tempAreaTaskInfo[0x30]; // 0x2780
be_t<u64> x27B0; // 0x27B0
vm::bptr<CellSpursTaskset, 1, u64> taskset; // 0x27B8 vm::bptr<CellSpursTaskset, 1, u64> taskset; // 0x27B8
be_t<u32> kernelMgmt; // 0x27C0 be_t<u32> kernelMgmtAddr; // 0x27C0
be_t<u32> yieldAddr; // 0x27C4 be_t<u32> yieldAddr; // 0x27C4
be_t<u32> x27C8; // 0x27C8 be_t<u32> x27C8; // 0x27C8
be_t<u32> spuNum; // 0x27CC be_t<u32> spuNum; // 0x27CC
@ -896,9 +909,20 @@ struct SpursTasksetPmMgmtData
be_t<u32> taskId; // 0x27D4 be_t<u32> taskId; // 0x27D4
u8 x27D8[0x2840 - 0x27D8]; // 0x27D8 u8 x27D8[0x2840 - 0x27D8]; // 0x27D8
u8 moduleId[16]; // 0x2840 u8 moduleId[16]; // 0x2840
u8 x2850[0x2C80 - 0x2850]; // 0x2850 u8 stackArea[0x2C80 - 0x2850]; // 0x2850
be_t<u128> contextSaveArea[50]; // 0x2C80 be_t<u128> savedContextLr; // 0x2C80
u8 x2FA0[0x3000 - 0x2FA0]; // 0x2FA0 be_t<u128> savedContextSp; // 0x2C90
be_t<u128> savedContextR80ToR127[48]; // 0x2CA0
be_t<u128> savedContextFpscr; // 0x2FA0
be_t<u32> savedWriteTagGroupQueryMask; // 0x2FB0
be_t<u32> savedSpuWriteEventMask; // 0x2FB4
be_t<u32> tasksetMgmtAddr; // 0x2FB8
be_t<u32> lowestLoadSegmentAddr; // 0x2FBC
be_t<u64> x2FC0; // 0x2FC0
be_t<u64> x2FC8; // 0x2FC8
be_t<u32> x2FD0; // 0x2FD0
be_t<u32> taskExitCode; // 0x2FD4
u8 x2FD8[0x3000 - 0x2FD8]; // 0x2FD8
}; };
static_assert(sizeof(SpursTasksetPmMgmtData) == 0x900, "Incorrect size for SpursTasksetPmMgmtData"); static_assert(sizeof(SpursTasksetPmMgmtData) == 0x900, "Incorrect size for SpursTasksetPmMgmtData");

View File

@ -865,7 +865,57 @@ bool spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32
return false; return false;
} }
void spursTasksetDispatch() { void spursTasksetDispatch(SPUThread & spu) {
auto mgmt = vm::get_ptr<SpursTasksetPmMgmtData>(spu.ls_offset + 0x2700);
auto kernelMgmt = vm::get_ptr<SpursKernelMgmtData>(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<void>(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<void>(spu.ls_offset + CELL_SPURS_TASK_TOP + ((i - 6) << 11)),
vm::get_ptr<void>((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) { void spursTasksetProcessPollStatus(SPUThread & spu, u32 pollStatus) {
@ -917,20 +967,20 @@ void spursTasksetEntry(SPUThread & spu) {
memset(mgmt, 0, sizeof(*mgmt)); memset(mgmt, 0, sizeof(*mgmt));
mgmt->taskset.set(arg); mgmt->taskset.set(arg);
memcpy(mgmt->moduleId, "SPURSTASK MODULE", 16); memcpy(mgmt->moduleId, "SPURSTASK MODULE", 16);
mgmt->kernelMgmt = spu.GPR[3]._u32[3]; mgmt->kernelMgmtAddr = spu.GPR[3]._u32[3];
mgmt->yieldAddr = 0xA70; mgmt->yieldAddr = 0xA70;
mgmt->spuNum = kernelMgmt->spuNum; mgmt->spuNum = kernelMgmt->spuNum;
mgmt->dmaTagId = kernelMgmt->dmaTagId; mgmt->dmaTagId = kernelMgmt->dmaTagId;
mgmt->taskId = 0xFFFFFFFF; mgmt->taskId = 0xFFFFFFFF;
spursTasksetInit(spu, pollStatus); spursTasksetInit(spu, pollStatus);
// TODO: Dispatch // TODO: Dispatch
} }
mgmt->contextSaveArea[0] = spu.GPR[0]; mgmt->savedContextLr = spu.GPR[0];
mgmt->contextSaveArea[1] = spu.GPR[1]; mgmt->savedContextSp = spu.GPR[1];
for (auto i = 0; i < 48; i++) { 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 // TODO: Process syscall