1
0
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:
Eladash 2020-07-17 11:18:04 +03:00 committed by Ivan
parent 6cc0fe4221
commit c37bc3c55c
14 changed files with 151 additions and 132 deletions

View File

@ -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;

View File

@ -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);
}
}
}

View File

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

View File

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

View File

@ -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;
}

View File

@ -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;

View File

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

View File

@ -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;
}

View File

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

View File

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

View File

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

View File

@ -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();

View File

@ -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;

View File

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