From c37bc3c55c16d4f2e2cb1b0d4a8ef58c8edf7d7d Mon Sep 17 00:00:00 2001 From: Eladash Date: Fri, 17 Jul 2020 11:18:04 +0300 Subject: [PATCH] SPU: Make spu_thread::offset private --- Utilities/Thread.cpp | 2 +- rpcs3/Emu/Cell/Modules/cellSpursSpu.cpp | 134 ++++++++++---------- rpcs3/Emu/Cell/Modules/sys_spu_.cpp | 4 +- rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp | 4 +- rpcs3/Emu/Cell/SPURecompiler.cpp | 2 +- rpcs3/Emu/Cell/SPUThread.cpp | 45 +++++-- rpcs3/Emu/Cell/SPUThread.h | 20 ++- rpcs3/Emu/Cell/lv2/sys_spu.cpp | 32 ++--- rpcs3/Emu/Cell/lv2/sys_spu.h | 2 +- rpcs3/rpcs3qt/breakpoint_list.cpp | 4 +- rpcs3/rpcs3qt/debugger_list.cpp | 10 +- rpcs3/rpcs3qt/instruction_editor_dialog.cpp | 9 +- rpcs3/rpcs3qt/instruction_editor_dialog.h | 2 +- rpcs3/rpcs3qt/kernel_explorer.cpp | 13 +- 14 files changed, 151 insertions(+), 132 deletions(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index f6d5158ed7..f21336e0f9 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -1417,7 +1417,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no { const auto& spu = static_cast(*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; diff --git a/rpcs3/Emu/Cell/Modules/cellSpursSpu.cpp b/rpcs3/Emu/Cell/Modules/cellSpursSpu.cpp index 08732ee3f8..5264309cdc 100644 --- a/rpcs3/Emu/Cell/Modules/cellSpursSpu.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSpursSpu.cpp @@ -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(spu.offset + 0x100); + auto ctxt = spu._ptr(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(spu.offset + 0x100); + auto ctxt = spu._ptr(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(spu.offset + 0x100); + const auto ctxt = spu._ptr(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(spu.offset + 0x100); + const auto ctxt = spu._ptr(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(spu.offset + 0x100); + const auto ctxt = spu._ptr(0x100); auto isKernel2 = ctxt->spurs->flags1 & SF1_32_WORKLOADS ? true : false; auto pollStatus = static_cast(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(0x3FFE0); + std::memcpy(wklInfo, wklInfoOffset, 0x20); // Load the workload to LS - auto wklInfo = vm::_ptr(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(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(spu.offset + 0x100); + const auto ctxt = spu._ptr(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(spu.offset + 0x100); + const auto ctxt = spu._ptr(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(spu.offset + spu.gpr[3]._u32[3]); + const auto ctxt = spu._ptr(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(spu.offset + 0x100); + const auto spurs = spu._ptr(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(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(spu.offset + 0x100); + const auto ctxt = spu._ptr(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(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(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(spu.offset + 0x100); - std::memcpy(vm::base(spu.offset + 0x30000), ctxt->spurs->wklInfo1, 0x200); + const auto spurs = spu._ptr(0x100); + std::memcpy(spu._ptr(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(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(spu.offset + 0x30000); + const auto wklInfo1 = spu._ptr(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(spu.offset + 0x30200); + const auto wklInfo2 = spu._ptr(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(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(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(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(spu.offset + 0x80 - offset32(&CellSpurs::traceBuffer)); + //vm::reservation_acquire(spu._ptr(0x80), ctxt->spurs.ptr(&CellSpurs::traceBuffer).addr(), 128); + auto spurs = spu._ptr(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(spu.offset + 0x2C00); + const auto traceBuffer = spu._ptr(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(spu.offset + 0x2D80 - offset32(&CellSpurs::wklState1)); + auto spurs = spu._ptr(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(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(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(spu.offset + 0x2700); - auto kernelCtxt = vm::_ptr(spu.offset + spu.gpr[3]._u32[3]); + auto ctxt = spu._ptr(0x2700); + auto kernelCtxt = spu._ptr(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(spu.offset + 0x2700); + auto ctxt = spu._ptr(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(spu.offset + 0x2700); + auto ctxt = spu._ptr(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(spu.offset + 0x2700); - auto taskset = vm::_ptr(spu.offset + 0x2700); + auto ctxt = spu._ptr(0x2700); + auto taskset = spu._ptr(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(spu.offset + 0x100); - auto ctxt = vm::_ptr(spu.offset + 0x2700); + auto kernelCtxt = spu._ptr(0x100); + auto ctxt = spu._ptr(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(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(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(spu.offset + 0x2700); + auto ctxt = spu._ptr(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(spu.offset + 0x2700); + auto ctxt = spu._ptr(0x2700); - std::memcpy(vm::base(spu.offset + 0x10000), vm::base(addr & -0x80), (addr & 0x7F) << 11); + std::memcpy(spu._ptr(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(spu.offset + 0x2700); - auto taskInfo = vm::_ptr(spu.offset + 0x2780); + auto ctxt = spu._ptr(0x2700); + auto taskInfo = spu._ptr(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(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(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(spu.offset + 0x2700); - auto taskset = vm::_ptr(spu.offset + 0x2700); + const auto ctxt = spu._ptr(0x2700); + const auto taskset = spu._ptr(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(spu.offset + 0x2780); + const auto taskInfo = spu._ptr(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(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(vm::cast(ctxt->taskset.addr()))->task_exit_code[taskId], 0x10); + std::memcpy(spu._ptr(0x2FC0), &vm::_ptr(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(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(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(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(spu.offset + 0x2700); - auto taskset = vm::_ptr(spu.offset + 0x2700); + auto ctxt = spu._ptr(0x2700); + auto taskset = spu._ptr(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(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(spu.offset + 0x2700); - auto kernelCtxt = vm::_ptr(spu.offset + 0x100); + auto ctxt = spu._ptr(0x2700); + auto kernelCtxt = spu._ptr(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(prog.p_vaddr), prog.bin.data(), prog.p_filesz); } } } diff --git a/rpcs3/Emu/Cell/Modules/sys_spu_.cpp b/rpcs3/Emu/Cell/Modules/sys_spu_.cpp index 96a9a1c2e2..d7449d0f91 100644 --- a/rpcs3/Emu/Cell/Modules/sys_spu_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_spu_.cpp @@ -391,7 +391,7 @@ s32 sys_raw_spu_load(s32 id, vm::cptr path, vm::ptr 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(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 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(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); diff --git a/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp b/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp index 6b1fedd050..3e34d762ae 100644 --- a/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp @@ -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); diff --git a/rpcs3/Emu/Cell/SPURecompiler.cpp b/rpcs3/Emu/Cell/SPURecompiler.cpp index 52bddd7e3e..174b746864 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.cpp +++ b/rpcs3/Emu/Cell/SPURecompiler.cpp @@ -5502,7 +5502,7 @@ public: case SPU_RdMachStat: { res.value = m_ir->CreateZExt(m_ir->CreateLoad(spu_ptr(&spu_thread::interrupts_enabled)), get_type()); - res.value = m_ir->CreateOr(res.value, m_ir->CreateShl(m_ir->CreateZExt(m_ir->CreateLoad(spu_ptr(&spu_thread::is_isolated)), get_type()), m_ir->getInt32(1))); + res.value = m_ir->CreateOr(res.value, m_ir->CreateAnd(m_ir->CreateLoad(spu_ptr(&spu_thread::thread_type)), m_ir->getInt32(2))); break; } diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 7b73ce3b09..c733aafb83 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -59,6 +59,22 @@ void fmt_class_string::format(std::string& out, u64 arg) }); } +template <> +void fmt_class_string::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::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; diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index a20a085bc8..e88f2e33e5 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -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; std::array int_ctrl; // SPU Class 0, 1, 2 Interrupt Management @@ -640,9 +646,10 @@ public: atomic_t 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 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 - inline to_be_t* _ptr(u32 lsa) + to_be_t* _ptr(u32 lsa) const { return reinterpret_cast*>(ls + lsa); } // Convert specified SPU LS address to a reference of specified (possibly converted to BE) type template - inline to_be_t& _ref(u32 lsa) + to_be_t& _ref(u32 lsa) const { return *_ptr(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); diff --git a/rpcs3/Emu/Cell/lv2/sys_spu.cpp b/rpcs3/Emu/Cell/lv2/sys_spu.cpp index 84dc6b2927..17ca2764e8 100644 --- a/rpcs3/Emu/Cell/lv2/sys_spu.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_spu.cpp @@ -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(&seg.size), sizeof(seg.size)); sha1_update(&sha, reinterpret_cast(&seg.ls), sizeof(seg.ls)); sha1_update(&sha, vm::_ptr(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(loc + seg.ls), seg.size / 4, seg.addr); + std::fill_n(reinterpret_cast*>(loc + seg.ls), seg.size / 4, seg.addr); sha1_update(&sha, reinterpret_cast(&seg.size), sizeof(seg.size)); sha1_update(&sha, reinterpret_cast(&seg.ls), sizeof(seg.ls)); sha1_update(&sha, reinterpret_cast(&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()->apply(hash, vm::_ptr(loc)); + auto applied = g_fxo->get()->apply(hash, loc); if (!Emu.GetTitleID().empty()) { // Alternative patch - applied += g_fxo->get()->apply(Emu.GetTitleID() + '-' + hash, vm::_ptr(loc)); + applied += g_fxo->get()->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 id, vm::ptr(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(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>(idm_id, [](named_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>(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>(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>(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 value, ato const auto thread = idm::get>(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 value) { const auto thread = idm::get>(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>(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 value) { const auto thread = idm::get>(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; } diff --git a/rpcs3/Emu/Cell/lv2/sys_spu.h b/rpcs3/Emu/Cell/lv2/sys_spu.h index 1d0e604bcf..389608df25 100644 --- a/rpcs3/Emu/Cell/lv2/sys_spu.h +++ b/rpcs3/Emu/Cell/lv2/sys_spu.h @@ -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 diff --git a/rpcs3/rpcs3qt/breakpoint_list.cpp b/rpcs3/rpcs3qt/breakpoint_list.cpp index ca4136b6b0..34ff2eceb6 100644 --- a/rpcs3/rpcs3qt/breakpoint_list.cpp +++ b/rpcs3/rpcs3qt/breakpoint_list.cpp @@ -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(*cpu).offset : 0; - m_disasm->offset = vm::_ptr(cpu_offset); + const auto cpu_offset = cpu->id_type() != 1 ? static_cast(*cpu).ls : vm::g_sudo_addr; + m_disasm->offset = cpu_offset; m_disasm->disasm(m_disasm->dump_pc = pc); diff --git a/rpcs3/rpcs3qt/debugger_list.cpp b/rpcs3/rpcs3qt/debugger_list.cpp index 75d5d63a28..16f89e8c2c 100644 --- a/rpcs3/rpcs3qt/debugger_list.cpp +++ b/rpcs3/rpcs3qt/debugger_list.cpp @@ -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(*cpu).offset : 0; + const auto cpu_offset = cpu->id_type() != 1 ? static_cast(*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; isetBackground(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>(cpu_offset + pc); + const u32 data = *vm::get_super_ptr>(pc); item(i)->setText((IsBreakpoint(pc) ? ">> " : " ") + qstr(fmt::format("[%08x] %02x %02x %02x %02x:", pc, static_cast(data >> 24), static_cast(data >> 16), diff --git a/rpcs3/rpcs3qt/instruction_editor_dialog.cpp b/rpcs3/rpcs3qt/instruction_editor_dialog.cpp index 7c97de997d..d056011356 100644 --- a/rpcs3/rpcs3qt/instruction_editor_dialog.cpp +++ b/rpcs3/rpcs3qt/instruction_editor_dialog.cpp @@ -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(*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(*cpu).ls : vm::g_sudo_addr; + QString instruction = qstr(fmt::format("%08x", *reinterpret_cast*>(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(opcode))) + if (!ppu_patch(m_pc, static_cast(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(opcode)); + const be_t swapped{static_cast(opcode)}; + std::memcpy(m_cpu_offset + m_pc, &swapped, 4); } accept(); diff --git a/rpcs3/rpcs3qt/instruction_editor_dialog.h b/rpcs3/rpcs3qt/instruction_editor_dialog.h index 968677e8d2..90f8ff557b 100644 --- a/rpcs3/rpcs3qt/instruction_editor_dialog.h +++ b/rpcs3/rpcs3qt/instruction_editor_dialog.h @@ -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; diff --git a/rpcs3/rpcs3qt/kernel_explorer.cpp b/rpcs3/rpcs3qt/kernel_explorer.cpp index 4c9c88ed55..f7769de0ab 100644 --- a/rpcs3/rpcs3qt/kernel_explorer.cpp +++ b/rpcs3/rpcs3qt/kernel_explorer.cpp @@ -471,18 +471,7 @@ void kernel_explorer::Update() idm::select>([&](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([&](u32 id, lv2_spu_group& tg)