mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-27 09:41:05 +00:00
Add PPU instruction stat dumper
Needs PPU Debug option to activate and PPU Interpreter Dumps after Resume (after Pause) Fix utils::memory_decommit, clean vm.cpp
This commit is contained in:
parent
f5d450f24c
commit
df2fc13b7a
@ -70,7 +70,7 @@ namespace utils
|
||||
void memory_decommit(void* pointer, std::size_t size)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
verify(HERE), ::VirtualFree(pointer, 0, MEM_DECOMMIT);
|
||||
verify(HERE), ::VirtualFree(pointer, size, MEM_DECOMMIT);
|
||||
#else
|
||||
verify(HERE), ::mmap(pointer, size, PROT_NONE, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
#endif
|
||||
|
@ -14,6 +14,11 @@ inline void ppu_cr_set(ppu_thread& ppu, u32 field, bool le, bool gt, bool eq, bo
|
||||
ppu.cr[field * 4 + 1] = gt;
|
||||
ppu.cr[field * 4 + 2] = eq;
|
||||
ppu.cr[field * 4 + 3] = so;
|
||||
|
||||
if (UNLIKELY(g_cfg.core.ppu_debug))
|
||||
{
|
||||
*(u32*)(vm::g_stat_addr + ppu.cia) |= *(u32*)(u8*)(ppu.cr + field * 4);
|
||||
}
|
||||
}
|
||||
|
||||
// Write comparison results to CR field
|
||||
|
@ -8,21 +8,6 @@
|
||||
#include "Emu/Cell/lv2/sys_memory.h"
|
||||
#include "Emu/RSX/GSRender.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* OS X uses MAP_ANON instead of MAP_ANONYMOUS */
|
||||
#ifndef MAP_ANONYMOUS
|
||||
#define MAP_ANONYMOUS MAP_ANON
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <atomic>
|
||||
#include <deque>
|
||||
|
||||
@ -48,6 +33,9 @@ namespace vm
|
||||
// Auxiliary virtual memory for executable areas
|
||||
u8* const g_exec_addr = memory_reserve_4GiB((std::uintptr_t)g_base_addr);
|
||||
|
||||
// Stats for debugging
|
||||
u8* const g_stat_addr = memory_reserve_4GiB((std::uintptr_t)g_exec_addr);
|
||||
|
||||
// Memory locations
|
||||
std::vector<std::shared_ptr<block_t>> g_locations;
|
||||
|
||||
@ -349,16 +337,17 @@ namespace vm
|
||||
}
|
||||
}
|
||||
|
||||
void* real_addr = g_base_addr + addr;
|
||||
void* exec_addr = g_exec_addr + addr;
|
||||
utils::memory_commit(g_base_addr + addr, size);
|
||||
|
||||
#ifdef _WIN32
|
||||
auto protection = flags & page_writable ? PAGE_READWRITE : (flags & page_readable ? PAGE_READONLY : PAGE_NOACCESS);
|
||||
verify(__func__), ::VirtualAlloc(real_addr, size, MEM_COMMIT, protection);
|
||||
#else
|
||||
auto protection = flags & page_writable ? PROT_WRITE | PROT_READ : (flags & page_readable ? PROT_READ : PROT_NONE);
|
||||
verify(__func__), !::mprotect(real_addr, size, protection), !::madvise(real_addr, size, MADV_WILLNEED);
|
||||
#endif
|
||||
if (flags & page_executable)
|
||||
{
|
||||
utils::memory_commit(g_exec_addr + addr, size);
|
||||
}
|
||||
|
||||
if (g_cfg.core.ppu_debug && g_system == system_type::ps3)
|
||||
{
|
||||
utils::memory_commit(g_stat_addr + addr, size);
|
||||
}
|
||||
|
||||
for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++)
|
||||
{
|
||||
@ -415,15 +404,8 @@ namespace vm
|
||||
{
|
||||
if (u32 page_size = (i - start) * 4096)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
DWORD old;
|
||||
|
||||
auto protection = start_value & page_writable ? PAGE_READWRITE : (start_value & page_readable ? PAGE_READONLY : PAGE_NOACCESS);
|
||||
verify(__func__), ::VirtualProtect(vm::base(start * 4096), page_size, protection, &old);
|
||||
#else
|
||||
auto protection = start_value & page_writable ? PROT_WRITE | PROT_READ : (start_value & page_readable ? PROT_READ : PROT_NONE);
|
||||
verify(__func__), !::mprotect(vm::base(start * 4096), page_size, protection);
|
||||
#endif
|
||||
const auto protection = start_value & page_writable ? utils::protection::rw : (start_value & page_readable ? utils::protection::ro : utils::protection::no);
|
||||
utils::memory_protect(g_base_addr + start * 4096, page_size, protection);
|
||||
}
|
||||
|
||||
start_value = new_val;
|
||||
@ -457,16 +439,13 @@ namespace vm
|
||||
}
|
||||
}
|
||||
|
||||
void* real_addr = g_base_addr + addr;
|
||||
void* exec_addr = g_exec_addr + addr;
|
||||
utils::memory_decommit(g_base_addr + addr, size);
|
||||
utils::memory_decommit(g_exec_addr + addr, size);
|
||||
|
||||
#ifdef _WIN32
|
||||
verify(__func__), ::VirtualFree(real_addr, size, MEM_DECOMMIT);
|
||||
verify(__func__), ::VirtualFree(exec_addr, size, MEM_DECOMMIT);
|
||||
#else
|
||||
verify(__func__), ::mmap(real_addr, size, PROT_NONE, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
verify(__func__), ::mmap(exec_addr, size, PROT_NONE, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
#endif
|
||||
if (g_cfg.core.ppu_debug && g_system == system_type::ps3)
|
||||
{
|
||||
utils::memory_decommit(g_stat_addr + addr, size);
|
||||
}
|
||||
}
|
||||
|
||||
bool check_addr(u32 addr, u32 size, u8 flags)
|
||||
@ -856,6 +835,7 @@ namespace vm
|
||||
|
||||
utils::memory_decommit(g_base_addr, 0x100000000);
|
||||
utils::memory_decommit(g_exec_addr, 0x100000000);
|
||||
utils::memory_decommit(g_stat_addr, 0x100000000);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ namespace vm
|
||||
{
|
||||
extern u8* const g_base_addr;
|
||||
extern u8* const g_exec_addr;
|
||||
extern u8* const g_stat_addr;
|
||||
|
||||
enum memory_location_t : uint
|
||||
{
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "Emu/Cell/PPUThread.h"
|
||||
#include "Emu/Cell/PPUCallback.h"
|
||||
#include "Emu/Cell/PPUOpcodes.h"
|
||||
#include "Emu/Cell/PPUDisAsm.h"
|
||||
#include "Emu/Cell/SPUThread.h"
|
||||
#include "Emu/Cell/RawSPUThread.h"
|
||||
#include "Emu/Cell/lv2/sys_sync.h"
|
||||
@ -695,6 +696,37 @@ void Emulator::Resume()
|
||||
m_pause_amend_time += get_system_time() - time;
|
||||
}
|
||||
|
||||
// Print and reset debug data collected
|
||||
if (m_state == system_state::paused && g_cfg.core.ppu_debug && g_system == system_type::ps3)
|
||||
{
|
||||
PPUDisAsm dis_asm(CPUDisAsm_InterpreterMode);
|
||||
dis_asm.offset = vm::g_base_addr;
|
||||
|
||||
std::string dump;
|
||||
|
||||
for (u32 i = 0x10000; i < 0x40000000;)
|
||||
{
|
||||
if (vm::check_addr(i))
|
||||
{
|
||||
if (auto& data = *(be_t<u32>*)(vm::g_stat_addr + i))
|
||||
{
|
||||
dis_asm.dump_pc = i;
|
||||
dis_asm.disasm(i);
|
||||
fmt::append(dump, "\n\t'%08X' %s", data, dis_asm.last_opcode);
|
||||
data = 0;
|
||||
}
|
||||
|
||||
i += sizeof(u32);
|
||||
}
|
||||
else
|
||||
{
|
||||
i += 4096;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_NOTICE(PPU, "[RESUME] Dumping instruction stats:%s", dump);
|
||||
}
|
||||
|
||||
// Try to resume
|
||||
if (!m_state.compare_and_swap_test(system_state::paused, system_state::running))
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user