Implement PPU LV2 debug

This commit is contained in:
Eladash 2023-05-19 18:41:17 +03:00 committed by Elad Ashkenazi
parent 05824e6acd
commit c21cdb8055
5 changed files with 50 additions and 9 deletions

View File

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

View File

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

View File

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

View File

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

View File

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