Interpreter: Check processor privilege level when executing supervisor instructions
Executing a supervisor-level instruction in user mode is supposed to
cause a program exception to occur.
The following supervisor instructions are present:
- dcbi
- mfmsr
- mfspr
- mfsr
- mfsrin
- mtmsr
- mtspr
- mtsr
- mtsrin
- rfi
- tlbie
- tlbsync
In 0337ca116a
checks within mfspr and
mtspr were added. This change adds the trivial checks to the other
instructions.
This commit is contained in:
parent
f64bd401b6
commit
9a088e008f
|
@ -7,6 +7,7 @@
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
#include "Core/CoreTiming.h"
|
#include "Core/CoreTiming.h"
|
||||||
#include "Core/HLE/HLE.h"
|
#include "Core/HLE/HLE.h"
|
||||||
|
#include "Core/PowerPC/Interpreter/ExceptionUtils.h"
|
||||||
#include "Core/PowerPC/Interpreter/Interpreter.h"
|
#include "Core/PowerPC/Interpreter/Interpreter.h"
|
||||||
#include "Core/PowerPC/MMU.h"
|
#include "Core/PowerPC/MMU.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
|
@ -119,6 +120,12 @@ void Interpreter::HLEFunction(UGeckoInstruction inst)
|
||||||
|
|
||||||
void Interpreter::rfi(UGeckoInstruction inst)
|
void Interpreter::rfi(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
|
if (MSR.PR)
|
||||||
|
{
|
||||||
|
GenerateProgramException();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Restore saved bits from SRR1 to MSR.
|
// Restore saved bits from SRR1 to MSR.
|
||||||
// Gecko/Broadway can save more bits than explicitly defined in ppc spec
|
// Gecko/Broadway can save more bits than explicitly defined in ppc spec
|
||||||
const u32 mask = 0x87C0FFFF;
|
const u32 mask = 0x87C0FFFF;
|
||||||
|
|
|
@ -456,6 +456,12 @@ void Interpreter::dcbf(UGeckoInstruction inst)
|
||||||
|
|
||||||
void Interpreter::dcbi(UGeckoInstruction inst)
|
void Interpreter::dcbi(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
|
if (MSR.PR)
|
||||||
|
{
|
||||||
|
GenerateProgramException();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Implement some sort of L2 emulation.
|
// TODO: Implement some sort of L2 emulation.
|
||||||
// TODO: Raise DSI if translation fails (except for direct-store segments).
|
// 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)
|
void Interpreter::tlbie(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
|
if (MSR.PR)
|
||||||
|
{
|
||||||
|
GenerateProgramException();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Invalidate TLB entry
|
// Invalidate TLB entry
|
||||||
const u32 address = rGPR[inst.RB];
|
const u32 address = rGPR[inst.RB];
|
||||||
|
|
||||||
|
@ -1062,5 +1074,10 @@ void Interpreter::tlbie(UGeckoInstruction inst)
|
||||||
|
|
||||||
void Interpreter::tlbsync(UGeckoInstruction inst)
|
void Interpreter::tlbsync(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
|
if (MSR.PR)
|
||||||
|
{
|
||||||
|
GenerateProgramException();
|
||||||
|
}
|
||||||
|
|
||||||
// Ignored
|
// Ignored
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,24 +137,46 @@ void Interpreter::mtcrf(UGeckoInstruction inst)
|
||||||
|
|
||||||
void Interpreter::mfmsr(UGeckoInstruction inst)
|
void Interpreter::mfmsr(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
// Privileged?
|
if (MSR.PR)
|
||||||
|
{
|
||||||
|
GenerateProgramException();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
rGPR[inst.RD] = MSR.Hex;
|
rGPR[inst.RD] = MSR.Hex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::mfsr(UGeckoInstruction inst)
|
void Interpreter::mfsr(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
|
if (MSR.PR)
|
||||||
|
{
|
||||||
|
GenerateProgramException();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
rGPR[inst.RD] = PowerPC::ppcState.sr[inst.SR];
|
rGPR[inst.RD] = PowerPC::ppcState.sr[inst.SR];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::mfsrin(UGeckoInstruction inst)
|
void Interpreter::mfsrin(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
|
if (MSR.PR)
|
||||||
|
{
|
||||||
|
GenerateProgramException();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const u32 index = (rGPR[inst.RB] >> 28) & 0xF;
|
const u32 index = (rGPR[inst.RB] >> 28) & 0xF;
|
||||||
rGPR[inst.RD] = PowerPC::ppcState.sr[index];
|
rGPR[inst.RD] = PowerPC::ppcState.sr[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::mtmsr(UGeckoInstruction inst)
|
void Interpreter::mtmsr(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
// Privileged?
|
if (MSR.PR)
|
||||||
|
{
|
||||||
|
GenerateProgramException();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MSR.Hex = rGPR[inst.RS];
|
MSR.Hex = rGPR[inst.RS];
|
||||||
PowerPC::CheckExceptions();
|
PowerPC::CheckExceptions();
|
||||||
m_end_block = true;
|
m_end_block = true;
|
||||||
|
@ -171,6 +193,12 @@ static void SetSR(u32 index, u32 value)
|
||||||
|
|
||||||
void Interpreter::mtsr(UGeckoInstruction inst)
|
void Interpreter::mtsr(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
|
if (MSR.PR)
|
||||||
|
{
|
||||||
|
GenerateProgramException();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const u32 index = inst.SR;
|
const u32 index = inst.SR;
|
||||||
const u32 value = rGPR[inst.RS];
|
const u32 value = rGPR[inst.RS];
|
||||||
SetSR(index, value);
|
SetSR(index, value);
|
||||||
|
@ -178,6 +206,12 @@ void Interpreter::mtsr(UGeckoInstruction inst)
|
||||||
|
|
||||||
void Interpreter::mtsrin(UGeckoInstruction inst)
|
void Interpreter::mtsrin(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
|
if (MSR.PR)
|
||||||
|
{
|
||||||
|
GenerateProgramException();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const u32 index = (rGPR[inst.RB] >> 28) & 0xF;
|
const u32 index = (rGPR[inst.RB] >> 28) & 0xF;
|
||||||
const u32 value = rGPR[inst.RS];
|
const u32 value = rGPR[inst.RS];
|
||||||
SetSR(index, value);
|
SetSR(index, value);
|
||||||
|
|
Loading…
Reference in New Issue