diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp index 22815f1993..0d07309cd7 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp @@ -7,6 +7,7 @@ #include "Core/ConfigManager.h" #include "Core/CoreTiming.h" #include "Core/HLE/HLE.h" +#include "Core/PowerPC/Interpreter/ExceptionUtils.h" #include "Core/PowerPC/Interpreter/Interpreter.h" #include "Core/PowerPC/MMU.h" #include "Core/PowerPC/PowerPC.h" @@ -119,6 +120,12 @@ void Interpreter::HLEFunction(UGeckoInstruction inst) void Interpreter::rfi(UGeckoInstruction inst) { + if (MSR.PR) + { + GenerateProgramException(); + return; + } + // Restore saved bits from SRR1 to MSR. // Gecko/Broadway can save more bits than explicitly defined in ppc spec const u32 mask = 0x87C0FFFF; diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp index 679517b21a..ecdf2ca5fc 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp @@ -456,6 +456,12 @@ void Interpreter::dcbf(UGeckoInstruction inst) void Interpreter::dcbi(UGeckoInstruction inst) { + if (MSR.PR) + { + GenerateProgramException(); + return; + } + // TODO: Implement some sort of L2 emulation. // TODO: Raise DSI if translation fails (except for direct-store segments). @@ -1054,6 +1060,12 @@ void Interpreter::sync(UGeckoInstruction inst) void Interpreter::tlbie(UGeckoInstruction inst) { + if (MSR.PR) + { + GenerateProgramException(); + return; + } + // Invalidate TLB entry const u32 address = rGPR[inst.RB]; @@ -1062,5 +1074,10 @@ void Interpreter::tlbie(UGeckoInstruction inst) void Interpreter::tlbsync(UGeckoInstruction inst) { + if (MSR.PR) + { + GenerateProgramException(); + } + // Ignored } diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp index 510f83758d..59ef7f5a57 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp @@ -137,24 +137,46 @@ void Interpreter::mtcrf(UGeckoInstruction inst) void Interpreter::mfmsr(UGeckoInstruction inst) { - // Privileged? + if (MSR.PR) + { + GenerateProgramException(); + return; + } + rGPR[inst.RD] = MSR.Hex; } void Interpreter::mfsr(UGeckoInstruction inst) { + if (MSR.PR) + { + GenerateProgramException(); + return; + } + rGPR[inst.RD] = PowerPC::ppcState.sr[inst.SR]; } void Interpreter::mfsrin(UGeckoInstruction inst) { + if (MSR.PR) + { + GenerateProgramException(); + return; + } + const u32 index = (rGPR[inst.RB] >> 28) & 0xF; rGPR[inst.RD] = PowerPC::ppcState.sr[index]; } void Interpreter::mtmsr(UGeckoInstruction inst) { - // Privileged? + if (MSR.PR) + { + GenerateProgramException(); + return; + } + MSR.Hex = rGPR[inst.RS]; PowerPC::CheckExceptions(); m_end_block = true; @@ -171,6 +193,12 @@ static void SetSR(u32 index, u32 value) void Interpreter::mtsr(UGeckoInstruction inst) { + if (MSR.PR) + { + GenerateProgramException(); + return; + } + const u32 index = inst.SR; const u32 value = rGPR[inst.RS]; SetSR(index, value); @@ -178,6 +206,12 @@ void Interpreter::mtsr(UGeckoInstruction inst) void Interpreter::mtsrin(UGeckoInstruction inst) { + if (MSR.PR) + { + GenerateProgramException(); + return; + } + const u32 index = (rGPR[inst.RB] >> 28) & 0xF; const u32 value = rGPR[inst.RS]; SetSR(index, value);