mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 04:02:42 +01:00
SPU: Make spu_thread::offset private
This commit is contained in:
parent
6cc0fe4221
commit
c37bc3c55c
@ -1417,7 +1417,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
|
||||
{
|
||||
const auto& spu = static_cast<spu_thread&>(*cpu);
|
||||
|
||||
const u64 type = spu.offset < RAW_SPU_BASE_ADDR ?
|
||||
const u64 type = spu.get_type() == spu_type::threaded ?
|
||||
SYS_MEMORY_PAGE_FAULT_TYPE_SPU_THREAD :
|
||||
SYS_MEMORY_PAGE_FAULT_TYPE_RAW_SPU;
|
||||
|
||||
|
@ -87,7 +87,7 @@ void cellSpursModulePutTrace(CellSpursTracePacket* packet, u32 dmaTagId)
|
||||
// Check for execution right requests
|
||||
u32 cellSpursModulePollStatus(spu_thread& spu, u32* status)
|
||||
{
|
||||
auto ctxt = vm::_ptr<SpursKernelContext>(spu.offset + 0x100);
|
||||
auto ctxt = spu._ptr<SpursKernelContext>(0x100);
|
||||
|
||||
spu.gpr[3]._u32[3] = 1;
|
||||
if (ctxt->spurs->flags1 & SF1_32_WORKLOADS)
|
||||
@ -112,7 +112,7 @@ u32 cellSpursModulePollStatus(spu_thread& spu, u32* status)
|
||||
// Exit current workload
|
||||
void cellSpursModuleExit(spu_thread& spu)
|
||||
{
|
||||
auto ctxt = vm::_ptr<SpursKernelContext>(spu.offset + 0x100);
|
||||
auto ctxt = spu._ptr<SpursKernelContext>(0x100);
|
||||
spu.pc = ctxt->exitToKernelAddr;
|
||||
|
||||
// TODO: use g_escape for actual long jump
|
||||
@ -246,7 +246,7 @@ s32 sys_spu_thread_switch_system_module(spu_thread& spu, u32 status)
|
||||
// Select a workload to run
|
||||
bool spursKernel1SelectWorkload(spu_thread& spu)
|
||||
{
|
||||
auto ctxt = vm::_ptr<SpursKernelContext>(spu.offset + 0x100);
|
||||
const auto ctxt = spu._ptr<SpursKernelContext>(0x100);
|
||||
|
||||
// The first and only argument to this function is a boolean that is set to false if the function
|
||||
// is called by the SPURS kernel and set to true if called by cellSpursModulePollStatus.
|
||||
@ -418,7 +418,7 @@ bool spursKernel1SelectWorkload(spu_thread& spu)
|
||||
}
|
||||
}
|
||||
|
||||
std::memcpy(vm::base(spu.offset + 0x100), spurs, 128);
|
||||
std::memcpy(ctxt, spurs, 128);
|
||||
}//);
|
||||
|
||||
u64 result = u64{wklSelectedId} << 32;
|
||||
@ -430,7 +430,7 @@ bool spursKernel1SelectWorkload(spu_thread& spu)
|
||||
// Select a workload to run
|
||||
bool spursKernel2SelectWorkload(spu_thread& spu)
|
||||
{
|
||||
auto ctxt = vm::_ptr<SpursKernelContext>(spu.offset + 0x100);
|
||||
const auto ctxt = spu._ptr<SpursKernelContext>(0x100);
|
||||
|
||||
// The first and only argument to this function is a boolean that is set to false if the function
|
||||
// is called by the SPURS kernel and set to true if called by cellSpursModulePollStatus.
|
||||
@ -591,7 +591,7 @@ bool spursKernel2SelectWorkload(spu_thread& spu)
|
||||
}
|
||||
}
|
||||
|
||||
std::memcpy(vm::base(spu.offset + 0x100), spurs, 128);
|
||||
std::memcpy(ctxt, spurs, 128);
|
||||
}//);
|
||||
|
||||
u64 result = u64{wklSelectedId} << 32;
|
||||
@ -603,7 +603,7 @@ bool spursKernel2SelectWorkload(spu_thread& spu)
|
||||
// SPURS kernel dispatch workload
|
||||
void spursKernelDispatchWorkload(spu_thread& spu, u64 widAndPollStatus)
|
||||
{
|
||||
auto ctxt = vm::_ptr<SpursKernelContext>(spu.offset + 0x100);
|
||||
const auto ctxt = spu._ptr<SpursKernelContext>(0x100);
|
||||
auto isKernel2 = ctxt->spurs->flags1 & SF1_32_WORKLOADS ? true : false;
|
||||
|
||||
auto pollStatus = static_cast<u32>(widAndPollStatus);
|
||||
@ -614,10 +614,10 @@ void spursKernelDispatchWorkload(spu_thread& spu, u64 widAndPollStatus)
|
||||
wid < CELL_SPURS_MAX_WORKLOAD2 && isKernel2 ? &ctxt->spurs->wklInfo2[wid & 0xf] :
|
||||
&ctxt->spurs->wklInfoSysSrv;
|
||||
|
||||
std::memcpy(vm::base(spu.offset + 0x3FFE0), wklInfoOffset, 0x20);
|
||||
const auto wklInfo = spu._ptr<CellSpurs::WorkloadInfo>(0x3FFE0);
|
||||
std::memcpy(wklInfo, wklInfoOffset, 0x20);
|
||||
|
||||
// Load the workload to LS
|
||||
auto wklInfo = vm::_ptr<CellSpurs::WorkloadInfo>(spu.offset + 0x3FFE0);
|
||||
if (ctxt->wklCurrentAddr != wklInfo->addr)
|
||||
{
|
||||
switch (wklInfo->addr.addr())
|
||||
@ -629,7 +629,7 @@ void spursKernelDispatchWorkload(spu_thread& spu, u64 widAndPollStatus)
|
||||
//spu.RegisterHleFunction(0xA00, spursTasksetEntry);
|
||||
break;
|
||||
default:
|
||||
std::memcpy(vm::base(spu.offset + 0xA00), wklInfo->addr.get_ptr(), wklInfo->size);
|
||||
std::memcpy(spu._ptr<void>(0xA00), wklInfo->addr.get_ptr(), wklInfo->size);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -655,7 +655,7 @@ void spursKernelDispatchWorkload(spu_thread& spu, u64 widAndPollStatus)
|
||||
// SPURS kernel workload exit
|
||||
bool spursKernelWorkloadExit(spu_thread& spu)
|
||||
{
|
||||
auto ctxt = vm::_ptr<SpursKernelContext>(spu.offset + 0x100);
|
||||
const auto ctxt = spu._ptr<SpursKernelContext>(0x100);
|
||||
auto isKernel2 = ctxt->spurs->flags1 & SF1_32_WORKLOADS ? true : false;
|
||||
|
||||
// Select next workload to run
|
||||
@ -676,7 +676,7 @@ bool spursKernelWorkloadExit(spu_thread& spu)
|
||||
// SPURS kernel entry point
|
||||
bool spursKernelEntry(spu_thread& spu)
|
||||
{
|
||||
auto ctxt = vm::_ptr<SpursKernelContext>(spu.offset + 0x100);
|
||||
const auto ctxt = spu._ptr<SpursKernelContext>(0x100);
|
||||
memset(ctxt, 0, sizeof(SpursKernelContext));
|
||||
|
||||
// Save arguments
|
||||
@ -726,7 +726,7 @@ bool spursKernelEntry(spu_thread& spu)
|
||||
// Entry point of the system service
|
||||
bool spursSysServiceEntry(spu_thread& spu)
|
||||
{
|
||||
auto ctxt = vm::_ptr<SpursKernelContext>(spu.offset + spu.gpr[3]._u32[3]);
|
||||
const auto ctxt = spu._ptr<SpursKernelContext>(spu.gpr[3]._u32[3]);
|
||||
auto arg = spu.gpr[4]._u64[1];
|
||||
auto pollStatus = spu.gpr[5]._u32[3];
|
||||
|
||||
@ -754,8 +754,8 @@ void spursSysServiceIdleHandler(spu_thread& spu, SpursKernelContext* ctxt)
|
||||
|
||||
while (true)
|
||||
{
|
||||
//vm::reservation_acquire(vm::base(spu.offset + 0x100), vm::cast(ctxt->spurs.addr(), HERE), 128);
|
||||
auto spurs = vm::_ptr<CellSpurs>(spu.offset + 0x100);
|
||||
const auto spurs = spu._ptr<CellSpurs>(0x100);
|
||||
//vm::reservation_acquire(spurs, vm::cast(ctxt->spurs.addr(), HERE), 128);
|
||||
|
||||
// Find the number of SPUs that are idling in this SPURS instance
|
||||
u32 nIdlingSpus = 0;
|
||||
@ -843,7 +843,7 @@ void spursSysServiceIdleHandler(spu_thread& spu, SpursKernelContext* ctxt)
|
||||
continue;
|
||||
}
|
||||
|
||||
//if (vm::reservation_update(vm::cast(ctxt->spurs.addr(), HERE), vm::base(spu.offset + 0x100), 128) && (shouldExit || foundReadyWorkload))
|
||||
//if (vm::reservation_update(vm::cast(ctxt->spurs.addr(), HERE), spu._ptr<void>(0x100), 128) && (shouldExit || foundReadyWorkload))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -858,7 +858,7 @@ void spursSysServiceIdleHandler(spu_thread& spu, SpursKernelContext* ctxt)
|
||||
// Main function for the system service
|
||||
void spursSysServiceMain(spu_thread& spu, u32 pollStatus)
|
||||
{
|
||||
auto ctxt = vm::_ptr<SpursKernelContext>(spu.offset + 0x100);
|
||||
const auto ctxt = spu._ptr<SpursKernelContext>(0x100);
|
||||
|
||||
if (!ctxt->spurs.aligned())
|
||||
{
|
||||
@ -871,7 +871,7 @@ void spursSysServiceMain(spu_thread& spu, u32 pollStatus)
|
||||
{
|
||||
ctxt->sysSrvInitialised = 1;
|
||||
|
||||
//vm::reservation_acquire(vm::base(spu.offset + 0x100), vm::cast(ctxt->spurs.addr(), HERE), 128);
|
||||
//vm::reservation_acquire(ctxt, vm::cast(ctxt->spurs.addr(), HERE), 128);
|
||||
|
||||
//vm::reservation_op(ctxt->spurs.ptr(&CellSpurs::wklState1).addr(), 128, [&]()
|
||||
{
|
||||
@ -886,7 +886,7 @@ void spursSysServiceMain(spu_thread& spu, u32 pollStatus)
|
||||
|
||||
spurs->sysSrvOnSpu |= 1 << ctxt->spuNum;
|
||||
|
||||
std::memcpy(vm::base(spu.offset + 0x2D80), spurs->wklState1, 128);
|
||||
std::memcpy(spu._ptr<void>(0x2D80), spurs->wklState1, 128);
|
||||
}//);
|
||||
|
||||
ctxt->traceBuffer = 0;
|
||||
@ -987,7 +987,7 @@ void spursSysServiceProcessRequests(spu_thread& spu, SpursKernelContext* ctxt)
|
||||
updateTrace = true;
|
||||
}
|
||||
|
||||
std::memcpy(vm::base(spu.offset + 0x2D80), spurs->wklState1, 128);
|
||||
std::memcpy(spu._ptr<void>(0x2D80), spurs->wklState1, 128);
|
||||
}//);
|
||||
|
||||
// Process update workload message
|
||||
@ -1012,11 +1012,11 @@ void spursSysServiceProcessRequests(spu_thread& spu, SpursKernelContext* ctxt)
|
||||
// Activate a workload
|
||||
void spursSysServiceActivateWorkload(spu_thread& spu, SpursKernelContext* ctxt)
|
||||
{
|
||||
auto spurs = vm::_ptr<CellSpurs>(spu.offset + 0x100);
|
||||
std::memcpy(vm::base(spu.offset + 0x30000), ctxt->spurs->wklInfo1, 0x200);
|
||||
const auto spurs = spu._ptr<CellSpurs>(0x100);
|
||||
std::memcpy(spu._ptr<void>(0x30000), ctxt->spurs->wklInfo1, 0x200);
|
||||
if (spurs->flags1 & SF1_32_WORKLOADS)
|
||||
{
|
||||
std::memcpy(vm::base(spu.offset + 0x30200), ctxt->spurs->wklInfo2, 0x200);
|
||||
std::memcpy(spu._ptr<void>(0x30200), ctxt->spurs->wklInfo2, 0x200);
|
||||
}
|
||||
|
||||
u32 wklShutdownBitSet = 0;
|
||||
@ -1024,7 +1024,7 @@ void spursSysServiceActivateWorkload(spu_thread& spu, SpursKernelContext* ctxt)
|
||||
ctxt->wklRunnable2 = 0;
|
||||
for (u32 i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++)
|
||||
{
|
||||
auto wklInfo1 = vm::_ptr<CellSpurs::WorkloadInfo>(spu.offset + 0x30000);
|
||||
const auto wklInfo1 = spu._ptr<CellSpurs::WorkloadInfo>(0x30000);
|
||||
|
||||
// Copy the priority of the workload for this SPU and its unique id to the LS
|
||||
ctxt->priority[i] = wklInfo1[i].priority[ctxt->spuNum] == 0 ? 0 : 0x10 - wklInfo1[i].priority[ctxt->spuNum];
|
||||
@ -1032,7 +1032,7 @@ void spursSysServiceActivateWorkload(spu_thread& spu, SpursKernelContext* ctxt)
|
||||
|
||||
if (spurs->flags1 & SF1_32_WORKLOADS)
|
||||
{
|
||||
auto wklInfo2 = vm::_ptr<CellSpurs::WorkloadInfo>(spu.offset + 0x30200);
|
||||
const auto wklInfo2 = spu._ptr<CellSpurs::WorkloadInfo>(0x30200);
|
||||
|
||||
// Copy the priority of the workload for this SPU to the LS
|
||||
if (wklInfo2[i].priority[ctxt->spuNum])
|
||||
@ -1098,7 +1098,7 @@ void spursSysServiceActivateWorkload(spu_thread& spu, SpursKernelContext* ctxt)
|
||||
}
|
||||
}
|
||||
|
||||
std::memcpy(vm::base(spu.offset + 0x2D80), spurs->wklState1, 128);
|
||||
std::memcpy(spu._ptr<void>(0x2D80), spurs->wklState1, 128);
|
||||
}//);
|
||||
|
||||
if (wklShutdownBitSet)
|
||||
@ -1141,7 +1141,7 @@ void spursSysServiceUpdateShutdownCompletionEvents(spu_thread& spu, SpursKernelC
|
||||
}
|
||||
}
|
||||
|
||||
std::memcpy(vm::base(spu.offset + 0x2D80), spurs->wklState1, 128);
|
||||
std::memcpy(spu._ptr<void>(0x2D80), spurs->wklState1, 128);
|
||||
}//);
|
||||
|
||||
if (wklNotifyBitSet)
|
||||
@ -1189,14 +1189,14 @@ void spursSysServiceTraceUpdate(spu_thread& spu, SpursKernelContext* ctxt, u32 a
|
||||
notify = true;
|
||||
}
|
||||
|
||||
std::memcpy(vm::base(spu.offset + 0x2D80), spurs->wklState1, 128);
|
||||
std::memcpy(spu._ptr<void>(0x2D80), spurs->wklState1, 128);
|
||||
}//);
|
||||
|
||||
// Get trace parameters from CellSpurs and store them in the LS
|
||||
if (((sysSrvMsgUpdateTrace & (1 << ctxt->spuNum)) != 0) || (arg3 != 0))
|
||||
{
|
||||
//vm::reservation_acquire(vm::base(spu.offset + 0x80), ctxt->spurs.ptr(&CellSpurs::traceBuffer).addr(), 128);
|
||||
auto spurs = vm::_ptr<CellSpurs>(spu.offset + 0x80 - offset32(&CellSpurs::traceBuffer));
|
||||
//vm::reservation_acquire(spu._ptr<void>(0x80), ctxt->spurs.ptr(&CellSpurs::traceBuffer).addr(), 128);
|
||||
auto spurs = spu._ptr<CellSpurs>(0x80 - offset32(&CellSpurs::traceBuffer));
|
||||
|
||||
if (ctxt->traceMsgCount != 0xffu || spurs->traceBuffer.addr() == 0u)
|
||||
{
|
||||
@ -1204,8 +1204,8 @@ void spursSysServiceTraceUpdate(spu_thread& spu, SpursKernelContext* ctxt, u32 a
|
||||
}
|
||||
else
|
||||
{
|
||||
std::memcpy(vm::base(spu.offset + 0x2C00), vm::base(vm::cast(spurs->traceBuffer.addr(), HERE) & -0x4), 0x80);
|
||||
auto traceBuffer = vm::_ptr<CellSpursTraceInfo>(spu.offset + 0x2C00);
|
||||
const auto traceBuffer = spu._ptr<CellSpursTraceInfo>(0x2C00);
|
||||
std::memcpy(traceBuffer, vm::base(vm::cast(spurs->traceBuffer.addr(), HERE) & -0x4), 0x80);
|
||||
ctxt->traceMsgCount = traceBuffer->count[ctxt->spuNum];
|
||||
}
|
||||
|
||||
@ -1219,7 +1219,7 @@ void spursSysServiceTraceUpdate(spu_thread& spu, SpursKernelContext* ctxt, u32 a
|
||||
|
||||
if (notify)
|
||||
{
|
||||
auto spurs = vm::_ptr<CellSpurs>(spu.offset + 0x2D80 - offset32(&CellSpurs::wklState1));
|
||||
auto spurs = spu._ptr<CellSpurs>(0x2D80 - offset32(&CellSpurs::wklState1));
|
||||
sys_spu_thread_send_event(spu, spurs->spuPort, 2, 0);
|
||||
}
|
||||
}
|
||||
@ -1244,7 +1244,7 @@ void spursSysServiceCleanupAfterSystemWorkload(spu_thread& spu, SpursKernelConte
|
||||
wklId = spurs->sysSrvPreemptWklId[ctxt->spuNum];
|
||||
spurs->sysSrvPreemptWklId[ctxt->spuNum] = 0xFF;
|
||||
|
||||
std::memcpy(vm::base(spu.offset + 0x2D80), spurs->wklState1, 128);
|
||||
std::memcpy(spu._ptr<void>(0x2D80), spurs->wklState1, 128);
|
||||
}//);
|
||||
|
||||
if (do_return) return;
|
||||
@ -1266,7 +1266,7 @@ void spursSysServiceCleanupAfterSystemWorkload(spu_thread& spu, SpursKernelConte
|
||||
spurs->wklIdleSpuCountOrReadyCount2[wklId & 0x0F].raw() -= 1;
|
||||
}
|
||||
|
||||
std::memcpy(vm::base(spu.offset + 0x100), spurs, 128);
|
||||
std::memcpy(spu._ptr<void>(0x100), spurs, 128);
|
||||
}//);
|
||||
|
||||
// Set the current workload id to the id of the pre-empted workload since cellSpursModulePutTrace
|
||||
@ -1302,8 +1302,8 @@ enum SpursTasksetRequest
|
||||
// Taskset PM entry point
|
||||
bool spursTasksetEntry(spu_thread& spu)
|
||||
{
|
||||
auto ctxt = vm::_ptr<SpursTasksetContext>(spu.offset + 0x2700);
|
||||
auto kernelCtxt = vm::_ptr<SpursKernelContext>(spu.offset + spu.gpr[3]._u32[3]);
|
||||
auto ctxt = spu._ptr<SpursTasksetContext>(0x2700);
|
||||
auto kernelCtxt = spu._ptr<SpursKernelContext>(spu.gpr[3]._u32[3]);
|
||||
|
||||
auto arg = spu.gpr[4]._u64[1];
|
||||
auto pollStatus = spu.gpr[5]._u32[3];
|
||||
@ -1337,7 +1337,7 @@ bool spursTasksetEntry(spu_thread& spu)
|
||||
// Entry point into the Taskset PM for task syscalls
|
||||
bool spursTasksetSyscallEntry(spu_thread& spu)
|
||||
{
|
||||
auto ctxt = vm::_ptr<SpursTasksetContext>(spu.offset + 0x2700);
|
||||
auto ctxt = spu._ptr<SpursTasksetContext>(0x2700);
|
||||
|
||||
{
|
||||
// Save task context
|
||||
@ -1364,7 +1364,7 @@ bool spursTasksetSyscallEntry(spu_thread& spu)
|
||||
// Resume a task
|
||||
void spursTasksetResumeTask(spu_thread& spu)
|
||||
{
|
||||
auto ctxt = vm::_ptr<SpursTasksetContext>(spu.offset + 0x2700);
|
||||
auto ctxt = spu._ptr<SpursTasksetContext>(0x2700);
|
||||
|
||||
// Restore task context
|
||||
spu.gpr[0] = ctxt->savedContextLr;
|
||||
@ -1380,8 +1380,8 @@ void spursTasksetResumeTask(spu_thread& spu)
|
||||
// Start a task
|
||||
void spursTasksetStartTask(spu_thread& spu, CellSpursTaskArgument& taskArgs)
|
||||
{
|
||||
auto ctxt = vm::_ptr<SpursTasksetContext>(spu.offset + 0x2700);
|
||||
auto taskset = vm::_ptr<CellSpursTaskset>(spu.offset + 0x2700);
|
||||
auto ctxt = spu._ptr<SpursTasksetContext>(0x2700);
|
||||
auto taskset = spu._ptr<CellSpursTaskset>(0x2700);
|
||||
|
||||
spu.gpr[2].clear();
|
||||
spu.gpr[3] = v128::from64r(taskArgs._u64[0], taskArgs._u64[1]);
|
||||
@ -1398,8 +1398,8 @@ void spursTasksetStartTask(spu_thread& spu, CellSpursTaskArgument& taskArgs)
|
||||
// Process a request and update the state of the taskset
|
||||
s32 spursTasksetProcessRequest(spu_thread& spu, s32 request, u32* taskId, u32* isWaiting)
|
||||
{
|
||||
auto kernelCtxt = vm::_ptr<SpursKernelContext>(spu.offset + 0x100);
|
||||
auto ctxt = vm::_ptr<SpursTasksetContext>(spu.offset + 0x2700);
|
||||
auto kernelCtxt = spu._ptr<SpursKernelContext>(0x100);
|
||||
auto ctxt = spu._ptr<SpursTasksetContext>(0x2700);
|
||||
|
||||
s32 rc = CELL_OK;
|
||||
s32 numNewlyReadyTasks;
|
||||
@ -1561,7 +1561,7 @@ s32 spursTasksetProcessRequest(spu_thread& spu, s32 request, u32* taskId, u32* i
|
||||
taskset->signalled = signalled;
|
||||
taskset->ready = ready;
|
||||
|
||||
std::memcpy(vm::base(spu.offset + 0x2700), taskset, 128);
|
||||
std::memcpy(spu._ptr<void>(0x2700), taskset, 128);
|
||||
}//);
|
||||
|
||||
// Increment the ready count of the workload by the number of tasks that have become ready
|
||||
@ -1582,7 +1582,7 @@ s32 spursTasksetProcessRequest(spu_thread& spu, s32 request, u32* taskId, u32* i
|
||||
spurs->wklIdleSpuCountOrReadyCount2[kernelCtxt->wklCurrentId & 0x0F] = readyCount;
|
||||
}
|
||||
|
||||
std::memcpy(vm::base(spu.offset + 0x100), spurs, 128);
|
||||
std::memcpy(spu._ptr<void>(0x100), spurs, 128);
|
||||
}//);
|
||||
|
||||
return rc;
|
||||
@ -1614,7 +1614,7 @@ bool spursTasksetPollStatus(spu_thread& spu)
|
||||
// Exit the Taskset PM
|
||||
void spursTasksetExit(spu_thread& spu)
|
||||
{
|
||||
auto ctxt = vm::_ptr<SpursTasksetContext>(spu.offset + 0x2700);
|
||||
auto ctxt = spu._ptr<SpursTasksetContext>(0x2700);
|
||||
|
||||
// Trace - STOP
|
||||
CellSpursTracePacket pkt{};
|
||||
@ -1635,9 +1635,9 @@ void spursTasksetExit(spu_thread& spu)
|
||||
// Invoked when a task exits
|
||||
void spursTasksetOnTaskExit(spu_thread& spu, u64 addr, u32 taskId, s32 exitCode, u64 args)
|
||||
{
|
||||
auto ctxt = vm::_ptr<SpursTasksetContext>(spu.offset + 0x2700);
|
||||
auto ctxt = spu._ptr<SpursTasksetContext>(0x2700);
|
||||
|
||||
std::memcpy(vm::base(spu.offset + 0x10000), vm::base(addr & -0x80), (addr & 0x7F) << 11);
|
||||
std::memcpy(spu._ptr<void>(0x10000), vm::base(addr & -0x80), (addr & 0x7F) << 11);
|
||||
|
||||
spu.gpr[3]._u64[1] = ctxt->taskset.addr();
|
||||
spu.gpr[4]._u32[3] = taskId;
|
||||
@ -1649,8 +1649,8 @@ void spursTasksetOnTaskExit(spu_thread& spu, u64 addr, u32 taskId, s32 exitCode,
|
||||
// Save the context of a task
|
||||
s32 spursTasketSaveTaskContext(spu_thread& spu)
|
||||
{
|
||||
auto ctxt = vm::_ptr<SpursTasksetContext>(spu.offset + 0x2700);
|
||||
auto taskInfo = vm::_ptr<CellSpursTaskset::TaskInfo>(spu.offset + 0x2780);
|
||||
auto ctxt = spu._ptr<SpursTasksetContext>(0x2700);
|
||||
auto taskInfo = spu._ptr<CellSpursTaskset::TaskInfo>(0x2780);
|
||||
|
||||
//spursDmaWaitForCompletion(spu, 0xFFFFFFFF);
|
||||
|
||||
@ -1693,7 +1693,7 @@ s32 spursTasketSaveTaskContext(spu_thread& spu)
|
||||
|
||||
// Store the processor context
|
||||
const u32 contextSaveStorage = vm::cast(taskInfo->context_save_storage_and_alloc_ls_blocks & -0x80, HERE);
|
||||
std::memcpy(vm::base(contextSaveStorage), vm::base(spu.offset + 0x2C80), 0x380);
|
||||
std::memcpy(vm::base(contextSaveStorage), spu._ptr<void>(0x2C80), 0x380);
|
||||
|
||||
// Save LS context
|
||||
for (auto i = 6; i < 128; i++)
|
||||
@ -1701,7 +1701,7 @@ s32 spursTasketSaveTaskContext(spu_thread& spu)
|
||||
if (ls_pattern._bit[i])
|
||||
{
|
||||
// TODO: Combine DMA requests for consecutive blocks into a single request
|
||||
std::memcpy(vm::base(contextSaveStorage + 0x400 + ((i - 6) << 11)), vm::base(spu.offset + CELL_SPURS_TASK_TOP + ((i - 6) << 11)), 0x800);
|
||||
std::memcpy(vm::base(contextSaveStorage + 0x400 + ((i - 6) << 11)), spu._ptr<void>(CELL_SPURS_TASK_TOP + ((i - 6) << 11)), 0x800);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1712,8 +1712,8 @@ s32 spursTasketSaveTaskContext(spu_thread& spu)
|
||||
// Taskset dispatcher
|
||||
void spursTasksetDispatch(spu_thread& spu)
|
||||
{
|
||||
auto ctxt = vm::_ptr<SpursTasksetContext>(spu.offset + 0x2700);
|
||||
auto taskset = vm::_ptr<CellSpursTaskset>(spu.offset + 0x2700);
|
||||
const auto ctxt = spu._ptr<SpursTasksetContext>(0x2700);
|
||||
const auto taskset = spu._ptr<CellSpursTaskset>(0x2700);
|
||||
|
||||
u32 taskId;
|
||||
u32 isWaiting;
|
||||
@ -1727,8 +1727,8 @@ void spursTasksetDispatch(spu_thread& spu)
|
||||
ctxt->taskId = taskId;
|
||||
|
||||
// DMA in the task info for the selected task
|
||||
std::memcpy(vm::base(spu.offset + 0x2780), &ctxt->taskset->task_info[taskId], sizeof(CellSpursTaskset::TaskInfo));
|
||||
auto taskInfo = vm::_ptr<CellSpursTaskset::TaskInfo>(spu.offset + 0x2780);
|
||||
const auto taskInfo = spu._ptr<CellSpursTaskset::TaskInfo>(0x2780);
|
||||
std::memcpy(taskInfo, &ctxt->taskset->task_info[taskId], sizeof(CellSpursTaskset::TaskInfo));
|
||||
auto elfAddr = taskInfo->elf.addr().value();
|
||||
taskInfo->elf.set(taskInfo->elf.addr() & 0xFFFFFFFFFFFFFFF8);
|
||||
|
||||
@ -1742,7 +1742,7 @@ void spursTasksetDispatch(spu_thread& spu)
|
||||
if (isWaiting == 0)
|
||||
{
|
||||
// If we reach here it means that the task is being started and not being resumed
|
||||
std::memset(vm::base(spu.offset + CELL_SPURS_TASK_TOP), 0, CELL_SPURS_TASK_BOTTOM - CELL_SPURS_TASK_TOP);
|
||||
std::memset(spu._ptr<void>(CELL_SPURS_TASK_TOP), 0, CELL_SPURS_TASK_BOTTOM - CELL_SPURS_TASK_TOP);
|
||||
ctxt->guidAddr = CELL_SPURS_TASK_TOP;
|
||||
|
||||
u32 entryPoint;
|
||||
@ -1764,7 +1764,7 @@ void spursTasksetDispatch(spu_thread& spu)
|
||||
|
||||
if ((elfAddr & 5) == 1)
|
||||
{
|
||||
std::memcpy(vm::base(spu.offset + 0x2FC0), &vm::_ptr<CellSpursTaskset2>(vm::cast(ctxt->taskset.addr()))->task_exit_code[taskId], 0x10);
|
||||
std::memcpy(spu._ptr<void>(0x2FC0), &vm::_ptr<CellSpursTaskset2>(vm::cast(ctxt->taskset.addr()))->task_exit_code[taskId], 0x10);
|
||||
}
|
||||
|
||||
// Trace - GUID
|
||||
@ -1785,7 +1785,7 @@ void spursTasksetDispatch(spu_thread& spu)
|
||||
{
|
||||
if (taskset->enable_clear_ls)
|
||||
{
|
||||
std::memset(vm::base(spu.offset + CELL_SPURS_TASK_TOP), 0, CELL_SPURS_TASK_BOTTOM - CELL_SPURS_TASK_TOP);
|
||||
std::memset(spu._ptr<void>(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 as well
|
||||
@ -1803,13 +1803,13 @@ void spursTasksetDispatch(spu_thread& spu)
|
||||
|
||||
// Load saved context from main memory to LS
|
||||
const u32 contextSaveStorage = vm::cast(taskInfo->context_save_storage_and_alloc_ls_blocks & -0x80, HERE);
|
||||
std::memcpy(vm::base(spu.offset + 0x2C80), vm::base(contextSaveStorage), 0x380);
|
||||
std::memcpy(spu._ptr<void>(0x2C80), vm::base(contextSaveStorage), 0x380);
|
||||
for (auto i = 6; i < 128; i++)
|
||||
{
|
||||
if (ls_pattern._bit[i])
|
||||
{
|
||||
// TODO: Combine DMA requests for consecutive blocks into a single request
|
||||
std::memcpy(vm::base(spu.offset + CELL_SPURS_TASK_TOP + ((i - 6) << 11)), vm::base(contextSaveStorage + 0x400 + ((i - 6) << 11)), 0x800);
|
||||
std::memcpy(spu._ptr<void>(CELL_SPURS_TASK_TOP + ((i - 6) << 11)), vm::base(contextSaveStorage + 0x400 + ((i - 6) << 11)), 0x800);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1840,8 +1840,8 @@ void spursTasksetDispatch(spu_thread& spu)
|
||||
// Process a syscall request
|
||||
s32 spursTasksetProcessSyscall(spu_thread& spu, u32 syscallNum, u32 args)
|
||||
{
|
||||
auto ctxt = vm::_ptr<SpursTasksetContext>(spu.offset + 0x2700);
|
||||
auto taskset = vm::_ptr<CellSpursTaskset>(spu.offset + 0x2700);
|
||||
auto ctxt = spu._ptr<SpursTasksetContext>(0x2700);
|
||||
auto taskset = spu._ptr<CellSpursTaskset>(0x2700);
|
||||
|
||||
// If the 0x10 bit is set in syscallNum then its the 2nd version of the
|
||||
// syscall (e.g. cellSpursYield2 instead of cellSpursYield) and so don't wait
|
||||
@ -1931,7 +1931,7 @@ s32 spursTasksetProcessSyscall(spu_thread& spu, u32 syscallNum, u32 args)
|
||||
cellSpursModulePutTrace(&pkt, ctxt->dmaTagId);
|
||||
|
||||
// Clear the GUID of the task
|
||||
std::memset(vm::base(spu.offset + ctxt->guidAddr), 0, 0x10);
|
||||
std::memset(spu._ptr<void>(ctxt->guidAddr), 0, 0x10);
|
||||
|
||||
if (spursTasksetPollStatus(spu))
|
||||
{
|
||||
@ -1949,8 +1949,8 @@ s32 spursTasksetProcessSyscall(spu_thread& spu, u32 syscallNum, u32 args)
|
||||
// Initialise the Taskset PM
|
||||
void spursTasksetInit(spu_thread& spu, u32 pollStatus)
|
||||
{
|
||||
auto ctxt = vm::_ptr<SpursTasksetContext>(spu.offset + 0x2700);
|
||||
auto kernelCtxt = vm::_ptr<SpursKernelContext>(spu.offset + 0x100);
|
||||
auto ctxt = spu._ptr<SpursTasksetContext>(0x2700);
|
||||
auto kernelCtxt = spu._ptr<SpursKernelContext>(0x100);
|
||||
|
||||
kernelCtxt->moduleId[0] = 'T';
|
||||
kernelCtxt->moduleId[1] = 'K';
|
||||
@ -2014,7 +2014,7 @@ s32 spursTasksetLoadElf(spu_thread& spu, u32* entryPoint, u32* lowestLoadAddr, u
|
||||
{
|
||||
if (skipWriteableSegments == false || (prog.p_flags & 2u) == 0u)
|
||||
{
|
||||
std::memcpy(vm::base(spu.offset + prog.p_vaddr), prog.bin.data(), prog.p_filesz);
|
||||
std::memcpy(spu._ptr<void>(prog.p_vaddr), prog.bin.data(), prog.p_filesz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -391,7 +391,7 @@ s32 sys_raw_spu_load(s32 id, vm::cptr<char> path, vm::ptr<u32> entry)
|
||||
|
||||
sys_spu_image img;
|
||||
img.load(elf_file);
|
||||
img.deploy(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id, img.segs.get_ptr(), img.nsegs);
|
||||
img.deploy(vm::_ptr<u8>(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id), img.segs.get_ptr(), img.nsegs);
|
||||
img.free();
|
||||
|
||||
*entry = img.entry_point;
|
||||
@ -404,7 +404,7 @@ s32 sys_raw_spu_image_load(ppu_thread& ppu, s32 id, vm::ptr<sys_spu_image> img)
|
||||
sysPrxForUser.warning("sys_raw_spu_image_load(id=%d, img=*0x%x)", id, img);
|
||||
|
||||
// Load SPU segments
|
||||
img->deploy(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id, img->segs.get_ptr(), img->nsegs);
|
||||
img->deploy(vm::_ptr<u8>(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id), img->segs.get_ptr(), img->nsegs);
|
||||
|
||||
// Use MMIO
|
||||
vm::write32(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id + RAW_SPU_PROB_OFFSET + SPU_NPC_offs, img->entry_point);
|
||||
|
@ -1659,8 +1659,8 @@ void spu_recompiler::RDCH(spu_opcode_t op)
|
||||
{
|
||||
const XmmLink& vr = XmmAlloc();
|
||||
c->movzx(*addr, SPU_OFF_8(interrupts_enabled));
|
||||
c->movzx(arg1->r32(), SPU_OFF_8(is_isolated));
|
||||
c->shl(arg1->r32(), 1);
|
||||
c->mov(arg1->r32(), SPU_OFF_32(thread_type));
|
||||
c->and_(arg1->r32(), 2);
|
||||
c->or_(addr->r32(), arg1->r32());
|
||||
c->movd(vr, *addr);
|
||||
c->pslldq(vr, 12);
|
||||
|
@ -5502,7 +5502,7 @@ public:
|
||||
case SPU_RdMachStat:
|
||||
{
|
||||
res.value = m_ir->CreateZExt(m_ir->CreateLoad(spu_ptr<u8>(&spu_thread::interrupts_enabled)), get_type<u32>());
|
||||
res.value = m_ir->CreateOr(res.value, m_ir->CreateShl(m_ir->CreateZExt(m_ir->CreateLoad(spu_ptr<u8>(&spu_thread::is_isolated)), get_type<u32>()), m_ir->getInt32(1)));
|
||||
res.value = m_ir->CreateOr(res.value, m_ir->CreateAnd(m_ir->CreateLoad(spu_ptr<u32>(&spu_thread::thread_type)), m_ir->getInt32(2)));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,22 @@ void fmt_class_string<mfc_tag_update>::format(std::string& out, u64 arg)
|
||||
});
|
||||
}
|
||||
|
||||
template <>
|
||||
void fmt_class_string<spu_type>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](spu_type arg)
|
||||
{
|
||||
switch (arg)
|
||||
{
|
||||
case spu_type::threaded: return "Threaded";
|
||||
case spu_type::raw: return "Raw";
|
||||
case spu_type::isolated: return "Isolated";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
// Verify AVX availability for TSX transactions
|
||||
static const bool s_tsx_avx = utils::has_avx();
|
||||
|
||||
@ -968,7 +984,7 @@ void spu_thread::cpu_init()
|
||||
ch_dec_start_timestamp = get_timebased_time(); // ???
|
||||
ch_dec_value = 0;
|
||||
|
||||
if (offset >= RAW_SPU_BASE_ADDR)
|
||||
if (get_type() >= spu_type::raw)
|
||||
{
|
||||
ch_in_mbox.clear();
|
||||
ch_snr1.data.raw() = {};
|
||||
@ -980,7 +996,7 @@ void spu_thread::cpu_init()
|
||||
mfc_prxy_write_state = {};
|
||||
}
|
||||
|
||||
status_npc.raw() = {is_isolated ? SPU_STATUS_IS_ISOLATED : 0, 0};
|
||||
status_npc.raw() = {get_type() == spu_type::isolated ? SPU_STATUS_IS_ISOLATED : 0, 0};
|
||||
run_ctrl.raw() = 0;
|
||||
|
||||
int_ctrl[0].clear();
|
||||
@ -992,7 +1008,7 @@ void spu_thread::cpu_init()
|
||||
|
||||
void spu_thread::cpu_stop()
|
||||
{
|
||||
if (!group && offset >= RAW_SPU_BASE_ADDR)
|
||||
if (get_type() >= spu_type::raw)
|
||||
{
|
||||
if (status_npc.fetch_op([this](status_npc_sync_var& state)
|
||||
{
|
||||
@ -1011,7 +1027,7 @@ void spu_thread::cpu_stop()
|
||||
status_npc.notify_one();
|
||||
}
|
||||
}
|
||||
else if (group && is_stopped())
|
||||
else if (is_stopped())
|
||||
{
|
||||
ch_in_mbox.clear();
|
||||
|
||||
@ -1092,7 +1108,8 @@ void spu_thread::cpu_task()
|
||||
name_cache = cpu->spu_tname.load();
|
||||
}
|
||||
|
||||
return fmt::format("%sSPU[0x%07x] Thread (%s) [0x%05x]", cpu->offset >= RAW_SPU_BASE_ADDR ? cpu->is_isolated ? "Iso" : "Raw" : "", cpu->lv2_id, *name_cache.get(), cpu->pc);
|
||||
const auto type = cpu->get_type();
|
||||
return fmt::format("%sSPU[0x%07x] Thread (%s) [0x%05x]", type >= spu_type::raw ? type == spu_type::isolated ? "Iso" : "Raw" : "", cpu->lv2_id, *name_cache.get(), cpu->pc);
|
||||
};
|
||||
|
||||
if (jit)
|
||||
@ -1166,7 +1183,7 @@ spu_thread::~spu_thread()
|
||||
utils::memory_release(ls - SPU_LS_SIZE, SPU_LS_SIZE * 3);
|
||||
|
||||
// Deallocate RawSPU ID
|
||||
if (!group && offset >= RAW_SPU_BASE_ADDR)
|
||||
if (get_type() >= spu_type::raw)
|
||||
{
|
||||
g_raw_spu_id[index] = 0;
|
||||
g_raw_spu_ctr--;
|
||||
@ -1175,9 +1192,7 @@ spu_thread::~spu_thread()
|
||||
|
||||
spu_thread::spu_thread(vm::addr_t _ls, lv2_spu_group* group, u32 index, std::string_view name, u32 lv2_id, bool is_isolated)
|
||||
: cpu_thread(idm::last_id())
|
||||
, is_isolated(is_isolated)
|
||||
, index(index)
|
||||
, offset(_ls)
|
||||
, ls([&]()
|
||||
{
|
||||
const auto [_, shm] = vm::get(vm::any, _ls)->get(_ls);
|
||||
@ -1193,6 +1208,8 @@ spu_thread::spu_thread(vm::addr_t _ls, lv2_spu_group* group, u32 index, std::str
|
||||
// Use the middle mirror
|
||||
return addr + SPU_LS_SIZE;
|
||||
}())
|
||||
, thread_type(group ? spu_type::threaded : is_isolated ? spu_type::isolated : spu_type::raw)
|
||||
, offset(_ls)
|
||||
, group(group)
|
||||
, lv2_id(lv2_id)
|
||||
, spu_tname(stx::shared_cptr<std::string>::make(name))
|
||||
@ -1216,7 +1233,7 @@ spu_thread::spu_thread(vm::addr_t _ls, lv2_spu_group* group, u32 index, std::str
|
||||
}
|
||||
}
|
||||
|
||||
if (!group && offset >= RAW_SPU_BASE_ADDR)
|
||||
if (get_type() >= spu_type::raw)
|
||||
{
|
||||
cpu_init();
|
||||
}
|
||||
@ -1279,7 +1296,7 @@ void spu_thread::do_dma_transfer(const spu_mfc_cmd& args)
|
||||
fmt::throw_exception("Invalid RawSPU MMIO offset (cmd=0x%x, lsa=0x%x, ea=0x%llx, tag=0x%x, size=0x%x)" HERE, args.cmd, args.lsa, args.eal, args.tag, args.size);
|
||||
}
|
||||
}
|
||||
else if (this->offset >= RAW_SPU_BASE_ADDR)
|
||||
else if (get_type() >= spu_type::raw)
|
||||
{
|
||||
fmt::throw_exception("SPU MMIO used for RawSPU (cmd=0x%x, lsa=0x%x, ea=0x%llx, tag=0x%x, size=0x%x)" HERE, args.cmd, args.lsa, args.eal, args.tag, args.size);
|
||||
}
|
||||
@ -2618,7 +2635,7 @@ s64 spu_thread::get_ch_value(u32 ch)
|
||||
case SPU_RdMachStat:
|
||||
{
|
||||
// Return SPU Interrupt status in LSB
|
||||
return u32{interrupts_enabled} | (u32{is_isolated} << 1);
|
||||
return u32{interrupts_enabled} | (u32{get_type() == spu_type::isolated} << 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2639,7 +2656,7 @@ bool spu_thread::set_ch_value(u32 ch, u32 value)
|
||||
|
||||
case SPU_WrOutIntrMbox:
|
||||
{
|
||||
if (offset >= RAW_SPU_BASE_ADDR)
|
||||
if (get_type() >= spu_type::raw)
|
||||
{
|
||||
while (!ch_out_intr_mbox.try_push(value))
|
||||
{
|
||||
@ -2957,7 +2974,7 @@ bool spu_thread::stop_and_signal(u32 code)
|
||||
});
|
||||
};
|
||||
|
||||
if (offset >= RAW_SPU_BASE_ADDR)
|
||||
if (get_type() >= spu_type::raw)
|
||||
{
|
||||
// Save next PC and current SPU Interrupt Status
|
||||
state += cpu_flag::stop + cpu_flag::wait;
|
||||
@ -3351,7 +3368,7 @@ void spu_thread::halt()
|
||||
{
|
||||
spu_log.trace("halt()");
|
||||
|
||||
if (offset >= RAW_SPU_BASE_ADDR)
|
||||
if (get_type() >= spu_type::raw)
|
||||
{
|
||||
state += cpu_flag::stop + cpu_flag::wait;
|
||||
|
||||
|
@ -533,6 +533,13 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
enum class spu_type : u32
|
||||
{
|
||||
threaded,
|
||||
raw,
|
||||
isolated,
|
||||
};
|
||||
|
||||
class spu_thread : public cpu_thread
|
||||
{
|
||||
public:
|
||||
@ -630,7 +637,6 @@ public:
|
||||
u32 npc; // SPU Next Program Counter register
|
||||
};
|
||||
|
||||
const bool is_isolated;
|
||||
atomic_t<status_npc_sync_var> status_npc;
|
||||
std::array<spu_int_ctrl_t, 3> int_ctrl; // SPU Class 0, 1, 2 Interrupt Management
|
||||
|
||||
@ -640,9 +646,10 @@ public:
|
||||
atomic_t<u32> last_exit_status; // Value to be written in exit_status after checking group termination
|
||||
|
||||
const u32 index; // SPU index
|
||||
const u32 offset; // SPU LS offset
|
||||
const std::add_pointer_t<u8> ls; // SPU LS pointer
|
||||
const spu_type thread_type;
|
||||
private:
|
||||
const u32 offset; // SPU LS offset
|
||||
lv2_spu_group* const group; // SPU Thread Group (only safe to access in the spu thread itself)
|
||||
public:
|
||||
const u32 lv2_id; // The actual id that is used by syscalls
|
||||
@ -686,18 +693,23 @@ public:
|
||||
|
||||
// Convert specified SPU LS address to a pointer of specified (possibly converted to BE) type
|
||||
template<typename T>
|
||||
inline to_be_t<T>* _ptr(u32 lsa)
|
||||
to_be_t<T>* _ptr(u32 lsa) const
|
||||
{
|
||||
return reinterpret_cast<to_be_t<T>*>(ls + lsa);
|
||||
}
|
||||
|
||||
// Convert specified SPU LS address to a reference of specified (possibly converted to BE) type
|
||||
template<typename T>
|
||||
inline to_be_t<T>& _ref(u32 lsa)
|
||||
to_be_t<T>& _ref(u32 lsa) const
|
||||
{
|
||||
return *_ptr<T>(lsa);
|
||||
}
|
||||
|
||||
spu_type get_type() const
|
||||
{
|
||||
return thread_type;
|
||||
}
|
||||
|
||||
bool read_reg(const u32 addr, u32& value);
|
||||
bool write_reg(const u32 addr, const u32 value);
|
||||
|
||||
|
@ -108,7 +108,7 @@ void sys_spu_image::free()
|
||||
}
|
||||
}
|
||||
|
||||
void sys_spu_image::deploy(u32 loc, sys_spu_segment* segs, u32 nsegs)
|
||||
void sys_spu_image::deploy(u8* loc, sys_spu_segment* segs, u32 nsegs)
|
||||
{
|
||||
// Segment info dump
|
||||
std::string dump;
|
||||
@ -129,7 +129,7 @@ void sys_spu_image::deploy(u32 loc, sys_spu_segment* segs, u32 nsegs)
|
||||
// Hash big-endian values
|
||||
if (seg.type == SYS_SPU_SEGMENT_TYPE_COPY)
|
||||
{
|
||||
std::memcpy(vm::base(loc + seg.ls), vm::base(seg.addr), seg.size);
|
||||
std::memcpy(loc + seg.ls, vm::base(seg.addr), seg.size);
|
||||
sha1_update(&sha, reinterpret_cast<uchar*>(&seg.size), sizeof(seg.size));
|
||||
sha1_update(&sha, reinterpret_cast<uchar*>(&seg.ls), sizeof(seg.ls));
|
||||
sha1_update(&sha, vm::_ptr<uchar>(seg.addr), seg.size);
|
||||
@ -141,7 +141,7 @@ void sys_spu_image::deploy(u32 loc, sys_spu_segment* segs, u32 nsegs)
|
||||
spu_log.error("Unaligned SPU FILL type segment (ls=0x%x, size=0x%x)", seg.ls, seg.size);
|
||||
}
|
||||
|
||||
std::fill_n(vm::_ptr<u32>(loc + seg.ls), seg.size / 4, seg.addr);
|
||||
std::fill_n(reinterpret_cast<be_t<u32>*>(loc + seg.ls), seg.size / 4, seg.addr);
|
||||
sha1_update(&sha, reinterpret_cast<uchar*>(&seg.size), sizeof(seg.size));
|
||||
sha1_update(&sha, reinterpret_cast<uchar*>(&seg.ls), sizeof(seg.ls));
|
||||
sha1_update(&sha, reinterpret_cast<uchar*>(&seg.addr), sizeof(seg.addr));
|
||||
@ -165,12 +165,12 @@ void sys_spu_image::deploy(u32 loc, sys_spu_segment* segs, u32 nsegs)
|
||||
}
|
||||
|
||||
// Apply the patch
|
||||
auto applied = g_fxo->get<patch_engine>()->apply(hash, vm::_ptr<u8>(loc));
|
||||
auto applied = g_fxo->get<patch_engine>()->apply(hash, loc);
|
||||
|
||||
if (!Emu.GetTitleID().empty())
|
||||
{
|
||||
// Alternative patch
|
||||
applied += g_fxo->get<patch_engine>()->apply(Emu.GetTitleID() + '-' + hash, vm::_ptr<u8>(loc));
|
||||
applied += g_fxo->get<patch_engine>()->apply(Emu.GetTitleID() + '-' + hash, loc);
|
||||
}
|
||||
|
||||
spu_log.notice("Loaded SPU image: %s (<- %u)%s", hash, applied, dump);
|
||||
@ -726,7 +726,7 @@ error_code sys_spu_thread_group_start(ppu_thread& ppu, u32 id)
|
||||
auto& args = group->args[thread->lv2_id >> 24];
|
||||
auto& img = group->imgs[thread->lv2_id >> 24];
|
||||
|
||||
sys_spu_image::deploy(thread->offset, img.second.data(), img.first.nsegs);
|
||||
sys_spu_image::deploy(thread->ls, img.second.data(), img.first.nsegs);
|
||||
|
||||
thread->cpu_init();
|
||||
thread->gpr[3] = v128::from64(0, args[0]);
|
||||
@ -1894,7 +1894,7 @@ error_code sys_isolated_spu_create(ppu_thread& ppu, vm::ptr<u32> id, vm::ptr<voi
|
||||
img.load(obj);
|
||||
|
||||
auto image_info = idm::get<lv2_obj, lv2_spu_image>(img.entry_point);
|
||||
img.deploy(ls_addr, image_info->segs.get_ptr(), image_info->nsegs);
|
||||
img.deploy(thread->ls, image_info->segs.get_ptr(), image_info->nsegs);
|
||||
|
||||
thread->write_reg(ls_addr + RAW_SPU_PROB_OFFSET + SPU_NPC_offs, image_info->e_entry);
|
||||
verify(HERE), idm::remove_verify<lv2_obj, lv2_spu_image>(img.entry_point, std::move(image_info));
|
||||
@ -1910,7 +1910,7 @@ error_code raw_spu_destroy(ppu_thread& ppu, u32 id)
|
||||
|
||||
auto thread = idm::get<named_thread<spu_thread>>(idm_id, [](named_thread<spu_thread>& thread)
|
||||
{
|
||||
if (thread.is_isolated != isolated)
|
||||
if (thread.get_type() != (isolated ? spu_type::isolated : spu_type::raw))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -2014,7 +2014,7 @@ error_code raw_spu_create_interrupt_tag(u32 id, u32 class_id, u32 hwthread, vm::
|
||||
|
||||
auto thread = idm::check_unlocked<named_thread<spu_thread>>(spu_thread::find_raw_spu(id));
|
||||
|
||||
if (!thread || *thread == thread_state::aborting || thread->is_isolated != isolated)
|
||||
if (!thread || *thread == thread_state::aborting || thread->get_type() != (isolated ? spu_type::isolated : spu_type::raw))
|
||||
{
|
||||
error = CELL_ESRCH;
|
||||
return result;
|
||||
@ -2070,7 +2070,7 @@ error_code raw_spu_set_int_mask(u32 id, u32 class_id, u64 mask)
|
||||
|
||||
const auto thread = idm::get<named_thread<spu_thread>>(spu_thread::find_raw_spu(id));
|
||||
|
||||
if (!thread || thread->is_isolated != isolated) [[unlikely]]
|
||||
if (!thread || thread->get_type() != (isolated ? spu_type::isolated : spu_type::raw)) [[unlikely]]
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
@ -2109,7 +2109,7 @@ error_code raw_spu_set_int_stat(u32 id, u32 class_id, u64 stat)
|
||||
|
||||
const auto thread = idm::get<named_thread<spu_thread>>(spu_thread::find_raw_spu(id));
|
||||
|
||||
if (!thread || thread->is_isolated != isolated) [[unlikely]]
|
||||
if (!thread || thread->get_type() != (isolated ? spu_type::isolated : spu_type::raw)) [[unlikely]]
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
@ -2147,7 +2147,7 @@ error_code raw_spu_get_int_control(u32 id, u32 class_id, vm::ptr<u64> value, ato
|
||||
|
||||
const auto thread = idm::get<named_thread<spu_thread>>(spu_thread::find_raw_spu(id));
|
||||
|
||||
if (!thread || thread->is_isolated != isolated) [[unlikely]]
|
||||
if (!thread || thread->get_type() != (isolated ? spu_type::isolated : spu_type::raw)) [[unlikely]]
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
@ -2198,7 +2198,7 @@ error_code raw_spu_read_puint_mb(u32 id, vm::ptr<u32> value)
|
||||
{
|
||||
const auto thread = idm::get<named_thread<spu_thread>>(spu_thread::find_raw_spu(id));
|
||||
|
||||
if (!thread || thread->is_isolated != isolated) [[unlikely]]
|
||||
if (!thread || thread->get_type() != (isolated ? spu_type::isolated : spu_type::raw)) [[unlikely]]
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
@ -2236,7 +2236,7 @@ error_code raw_spu_set_spu_cfg(u32 id, u32 value)
|
||||
|
||||
const auto thread = idm::get<named_thread<spu_thread>>(spu_thread::find_raw_spu(id));
|
||||
|
||||
if (!thread || thread->is_isolated != isolated) [[unlikely]]
|
||||
if (!thread || thread->get_type() != (isolated ? spu_type::isolated : spu_type::raw)) [[unlikely]]
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
@ -2269,7 +2269,7 @@ error_code raw_spu_get_spu_cfg(u32 id, vm::ptr<u32> value)
|
||||
{
|
||||
const auto thread = idm::get<named_thread<spu_thread>>(spu_thread::find_raw_spu(id));
|
||||
|
||||
if (!thread || thread->is_isolated != isolated) [[unlikely]]
|
||||
if (!thread || thread->get_type() != (isolated ? spu_type::isolated : spu_type::raw)) [[unlikely]]
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
@ -2311,6 +2311,6 @@ error_code sys_isolated_spu_start(ppu_thread& ppu, u32 id)
|
||||
}
|
||||
|
||||
// TODO: Can return ESTAT if called twice
|
||||
thread->write_reg(thread->offset + RAW_SPU_PROB_OFFSET + SPU_RunCntl_offs, SPU_RUNCNTL_RUN_REQUEST);
|
||||
thread->write_reg(RAW_SPU_BASE_ADDR + thread->lv2_id * RAW_SPU_OFFSET + RAW_SPU_PROB_OFFSET + SPU_RunCntl_offs, SPU_RUNCNTL_RUN_REQUEST);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ struct sys_spu_image
|
||||
|
||||
void load(const fs::file& stream);
|
||||
void free();
|
||||
static void deploy(u32 loc, sys_spu_segment* segs, u32 nsegs);
|
||||
static void deploy(u8* loc, sys_spu_segment* segs, u32 nsegs);
|
||||
};
|
||||
|
||||
enum : u32
|
||||
|
@ -63,8 +63,8 @@ void breakpoint_list::AddBreakpoint(u32 pc)
|
||||
m_breakpoint_handler->AddBreakpoint(pc);
|
||||
|
||||
const auto cpu = this->cpu.lock();
|
||||
const u32 cpu_offset = cpu->id_type() != 1 ? static_cast<spu_thread&>(*cpu).offset : 0;
|
||||
m_disasm->offset = vm::_ptr<u8>(cpu_offset);
|
||||
const auto cpu_offset = cpu->id_type() != 1 ? static_cast<spu_thread&>(*cpu).ls : vm::g_sudo_addr;
|
||||
m_disasm->offset = cpu_offset;
|
||||
|
||||
m_disasm->disasm(m_disasm->dump_pc = pc);
|
||||
|
||||
|
@ -92,10 +92,10 @@ void debugger_list::ShowAddress(u32 addr, bool force)
|
||||
else
|
||||
{
|
||||
const bool is_spu = cpu->id_type() != 1;
|
||||
const u32 cpu_offset = is_spu ? static_cast<spu_thread&>(*cpu).offset : 0;
|
||||
const auto cpu_offset = cpu->id_type() != 1 ? static_cast<spu_thread&>(*cpu).ls : vm::g_sudo_addr;
|
||||
const u32 address_limits = (is_spu ? 0x3fffc : ~3);
|
||||
m_pc &= address_limits;
|
||||
m_disasm->offset = vm::get_super_ptr(cpu_offset);
|
||||
m_disasm->offset = cpu_offset;
|
||||
u32 pc = m_pc;
|
||||
|
||||
for (uint i = 0, count = 4; i<m_item_count; ++i, pc = (pc + count) & address_limits)
|
||||
@ -116,16 +116,16 @@ void debugger_list::ShowAddress(u32 addr, bool force)
|
||||
item(i)->setBackground(default_background);
|
||||
}
|
||||
|
||||
if (!vm::check_addr(cpu_offset + pc, 4))
|
||||
if (!is_spu && !vm::check_addr(pc, 4))
|
||||
{
|
||||
item(i)->setText((IsBreakpoint(pc) ? ">> " : " ") + qstr(fmt::format("[%08x] ?? ?? ?? ??:", pc)));
|
||||
count = 4;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!is_spu && !vm::check_addr(cpu_offset + pc, 4, vm::page_executable))
|
||||
if (!is_spu && !vm::check_addr(pc, 4, vm::page_executable))
|
||||
{
|
||||
const u32 data = *vm::get_super_ptr<atomic_be_t<u32>>(cpu_offset + pc);
|
||||
const u32 data = *vm::get_super_ptr<atomic_be_t<u32>>(pc);
|
||||
item(i)->setText((IsBreakpoint(pc) ? ">> " : " ") + qstr(fmt::format("[%08x] %02x %02x %02x %02x:", pc,
|
||||
static_cast<u8>(data >> 24),
|
||||
static_cast<u8>(data >> 16),
|
||||
|
@ -24,8 +24,8 @@ instruction_editor_dialog::instruction_editor_dialog(QWidget *parent, u32 _pc, c
|
||||
setMinimumSize(300, sizeHint().height());
|
||||
|
||||
const auto cpu = _cpu.get();
|
||||
m_cpu_offset = cpu->id_type() != 1 ? static_cast<spu_thread&>(*cpu).offset : 0;
|
||||
QString instruction = qstr(fmt::format("%08x", vm::read32(m_cpu_offset + m_pc).value()));
|
||||
m_cpu_offset = cpu->id_type() != 1 ? static_cast<spu_thread&>(*cpu).ls : vm::g_sudo_addr;
|
||||
QString instruction = qstr(fmt::format("%08x", *reinterpret_cast<be_t<u32>*>(m_cpu_offset + m_pc)));
|
||||
|
||||
QVBoxLayout* vbox_panel(new QVBoxLayout());
|
||||
QHBoxLayout* hbox_panel(new QHBoxLayout());
|
||||
@ -83,7 +83,7 @@ instruction_editor_dialog::instruction_editor_dialog(QWidget *parent, u32 _pc, c
|
||||
}
|
||||
else if (cpu->id_type() == 1)
|
||||
{
|
||||
if (!ppu_patch(m_cpu_offset + m_pc, static_cast<u32>(opcode)))
|
||||
if (!ppu_patch(m_pc, static_cast<u32>(opcode)))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Failed to patch PPU instruction."));
|
||||
return;
|
||||
@ -91,7 +91,8 @@ instruction_editor_dialog::instruction_editor_dialog(QWidget *parent, u32 _pc, c
|
||||
}
|
||||
else
|
||||
{
|
||||
vm::write32(m_cpu_offset + m_pc, static_cast<u32>(opcode));
|
||||
const be_t<u32> swapped{static_cast<u32>(opcode)};
|
||||
std::memcpy(m_cpu_offset + m_pc, &swapped, 4);
|
||||
}
|
||||
|
||||
accept();
|
||||
|
@ -15,7 +15,7 @@ class instruction_editor_dialog : public QDialog
|
||||
|
||||
private:
|
||||
u32 m_pc;
|
||||
u32 m_cpu_offset;
|
||||
u8* m_cpu_offset;
|
||||
CPUDisAsm* m_disasm;
|
||||
QLineEdit* m_instr;
|
||||
QLabel* m_preview;
|
||||
|
@ -471,18 +471,7 @@ void kernel_explorer::Update()
|
||||
|
||||
idm::select<named_thread<spu_thread>>([&](u32 /*id*/, spu_thread& spu)
|
||||
{
|
||||
std::string_view type = "threaded";
|
||||
|
||||
if (spu.is_isolated)
|
||||
{
|
||||
type = "isolated";
|
||||
}
|
||||
else if (spu.offset >= RAW_SPU_BASE_ADDR)
|
||||
{
|
||||
type = "raw";
|
||||
}
|
||||
|
||||
add_leaf(find_node(m_tree, additional_nodes::spu_threads), qstr(fmt::format(u8"SPU 0x%07x: “%s”, State: %s, Type: %s", spu.lv2_id, *spu.spu_tname.load(), spu.state.load(), type)));
|
||||
add_leaf(find_node(m_tree, additional_nodes::spu_threads), qstr(fmt::format(u8"SPU 0x%07x: “%s”, State: %s, Type: %s", spu.lv2_id, *spu.spu_tname.load(), spu.state.load(), spu.get_type())));
|
||||
});
|
||||
|
||||
idm::select<lv2_spu_group>([&](u32 id, lv2_spu_group& tg)
|
||||
|
Loading…
Reference in New Issue
Block a user