From 8461ea19b166d6a341abfe9ba857da41ed00ab68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 4 Jul 2020 20:30:05 +0200 Subject: [PATCH] Centralize handling of memory exceptions a bit --- Core/Core.cpp | 31 ++++++++++++++++++++++++++ Core/Core.h | 10 +++++++++ Core/MIPS/IR/IRInterpreter.cpp | 5 +---- Core/MIPS/MIPSInt.cpp | 7 +----- Core/MemMapFunctions.cpp | 40 ++++------------------------------ Core/System.cpp | 13 ++++++----- 6 files changed, 54 insertions(+), 52 deletions(-) diff --git a/Core/Core.cpp b/Core/Core.cpp index 2e4bba6f06..41e5c170c0 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -29,6 +29,7 @@ #include "profiler/profiler.h" #include "Common/GraphicsContext.h" +#include "Common/Log.h" #include "Core/Core.h" #include "Core/Config.h" #include "Core/Host.h" @@ -368,3 +369,33 @@ void Core_EnableStepping(bool step) { int Core_GetSteppingCounter() { return steppingCounter; } + +void Core_MemoryException(u32 address, u32 pc, MemoryExceptionType type) { + const char *desc = ""; + switch (type) { + case MemoryExceptionType::READ_WORD: desc = "Read Word"; break; + case MemoryExceptionType::WRITE_WORD: desc = "Write Word"; break; + case MemoryExceptionType::READ_BLOCK: desc = "Read Block"; break; + case MemoryExceptionType::WRITE_BLOCK: desc = "Read/Write Block"; break; + } + + // In jit, we only flush PC when bIgnoreBadMemAccess is off. + if (g_Config.iCpuCore == (int)CPUCore::JIT && g_Config.bIgnoreBadMemAccess) { + WARN_LOG(MEMMAP, "%s: Invalid address %08x", desc, address); + } else { + WARN_LOG(MEMMAP, "%s: Invalid address %08x PC %08x LR %08x", desc, address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); + } + + if (!g_Config.bIgnoreBadMemAccess) { + Core_EnableStepping(true); + host->SetDebugMode(true); + } +} + +void Core_Break() { + ERROR_LOG(CPU, "BREAK!"); + if (!g_Config.bIgnoreBadMemAccess) { + Core_EnableStepping(true); + host->SetDebugMode(true); + } +} diff --git a/Core/Core.h b/Core/Core.h index 69749f0d70..f5cb4ca038 100644 --- a/Core/Core.h +++ b/Core/Core.h @@ -76,3 +76,13 @@ void Core_NotifyActivity(); void Core_SetPowerSaving(bool mode); bool Core_GetPowerSaving(); + +enum class MemoryExceptionType { + READ_WORD, + WRITE_WORD, + READ_BLOCK, + WRITE_BLOCK, +}; + +void Core_MemoryException(u32 address, u32 pc, MemoryExceptionType type); +void Core_Break(); diff --git a/Core/MIPS/IR/IRInterpreter.cpp b/Core/MIPS/IR/IRInterpreter.cpp index 9a4e491228..63a1d57189 100644 --- a/Core/MIPS/IR/IRInterpreter.cpp +++ b/Core/MIPS/IR/IRInterpreter.cpp @@ -947,10 +947,7 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, int count) { } case IROp::Break: - if (!g_Config.bIgnoreBadMemAccess) { - Core_EnableStepping(true); - host->SetDebugMode(true); - } + Core_Break(); return mips->pc + 4; case IROp::SetCtrlVFPU: diff --git a/Core/MIPS/MIPSInt.cpp b/Core/MIPS/MIPSInt.cpp index 93372391c8..9ca3ee67b1 100644 --- a/Core/MIPS/MIPSInt.cpp +++ b/Core/MIPS/MIPSInt.cpp @@ -151,12 +151,7 @@ namespace MIPSInt void Int_Break(MIPSOpcode op) { - Reporting::ReportMessage("BREAK instruction hit"); - ERROR_LOG(CPU, "BREAK!"); - if (!g_Config.bIgnoreBadMemAccess) { - Core_EnableStepping(true); - host->SetDebugMode(true); - } + Core_Break(); PC += 4; } diff --git a/Core/MemMapFunctions.cpp b/Core/MemMapFunctions.cpp index ac543e36bd..4c00281840 100644 --- a/Core/MemMapFunctions.cpp +++ b/Core/MemMapFunctions.cpp @@ -26,17 +26,7 @@ #include "Core/MIPS/MIPS.h" -namespace Memory -{ - -// ================================= -// From Memmap.cpp -// ---------------- - -// Read and write shortcuts - -// GetPointer must always return an address in the bottom 32 bits of address space, so that 64-bit -// programs don't have problems directly addressing any part of memory. +namespace Memory { u8 *GetPointer(const u32 address) { if ((address & 0x3E000000) == 0x08000000) { @@ -52,16 +42,12 @@ u8 *GetPointer(const u32 address) { // More RAM (remasters, etc.) return GetPointerUnchecked(address); } else { - ERROR_LOG(MEMMAP, "Unknown GetPointer %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); static bool reported = false; if (!reported) { Reporting::ReportMessage("Unknown GetPointer %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); reported = true; } - if (!g_Config.bIgnoreBadMemAccess) { - Core_EnableStepping(true); - host->SetDebugMode(true); - } + Core_MemoryException(address, currentMIPS->pc, MemoryExceptionType::WRITE_BLOCK); return nullptr; } } @@ -86,21 +72,12 @@ inline void ReadFromHardware(T &var, const u32 address) { // More RAM (remasters, etc.) var = *((const T*)GetPointerUnchecked(address)); } else { - // In jit, we only flush PC when bIgnoreBadMemAccess is off. - if (g_Config.iCpuCore == (int)CPUCore::JIT && g_Config.bIgnoreBadMemAccess) { - WARN_LOG(MEMMAP, "ReadFromHardware: Invalid address %08x", address); - } else { - WARN_LOG(MEMMAP, "ReadFromHardware: Invalid address %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); - } static bool reported = false; if (!reported) { Reporting::ReportMessage("ReadFromHardware: Invalid address %08x near PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); reported = true; } - if (!g_Config.bIgnoreBadMemAccess) { - Core_EnableStepping(true); - host->SetDebugMode(true); - } + Core_MemoryException(address, currentMIPS->pc, MemoryExceptionType::READ_WORD); var = 0; } } @@ -122,21 +99,12 @@ inline void WriteToHardware(u32 address, const T data) { // More RAM (remasters, etc.) *(T*)GetPointerUnchecked(address) = data; } else { - // In jit, we only flush PC when bIgnoreBadMemAccess is off. - if (g_Config.iCpuCore == (int)CPUCore::JIT && g_Config.bIgnoreBadMemAccess) { - WARN_LOG(MEMMAP, "WriteToHardware: Invalid address %08x", address); - } else { - WARN_LOG(MEMMAP, "WriteToHardware: Invalid address %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); - } static bool reported = false; if (!reported) { Reporting::ReportMessage("WriteToHardware: Invalid address %08x near PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); reported = true; } - if (!g_Config.bIgnoreBadMemAccess) { - Core_EnableStepping(true); - host->SetDebugMode(true); - } + Core_MemoryException(address, currentMIPS->pc, MemoryExceptionType::WRITE_WORD); } } diff --git a/Core/System.cpp b/Core/System.cpp index 4b95c2bda0..9a6fcb1779 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -97,13 +97,19 @@ bool coreCollectDebugStatsForced = false; // This can be read and written from ANYWHERE. volatile CoreState coreState = CORE_STEPPING; -// Note: intentionally not used for CORE_NEXTFRAME. +// Note: intentionally not used for CORE_NEXTFRAME. << TODO: This comment is a lie, it is used! volatile bool coreStatePending = false; + static volatile CPUThreadState cpuThreadState = CPU_THREAD_NOT_RUNNING; static GPUBackend gpuBackend; static std::string gpuBackendDevice; +// Ugly! +static bool pspIsInited = false; +static bool pspIsIniting = false; +static bool pspIsQuitting = false; + void ResetUIState() { globalUIState = UISTATE_MENU; } @@ -328,11 +334,6 @@ void Core_UpdateDebugStats(bool collectStats) { gpuStats.ResetFrame(); } -// Ugly! -static bool pspIsInited = false; -static bool pspIsIniting = false; -static bool pspIsQuitting = false; - bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) { if (pspIsIniting || pspIsQuitting) { return false;