mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-19 19:15:26 +00:00
PPU Debugger/Memory: STDCX/STWCX breakpoints, make vm::_ref const
This commit is contained in:
parent
564c903fbd
commit
b34a08fc99
14 changed files with 61 additions and 91 deletions
|
@ -446,7 +446,7 @@ error_code _cellGcmInitBody(ppu_thread& ppu, vm::pptr<CellGcmContextData> contex
|
|||
gcm_cfg.zculls_addr = vm::alloc(sizeof(CellGcmZcullInfo) * 8, vm::main);
|
||||
gcm_cfg.tiles_addr = vm::alloc(sizeof(CellGcmTileInfo) * 15, vm::main);
|
||||
|
||||
vm::_ref<CellGcmContextData>(gcm_cfg.gcm_info.context_addr) = gcm_cfg.current_context;
|
||||
vm::write<CellGcmContextData>(gcm_cfg.gcm_info.context_addr, gcm_cfg.current_context);
|
||||
context->set(gcm_cfg.gcm_info.context_addr);
|
||||
|
||||
// 0x40 is to offset CellGcmControl from RsxDmaControl
|
||||
|
@ -590,7 +590,7 @@ ret_type gcmSetPrepareFlip(ppu_thread& ppu, vm::ptr<CellGcmContextData> ctxt, u3
|
|||
|
||||
if (!old_api && ctxt.addr() == gcm_cfg.gcm_info.context_addr)
|
||||
{
|
||||
vm::_ref<CellGcmControl>(gcm_cfg.gcm_info.control_addr).put += cmd_size;
|
||||
vm::_ptr<CellGcmControl>(gcm_cfg.gcm_info.control_addr)->put += cmd_size;
|
||||
}
|
||||
|
||||
return static_cast<ret_type>(not_an_error(id));
|
||||
|
@ -1463,7 +1463,7 @@ s32 cellGcmCallback(ppu_thread& ppu, vm::ptr<CellGcmContextData> context, u32 co
|
|||
|
||||
auto& gcm_cfg = g_fxo->get<gcm_config>();
|
||||
|
||||
auto& ctrl = vm::_ref<CellGcmControl>(gcm_cfg.gcm_info.control_addr);
|
||||
auto& ctrl = *vm::_ptr<CellGcmControl>(gcm_cfg.gcm_info.control_addr);
|
||||
|
||||
// Flush command buffer (ie allow RSX to read up to context->current)
|
||||
ctrl.put.exchange(getOffsetFromAddress(context->current.addr()));
|
||||
|
|
|
@ -4134,7 +4134,7 @@ s32 _spurs::create_task(vm::ptr<CellSpursTaskset> taskset, vm::ptr<u32> task_id,
|
|||
|
||||
u32 tmp_task_id;
|
||||
|
||||
vm::light_op(vm::_ref<atomic_be_t<v128>>(taskset.ptr(&CellSpursTaskset::enabled).addr()), [&](atomic_be_t<v128>& ptr)
|
||||
vm::light_op(*vm::_ptr<atomic_be_t<v128>>(taskset.ptr(&CellSpursTaskset::enabled).addr()), [&](atomic_be_t<v128>& ptr)
|
||||
{
|
||||
// NOTE: Realfw processes this using 4 32-bits atomic loops
|
||||
// But here its processed within a single 128-bit atomic op
|
||||
|
|
|
@ -1594,12 +1594,12 @@ s32 spursTasksetProcessRequest(spu_thread& spu, s32 request, u32* taskId, u32* i
|
|||
spursHalt(spu);
|
||||
}
|
||||
|
||||
vm::_ref<v128>(ctxt->taskset.addr() + ::offset32(&CellSpursTaskset::waiting)) = waiting;
|
||||
vm::_ref<v128>(ctxt->taskset.addr() + ::offset32(&CellSpursTaskset::running)) = running;
|
||||
vm::_ref<v128>(ctxt->taskset.addr() + ::offset32(&CellSpursTaskset::ready)) = ready;
|
||||
vm::_ref<v128>(ctxt->taskset.addr() + ::offset32(&CellSpursTaskset::pending_ready)) = v128{};
|
||||
vm::_ref<v128>(ctxt->taskset.addr() + ::offset32(&CellSpursTaskset::enabled)) = enabled;
|
||||
vm::_ref<v128>(ctxt->taskset.addr() + ::offset32(&CellSpursTaskset::signalled)) = signalled;
|
||||
// vm::_ref<v128>(ctxt->taskset.addr() + ::offset32(&CellSpursTaskset::waiting)) = waiting;
|
||||
// vm::_ref<v128>(ctxt->taskset.addr() + ::offset32(&CellSpursTaskset::running)) = running;
|
||||
// vm::_ref<v128>(ctxt->taskset.addr() + ::offset32(&CellSpursTaskset::ready)) = ready;
|
||||
// vm::_ref<v128>(ctxt->taskset.addr() + ::offset32(&CellSpursTaskset::pending_ready)) = v128{};
|
||||
// vm::_ref<v128>(ctxt->taskset.addr() + ::offset32(&CellSpursTaskset::enabled)) = enabled;
|
||||
// vm::_ref<v128>(ctxt->taskset.addr() + ::offset32(&CellSpursTaskset::signalled)) = signalled;
|
||||
|
||||
std::memcpy(spu._ptr<void>(0x2700), spu._ptr<void>(0x100), 128); // Copy data
|
||||
}//);
|
||||
|
|
|
@ -3367,7 +3367,10 @@ static bool ppu_store_reservation(ppu_thread& ppu, u32 addr, u64 reg_value)
|
|||
fmt::throw_exception("PPU %s: Unaligned address: 0x%08x", sizeof(T) == 4 ? "STWCX" : "STDCX", addr);
|
||||
}
|
||||
|
||||
auto& data = vm::_ref<atomic_be_t<u64>>(addr & -8);
|
||||
// Notify breakpoint handler
|
||||
vm::write<void>(addr, T{0}, &ppu);
|
||||
|
||||
auto& data = const_cast<atomic_be_t<u64>&>(vm::_ref<atomic_be_t<u64>>(addr & -8));
|
||||
auto& res = vm::reservation_acquire(addr);
|
||||
const u64 rtime = ppu.rtime;
|
||||
|
||||
|
|
|
@ -3833,14 +3833,14 @@ bool spu_thread::do_putllc(const spu_mfc_cmd& args)
|
|||
{
|
||||
if (addr - spurs_addr <= 0x80)
|
||||
{
|
||||
mov_rdata(vm::_ref<spu_rdata_t>(addr), to_write);
|
||||
mov_rdata(*vm::_ptr<spu_rdata_t>(addr), to_write);
|
||||
res += 64;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (!g_use_rtm)
|
||||
{
|
||||
vm::_ref<atomic_t<u32>>(addr) += 0;
|
||||
*vm::_ptr<atomic_t<u32>>(addr) += 0;
|
||||
}
|
||||
|
||||
if (g_use_rtm) [[likely]]
|
||||
|
|
|
@ -181,7 +181,7 @@ error_code sys_rsx_memory_allocate(cpu_thread& cpu, vm::ptr<u32> mem_handle, vm:
|
|||
|
||||
if (u32 addr = rsx::get_current_renderer()->driver_info)
|
||||
{
|
||||
vm::_ref<RsxDriverInfo>(addr).memory_size = size;
|
||||
vm::_ptr<RsxDriverInfo>(addr)->memory_size = size;
|
||||
}
|
||||
|
||||
*mem_addr = rsx::constants::local_mem_base;
|
||||
|
@ -265,7 +265,7 @@ error_code sys_rsx_context_allocate(cpu_thread& cpu, vm::ptr<u32> context_id, vm
|
|||
*lpar_driver_info = dma_address + 0x100000;
|
||||
*lpar_reports = dma_address + 0x200000;
|
||||
|
||||
auto &reports = vm::_ref<RsxReports>(vm::cast(*lpar_reports));
|
||||
auto &reports = *vm::_ptr<RsxReports>(vm::cast(*lpar_reports));
|
||||
std::memset(&reports, 0, sizeof(RsxReports));
|
||||
|
||||
for (usz i = 0; i < std::size(reports.notify); ++i)
|
||||
|
@ -273,10 +273,10 @@ error_code sys_rsx_context_allocate(cpu_thread& cpu, vm::ptr<u32> context_id, vm
|
|||
|
||||
for (usz i = 0; i < std::size(reports.semaphore); i += 4)
|
||||
{
|
||||
reports.semaphore[i + 0].val.raw() = 0x1337C0D3;
|
||||
reports.semaphore[i + 1].val.raw() = 0x1337BABE;
|
||||
reports.semaphore[i + 2].val.raw() = 0x1337BEEF;
|
||||
reports.semaphore[i + 3].val.raw() = 0x1337F001;
|
||||
reports.semaphore[i + 0] = 0x1337C0D3;
|
||||
reports.semaphore[i + 1] = 0x1337BABE;
|
||||
reports.semaphore[i + 2] = 0x1337BEEF;
|
||||
reports.semaphore[i + 3] = 0x1337F001;
|
||||
}
|
||||
|
||||
for (usz i = 0; i < std::size(reports.report); ++i)
|
||||
|
@ -286,7 +286,7 @@ error_code sys_rsx_context_allocate(cpu_thread& cpu, vm::ptr<u32> context_id, vm
|
|||
reports.report[i].pad = -1;
|
||||
}
|
||||
|
||||
auto &driverInfo = vm::_ref<RsxDriverInfo>(vm::cast(*lpar_driver_info));
|
||||
auto &driverInfo = *vm::_ptr<RsxDriverInfo>(vm::cast(*lpar_driver_info));
|
||||
|
||||
std::memset(&driverInfo, 0, sizeof(RsxDriverInfo));
|
||||
|
||||
|
@ -303,7 +303,7 @@ error_code sys_rsx_context_allocate(cpu_thread& cpu, vm::ptr<u32> context_id, vm
|
|||
|
||||
render->driver_info = vm::cast(*lpar_driver_info);
|
||||
|
||||
auto &dmaControl = vm::_ref<RsxDmaControl>(vm::cast(*lpar_dma_control));
|
||||
auto &dmaControl = *vm::_ptr<RsxDmaControl>(vm::cast(*lpar_dma_control));
|
||||
dmaControl.get = 0;
|
||||
dmaControl.put = 0;
|
||||
dmaControl.ref = 0; // Set later to -1 by cellGcmSys
|
||||
|
@ -527,7 +527,7 @@ error_code sys_rsx_context_attribute(u32 context_id, u32 package_id, u64 a3, u64
|
|||
return { CELL_EINVAL, "context_id is 0x%x", context_id };
|
||||
}
|
||||
|
||||
auto &driverInfo = vm::_ref<RsxDriverInfo>(render->driver_info);
|
||||
auto &driverInfo = *vm::_ptr<RsxDriverInfo>(render->driver_info);
|
||||
switch (package_id)
|
||||
{
|
||||
case 0x001: // FIFO
|
||||
|
@ -862,7 +862,7 @@ error_code sys_rsx_context_attribute(u32 context_id, u32 package_id, u64 a3, u64
|
|||
|
||||
// seems gcmSysWaitLabel uses this offset, so lets set it to 0 every flip
|
||||
// NOTE: Realhw resets 16 bytes of this semaphore for some reason
|
||||
vm::_ref<atomic_t<u128>>(render->label_addr + 0x10).store(u128{});
|
||||
vm::_ptr<atomic_t<u128>>(render->label_addr + 0x10)->store(u128{});
|
||||
|
||||
render->send_event(0, SYS_RSX_EVENT_FLIP_BASE << 1, 0);
|
||||
break;
|
||||
|
|
|
@ -87,10 +87,7 @@ struct RsxDmaControl
|
|||
be_t<u32> unk1;
|
||||
};
|
||||
|
||||
struct RsxSemaphore
|
||||
{
|
||||
atomic_be_t<u32> val;
|
||||
};
|
||||
using RsxSemaphore = be_t<u32>;
|
||||
|
||||
struct alignas(16) RsxNotify
|
||||
{
|
||||
|
|
|
@ -553,7 +553,7 @@ error_code sys_ss_individual_info_manager(u64 pkg_id, u64 a2, vm::ptr<u64> out_s
|
|||
case 0x17002:
|
||||
{
|
||||
// TODO
|
||||
vm::_ref<u64>(a5) = a4; // Write back size of buffer
|
||||
vm::write<u64>(a5, a4); // Write back size of buffer
|
||||
break;
|
||||
}
|
||||
// Get EID size
|
||||
|
|
|
@ -8,14 +8,14 @@
|
|||
|
||||
#include "util/to_endian.hpp"
|
||||
|
||||
class ppu_thread;
|
||||
|
||||
#ifdef RPCS3_HAS_MEMORY_BREAKPOINTS
|
||||
#include "rpcs3qt/breakpoint_handler.h"
|
||||
#include "util/logs.hpp"
|
||||
|
||||
LOG_CHANNEL(debugbp_log, "DebugBP");
|
||||
|
||||
class ppu_thread;
|
||||
|
||||
void ppubreak(ppu_thread& ppu);
|
||||
#endif
|
||||
|
||||
|
@ -282,9 +282,10 @@ namespace vm
|
|||
}
|
||||
|
||||
// Convert specified PS3 address to a reference of specified (possibly converted to BE) type
|
||||
template <typename T, typename U> inline to_be_t<T>& _ref(const U& addr)
|
||||
// Const lvalue: prevent abused writes
|
||||
template <typename T, typename U> inline const to_be_t<T>& _ref(const U& addr)
|
||||
{
|
||||
return *static_cast<to_be_t<T>*>(base(addr));
|
||||
return *static_cast<const to_be_t<T>*>(base(addr));
|
||||
}
|
||||
|
||||
// Access memory bypassing memory protection
|
||||
|
@ -300,42 +301,43 @@ namespace vm
|
|||
}
|
||||
|
||||
#ifdef RPCS3_HAS_MEMORY_BREAKPOINTS
|
||||
inline void write16(u32 addr, be_t<u16> value, ppu_thread* ppu = nullptr)
|
||||
template <typename T, typename U = T>
|
||||
inline void write(u32 addr, U value, ppu_thread* ppu = nullptr)
|
||||
#else
|
||||
inline void write16(u32 addr, be_t<u16> value)
|
||||
template <typename T, typename U = T>
|
||||
inline void write(u32 addr, U value, ppu_thread* = nullptr)
|
||||
#endif
|
||||
{
|
||||
_ref<u16>(addr) = value;
|
||||
using dest_t = std::conditional_t<std::is_void_v<T>, U, T>;
|
||||
|
||||
if constexpr (!std::is_void_v<T>)
|
||||
{
|
||||
*_ptr<dest_t>(addr) = value;
|
||||
}
|
||||
|
||||
#ifdef RPCS3_HAS_MEMORY_BREAKPOINTS
|
||||
if (ppu && g_breakpoint_handler.HasBreakpoint(addr, breakpoint_types::bp_write))
|
||||
{
|
||||
debugbp_log.success("BPMW: breakpoint writing(16) 0x%x at 0x%x", value, addr);
|
||||
debugbp_log.success("BPMW: breakpoint writing(%d) 0x%x at 0x%x",
|
||||
sizeof(dest_t) * CHAR_BIT, value, addr);
|
||||
ppubreak(*ppu);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void write16(u32 addr, be_t<u16> value, ppu_thread* ppu = nullptr)
|
||||
{
|
||||
write<be_t<u16>>(addr, value, ppu);
|
||||
}
|
||||
|
||||
inline const be_t<u32>& read32(u32 addr)
|
||||
{
|
||||
return _ref<u32>(addr);
|
||||
}
|
||||
|
||||
#ifdef RPCS3_HAS_MEMORY_BREAKPOINTS
|
||||
inline void write32(u32 addr, be_t<u32> value, ppu_thread* ppu = nullptr)
|
||||
#else
|
||||
inline void write32(u32 addr, be_t<u32> value)
|
||||
#endif
|
||||
{
|
||||
_ref<u32>(addr) = value;
|
||||
|
||||
#ifdef RPCS3_HAS_MEMORY_BREAKPOINTS
|
||||
if (ppu && g_breakpoint_handler.HasBreakpoint(addr, breakpoint_types::bp_write))
|
||||
{
|
||||
debugbp_log.success("BPMW: breakpoint writing(32) 0x%x at 0x%x", value, addr);
|
||||
ppubreak(*ppu);
|
||||
}
|
||||
#endif
|
||||
write<be_t<u32>>(addr, value, ppu);
|
||||
}
|
||||
|
||||
inline const be_t<u64>& read64(u32 addr)
|
||||
|
@ -343,41 +345,9 @@ namespace vm
|
|||
return _ref<u64>(addr);
|
||||
}
|
||||
|
||||
#ifdef RPCS3_HAS_MEMORY_BREAKPOINTS
|
||||
inline void write64(u32 addr, be_t<u64> value, ppu_thread* ppu = nullptr)
|
||||
#else
|
||||
inline void write64(u32 addr, be_t<u64> value)
|
||||
#endif
|
||||
{
|
||||
_ref<u64>(addr) = value;
|
||||
|
||||
#ifdef RPCS3_HAS_MEMORY_BREAKPOINTS
|
||||
if (ppu && g_breakpoint_handler.HasBreakpoint(addr, breakpoint_types::bp_write))
|
||||
{
|
||||
debugbp_log.success("BPMW: breakpoint writing(64) 0x%x at 0x%x", value, addr);
|
||||
ppubreak(*ppu);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef RPCS3_HAS_MEMORY_BREAKPOINTS
|
||||
template <typename T, typename U = T>
|
||||
inline void write(u32 addr, U value, ppu_thread* ppu = nullptr)
|
||||
#else
|
||||
template <typename T, typename U = T>
|
||||
inline void write(u32 addr, U value)
|
||||
#endif
|
||||
{
|
||||
_ref<T>(addr) = static_cast<T>(value);
|
||||
|
||||
#ifdef RPCS3_HAS_MEMORY_BREAKPOINTS
|
||||
if (ppu && g_breakpoint_handler.HasBreakpoint(addr, breakpoint_types::bp_write))
|
||||
{
|
||||
debugbp_log.success("BPMW: breakpoint writing(%d) 0x%x at 0x%x",
|
||||
sizeof(T) * CHAR_BIT, value, addr);
|
||||
ppubreak(*ppu);
|
||||
}
|
||||
#endif
|
||||
write<be_t<u64>>(addr, value, ppu);
|
||||
}
|
||||
|
||||
void init();
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace rsx
|
|||
RSX(ctx)->sync();
|
||||
|
||||
// Write ref+get (get will be written again with the same value at command end)
|
||||
auto& dma = vm::_ref<RsxDmaControl>(RSX(ctx)->dma_address);
|
||||
auto& dma = *vm::_ptr<RsxDmaControl>(RSX(ctx)->dma_address);
|
||||
dma.get.release(RSX(ctx)->fifo_ctrl->get_pos());
|
||||
dma.ref.store(arg);
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ namespace rsx
|
|||
// Syncronization point, may be associated with memory changes without actually changing addresses
|
||||
RSX(ctx)->m_graphics_state |= rsx::pipeline_state::fragment_program_needs_rehash;
|
||||
|
||||
const auto& sema = vm::_ref<RsxSemaphore>(addr).val;
|
||||
const auto& sema = vm::_ref<RsxSemaphore>(addr);
|
||||
|
||||
if (sema == arg)
|
||||
{
|
||||
|
|
|
@ -566,7 +566,7 @@ namespace rsx
|
|||
default:
|
||||
rsx_log.error("NV4097_GET_REPORT: Bad type %d", type);
|
||||
|
||||
vm::_ref<atomic_t<CellGcmReportData>>(address_ptr).atomic_op([&](CellGcmReportData& data)
|
||||
vm::_ptr<atomic_t<CellGcmReportData>>(address_ptr)->atomic_op([&](CellGcmReportData& data)
|
||||
{
|
||||
data.timer = RSX(ctx)->timestamp();
|
||||
data.padding = 0;
|
||||
|
@ -651,7 +651,7 @@ namespace rsx
|
|||
|
||||
ensure(addr != umax);
|
||||
|
||||
vm::_ref<atomic_t<RsxNotify>>(addr).store(
|
||||
vm::_ptr<atomic_t<RsxNotify>>(addr)->store(
|
||||
{
|
||||
RSX(ctx)->timestamp(),
|
||||
0
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace rsx
|
|||
// First, queue the GPU work. If it flushes the queue for us, the following routines will be faster.
|
||||
const bool handled = RSX(ctx)->get_backend_config().supports_host_gpu_labels && RSX(ctx)->release_GCM_label(address, data);
|
||||
|
||||
if (vm::_ref<RsxSemaphore>(address).val == data)
|
||||
if (vm::_ref<RsxSemaphore>(address) == data)
|
||||
{
|
||||
// It's a no-op to write the same value (although there is a delay in real-hw so it's more accurate to allow GPU label in this case)
|
||||
return;
|
||||
|
@ -57,7 +57,7 @@ namespace rsx
|
|||
}
|
||||
}
|
||||
|
||||
vm::_ref<RsxSemaphore>(address).val = data;
|
||||
vm::write<atomic_t<RsxSemaphore>>(address, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1212,7 +1212,7 @@ namespace rsx
|
|||
if (const u64 get_put = new_get_put.exchange(u64{umax});
|
||||
get_put != umax)
|
||||
{
|
||||
vm::_ref<atomic_be_t<u64>>(dma_address + ::offset32(&RsxDmaControl::put)).release(get_put);
|
||||
vm::_ptr<atomic_be_t<u64>>(dma_address + ::offset32(&RsxDmaControl::put))->release(get_put);
|
||||
fifo_ctrl->set_get(static_cast<u32>(get_put));
|
||||
fifo_ctrl->abort();
|
||||
fifo_ret_addr = RSX_CALL_STACK_EMPTY;
|
||||
|
@ -2457,7 +2457,7 @@ namespace rsx
|
|||
}
|
||||
|
||||
rsx::reservation_lock<true> lock(sink, 16);
|
||||
vm::_ref<atomic_t<CellGcmReportData>>(sink).store({timestamp(), value, 0});
|
||||
vm::_ptr<atomic_t<CellGcmReportData>>(sink)->store({timestamp(), value, 0});
|
||||
}
|
||||
|
||||
u32 thread::copy_zcull_stats(u32 memory_range_start, u32 memory_range, u32 destination)
|
||||
|
|
|
@ -62,7 +62,7 @@ namespace rsx
|
|||
RSX(ctx)->reset();
|
||||
RSX(ctx)->on_frame_end(arg);
|
||||
RSX(ctx)->request_emu_flip(arg);
|
||||
vm::_ref<atomic_t<u128>>(RSX(ctx)->label_addr + 0x10).store(u128{});
|
||||
vm::_ptr<atomic_t<u128>>(RSX(ctx)->label_addr + 0x10)->store(u128{});
|
||||
}
|
||||
|
||||
void user_command(context* ctx, u32, u32 arg)
|
||||
|
|
Loading…
Add table
Reference in a new issue