diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp index 1d57d971b4..dac66cb259 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp @@ -10,6 +10,7 @@ #include "Core/Debugger/BranchWatch.h" #include "Core/HLE/HLE.h" #include "Core/PowerPC/Interpreter/ExceptionUtils.h" +#include "Core/PowerPC/MMU.h" #include "Core/PowerPC/PowerPC.h" #include "Core/System.h" @@ -141,6 +142,18 @@ void Interpreter::rfi(Interpreter& interpreter, UGeckoInstruction inst) { auto& ppc_state = interpreter.m_ppc_state; + if (ppc_state.ibat_update_pending) + { + interpreter.m_mmu.IBATUpdated(); + ppc_state.ibat_update_pending = false; + } + + if (ppc_state.dbat_update_pending) + { + interpreter.m_mmu.DBATUpdated(); + ppc_state.dbat_update_pending = false; + } + if (ppc_state.msr.PR) { GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction); diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp index a28a968653..77b2fa8e79 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp @@ -173,6 +173,19 @@ void Interpreter::mfsrin(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::mtmsr(Interpreter& interpreter, UGeckoInstruction inst) { auto& ppc_state = interpreter.m_ppc_state; + + if (ppc_state.ibat_update_pending) + { + interpreter.m_mmu.IBATUpdated(); + ppc_state.ibat_update_pending = false; + } + + if (ppc_state.dbat_update_pending) + { + interpreter.m_mmu.DBATUpdated(); + ppc_state.dbat_update_pending = false; + } + if (ppc_state.msr.PR) { GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction); @@ -383,8 +396,8 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst) if (old_value != ppc_state.spr[index]) { INFO_LOG_FMT(POWERPC, "HID4 updated {:x} {:x}", old_value, ppc_state.spr[index]); - interpreter.m_mmu.IBATUpdated(); - interpreter.m_mmu.DBATUpdated(); + ppc_state.ibat_update_pending = true; + ppc_state.dbat_update_pending = true; } break; @@ -466,7 +479,7 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst) if (old_value != ppc_state.spr[index]) { INFO_LOG_FMT(POWERPC, "DBAT updated {} {:x} {:x}", index, old_value, ppc_state.spr[index]); - interpreter.m_mmu.DBATUpdated(); + ppc_state.dbat_update_pending = true; } break; @@ -489,7 +502,7 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst) if (old_value != ppc_state.spr[index]) { INFO_LOG_FMT(POWERPC, "IBAT updated {} {:x} {:x}", index, old_value, ppc_state.spr[index]); - interpreter.m_mmu.IBATUpdated(); + ppc_state.ibat_update_pending = true; } break; @@ -612,7 +625,21 @@ void Interpreter::mcrf(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::isync(Interpreter& interpreter, UGeckoInstruction inst) { - // shouldn't do anything + // useful hook for lazy updating of BATs + + auto& ppc_state = interpreter.m_ppc_state; + + if (ppc_state.ibat_update_pending && ppc_state.msr.IR) + { + interpreter.m_mmu.IBATUpdated(); + ppc_state.ibat_update_pending = false; + } + + if (ppc_state.dbat_update_pending && ppc_state.msr.DR) + { + interpreter.m_mmu.DBATUpdated(); + ppc_state.dbat_update_pending = false; + } } // the following commands read from FPSCR diff --git a/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp b/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp index 1914542c9f..3d64fc8615 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp @@ -143,10 +143,10 @@ constexpr std::array s_table19{{ {417, &Jit64::crXXX}, // crorc {193, &Jit64::crXXX}, // crxor - {150, &Jit64::DoNothing}, // isync - {0, &Jit64::mcrf}, // mcrf + {150, &Jit64::FallBackToInterpreter}, // isync + {0, &Jit64::mcrf}, // mcrf - {50, &Jit64::rfi}, // rfi + {50, &Jit64::FallBackToInterpreter}, // rfi }}; constexpr std::array s_table31{{ @@ -269,7 +269,7 @@ constexpr std::array s_table31{{ {19, &Jit64::mfcr}, // mfcr {83, &Jit64::mfmsr}, // mfmsr {144, &Jit64::mtcrf}, // mtcrf - {146, &Jit64::mtmsr}, // mtmsr + {146, &Jit64::FallBackToInterpreter}, // mtmsr {210, &Jit64::FallBackToInterpreter}, // mtsr {242, &Jit64::FallBackToInterpreter}, // mtsrin {339, &Jit64::mfspr}, // mfspr diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp index 09013ee196..43cc6b3b48 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp @@ -143,10 +143,10 @@ constexpr std::array s_table19{{ {417, &JitArm64::crXXX}, // crorc {193, &JitArm64::crXXX}, // crxor - {150, &JitArm64::DoNothing}, // isync - {0, &JitArm64::mcrf}, // mcrf + {150, &JitArm64::FallBackToInterpreter}, // isync + {0, &JitArm64::mcrf}, // mcrf - {50, &JitArm64::rfi}, // rfi + {50, &JitArm64::FallBackToInterpreter}, // rfi }}; constexpr std::array s_table31{{ @@ -266,18 +266,18 @@ constexpr std::array s_table31{{ {759, &JitArm64::stfXX}, // stfdux {983, &JitArm64::stfXX}, // stfiwx - {19, &JitArm64::mfcr}, // mfcr - {83, &JitArm64::mfmsr}, // mfmsr - {144, &JitArm64::mtcrf}, // mtcrf - {146, &JitArm64::mtmsr}, // mtmsr - {210, &JitArm64::mtsr}, // mtsr - {242, &JitArm64::mtsrin}, // mtsrin - {339, &JitArm64::mfspr}, // mfspr - {467, &JitArm64::mtspr}, // mtspr - {371, &JitArm64::mftb}, // mftb - {512, &JitArm64::mcrxr}, // mcrxr - {595, &JitArm64::mfsr}, // mfsr - {659, &JitArm64::mfsrin}, // mfsrin + {19, &JitArm64::mfcr}, // mfcr + {83, &JitArm64::mfmsr}, // mfmsr + {144, &JitArm64::mtcrf}, // mtcrf + {146, &JitArm64::FallBackToInterpreter}, // mtmsr + {210, &JitArm64::mtsr}, // mtsr + {242, &JitArm64::mtsrin}, // mtsrin + {339, &JitArm64::mfspr}, // mfspr + {467, &JitArm64::mtspr}, // mtspr + {371, &JitArm64::mftb}, // mftb + {512, &JitArm64::mcrxr}, // mcrxr + {595, &JitArm64::mfsr}, // mfsr + {659, &JitArm64::mfsrin}, // mfsrin {4, &JitArm64::twx}, // tw {598, &JitArm64::DoNothing}, // sync diff --git a/Source/Core/Core/PowerPC/PowerPC.h b/Source/Core/Core/PowerPC/PowerPC.h index 662507697e..e0d2f37504 100644 --- a/Source/Core/Core/PowerPC/PowerPC.h +++ b/Source/Core/Core/PowerPC/PowerPC.h @@ -166,6 +166,9 @@ struct PowerPCState u32 sr[16]{}; // Segment registers. + bool ibat_update_pending = false; + bool dbat_update_pending = false; + // special purpose registers - controls quantizers, DMA, and lots of other misc extensions. // also for power management, but we don't care about that. // JitArm64 needs 64-bit alignment for SPR_TL.