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].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;

View File

@ -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<u16> ls;
} start;
struct
{
be_t<u32> incident;
be_t<u32> taskId;
} task;
be_t<u64> user;
be_t<u64> guid;
be_t<u64> stop;
@ -607,7 +619,7 @@ struct CellSpursTaskset
{
CellSpursTaskArgument args;
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;
};
@ -716,7 +728,7 @@ struct CellSpursTaskset2
{
CellSpursTaskArgument args;
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;
};
@ -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<u64> x27B0; // 0x27B0
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> x27C8; // 0x27C8
be_t<u32> spuNum; // 0x27CC
@ -896,9 +909,20 @@ struct SpursTasksetPmMgmtData
be_t<u32> taskId; // 0x27D4
u8 x27D8[0x2840 - 0x27D8]; // 0x27D8
u8 moduleId[16]; // 0x2840
u8 x2850[0x2C80 - 0x2850]; // 0x2850
be_t<u128> contextSaveArea[50]; // 0x2C80
u8 x2FA0[0x3000 - 0x2FA0]; // 0x2FA0
u8 stackArea[0x2C80 - 0x2850]; // 0x2850
be_t<u128> savedContextLr; // 0x2C80
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");

View File

@ -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<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) {
@ -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