mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-17 08:11:51 +00:00
Implement PPU LV2 debug
This commit is contained in:
parent
05824e6acd
commit
c21cdb8055
@ -14,6 +14,11 @@
|
||||
std::memcpy(ppu.syscall_args, ppu.gpr + 3, sizeof(ppu.syscall_args)); \
|
||||
ppu_func_detail::do_call(ppu, func);\
|
||||
static_cast<void>(ppu.test_stopped());\
|
||||
auto& history = ppu.syscall_history.data[ppu.syscall_history.index++ % ppu.syscall_history.data.size()];\
|
||||
history.cia = ppu.cia;\
|
||||
history.func_name = ppu.current_function;\
|
||||
history.error = ppu.gpr[3];\
|
||||
if (ppu.syscall_history.count_debug_arguments) std::copy_n(ppu.syscall_args, std::size(history.args), history.args.data());\
|
||||
ppu.current_function = old_f;\
|
||||
ppu.cia += 4;\
|
||||
__VA_ARGS__;\
|
||||
|
@ -1593,7 +1593,7 @@ void ppu_thread::dump_all(std::string& ret) const
|
||||
{
|
||||
cpu_thread::dump_all(ret);
|
||||
|
||||
if (!call_history.data.empty())
|
||||
if (call_history.data.size() > 1)
|
||||
{
|
||||
ret +=
|
||||
"\nCalling History:"
|
||||
@ -1887,10 +1887,9 @@ ppu_thread::ppu_thread(const ppu_thread_params& param, std::string_view name, u3
|
||||
state += cpu_flag::memory;
|
||||
}
|
||||
|
||||
if (g_cfg.core.ppu_call_history)
|
||||
{
|
||||
call_history.data.resize(call_history_max_size);
|
||||
}
|
||||
call_history.data.resize(g_cfg.core.ppu_call_history ? call_history_max_size : 1);
|
||||
syscall_history.data.resize(g_cfg.core.ppu_call_history ? syscall_history_max_size : 1);
|
||||
syscall_history.count_debug_arguments = static_cast<u32>(g_cfg.core.ppu_call_history ? std::size(syscall_history.data[0].args) : 0);
|
||||
|
||||
#ifdef __APPLE__
|
||||
pthread_jit_write_protect_np(true);
|
||||
@ -1967,6 +1966,10 @@ ppu_thread::ppu_thread(utils::serial& ar)
|
||||
atomic_t<bool> inited = false;
|
||||
};
|
||||
|
||||
call_history.data.resize(g_cfg.core.ppu_call_history ? call_history_max_size : 1);
|
||||
syscall_history.data.resize(g_cfg.core.ppu_call_history ? syscall_history_max_size : 1);
|
||||
syscall_history.count_debug_arguments = static_cast<u32>(g_cfg.core.ppu_call_history ? std::size(syscall_history.data[0].args) : 0);
|
||||
|
||||
serialize_common(ar);
|
||||
|
||||
// Restore jm_mask
|
||||
|
@ -311,6 +311,23 @@ public:
|
||||
|
||||
static constexpr u32 call_history_max_size = 4096;
|
||||
|
||||
struct syscall_history_t
|
||||
{
|
||||
struct entry_t
|
||||
{
|
||||
u64 cia;
|
||||
const char* func_name;
|
||||
u64 error;
|
||||
std::array<u64, 4> args;
|
||||
};
|
||||
|
||||
std::vector<entry_t> data;
|
||||
u64 index = 0;
|
||||
u32 count_debug_arguments;
|
||||
} syscall_history;
|
||||
|
||||
static constexpr u32 syscall_history_max_size = 2048;
|
||||
|
||||
struct hle_func_call_with_toc_info_t
|
||||
{
|
||||
u32 cia;
|
||||
|
@ -782,7 +782,7 @@ public:
|
||||
|
||||
std::vector<mfc_cmd_dump> mfc_history;
|
||||
u64 mfc_dump_idx = 0;
|
||||
static constexpr u32 max_mfc_dump_idx = 2048;
|
||||
static constexpr u32 max_mfc_dump_idx = 4096;
|
||||
|
||||
bool in_cpu_work = false;
|
||||
bool allow_interrupts_in_cpu_work = false;
|
||||
|
@ -462,6 +462,8 @@ void debugger_frame::keyPressEvent(QKeyEvent* event)
|
||||
|
||||
auto copy_overlapping_list = [&] <typename T> (u64& index, u64 max, const std::vector<T>& in, std::vector<T>& out, bool& emptied)
|
||||
{
|
||||
max = std::min<u64>(max, in.size());
|
||||
|
||||
const u64 current_pos = index % in.size();
|
||||
const u64 last_elements = std::min<u64>(current_pos, max);
|
||||
const u64 overlapped_old_elements = std::min<u64>(index, max) - last_elements;
|
||||
@ -543,13 +545,16 @@ void debugger_frame::keyPressEvent(QKeyEvent* event)
|
||||
|
||||
// Preallocate in order to save execution time when inside suspend_all.
|
||||
std::vector<u32> copy(max);
|
||||
std::vector<typename ppu_thread::syscall_history_t::entry_t> sys_copy(ppu_thread::syscall_history_max_size);
|
||||
|
||||
bool emptied = false;
|
||||
std::array<bool, 2> emptied{};
|
||||
|
||||
cpu_thread::suspend_all(nullptr, {}, [&]
|
||||
{
|
||||
auto& list = static_cast<ppu_thread*>(cpu)->call_history;
|
||||
copy_overlapping_list(list.index, max, list.data, copy, emptied);
|
||||
auto& sys_list = static_cast<ppu_thread*>(cpu)->syscall_history;
|
||||
copy_overlapping_list(list.index, max, list.data, copy, emptied[0]);
|
||||
copy_overlapping_list(sys_list.index, max, sys_list.data, sys_copy, emptied[1]);
|
||||
});
|
||||
|
||||
std::string ret;
|
||||
@ -563,16 +568,27 @@ void debugger_frame::keyPressEvent(QKeyEvent* event)
|
||||
fmt::append(ret, "\n(%u) 0x%08x: %s", i, *it, dis_asm.last_opcode);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for (auto it = sys_copy.rbegin(); it != sys_copy.rend(); it++, i++)
|
||||
{
|
||||
fmt::append(ret, "\n(%u) 0x%08x: %s, 0x%x, r3=0x%x, r4=0x%x, r5=0x%x, r6=0x%x", i, it->cia, it->func_name, it->error, it->args[0], it->args[1], it->args[2], it->args[3]);
|
||||
}
|
||||
|
||||
if (ret.empty())
|
||||
{
|
||||
ret = "No PPU calls have been logged";
|
||||
}
|
||||
|
||||
if (emptied)
|
||||
if (emptied[0])
|
||||
{
|
||||
ret += "\nPrevious call history has been emptied!";
|
||||
}
|
||||
|
||||
if (emptied[1])
|
||||
{
|
||||
ret += "\nPrevious HLE call history has been emptied!";
|
||||
}
|
||||
|
||||
ppu_log.success("PPU calling history dump of '%s': %s", cpu->get_name(), ret);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user