summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorDolphin Bot <dolphin-emu-bot@users.noreply.github.com>2014-09-02 05:46:03 +0200
committerDolphin Bot <dolphin-emu-bot@users.noreply.github.com>2014-09-02 05:46:03 +0200
commite5705a9273d8977dae8de3cdddea7f28601e71b8 (patch)
tree56a9793743e191f020352bbd16e449e608ba1a01 /Source
parentaec639470f2ae32826b7c0d00e0323a6e3d87f18 (diff)
parent08ab2d3110282acfcca6646c215b08ef9d573845 (diff)
Merge pull request #908 from FioraAeterna/fixenhancedbat
MMU: fix enhanced BAT support
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/HW/MemmapFunctions.cpp84
1 files changed, 37 insertions, 47 deletions
diff --git a/Source/Core/Core/HW/MemmapFunctions.cpp b/Source/Core/Core/HW/MemmapFunctions.cpp
index 596ebf1e8c..78192556a5 100644
--- a/Source/Core/Core/HW/MemmapFunctions.cpp
+++ b/Source/Core/Core/HW/MemmapFunctions.cpp
@@ -846,63 +846,53 @@ static u32 TranslatePageAddress(const u32 _Address, const XCheckTLBFlag _Flag)
#define BAT_EA_11(v) ((v)&0x0ffe0000)
#define BAT_EA_4(v) ((v)&0xf0000000)
+static inline bool CheckAddrBats(const u32 addr, u32* result, u32 batu, u32 spr)
+{
+ for (int i = 0; i < 4; i++)
+ {
+ u32 bl17 = ~(BATU_BL(PowerPC::ppcState.spr[spr + i * 2]) << 17);
+ u32 addr2 = addr & (bl17 | 0xf001ffff);
+
+ if (BATU_BEPI(addr2) == BATU_BEPI(PowerPC::ppcState.spr[spr + i * 2]))
+ {
+ // bat applies to this address
+ if (PowerPC::ppcState.spr[spr + i * 2] & batu)
+ {
+ // bat entry valid
+ u32 offset = BAT_EA_OFFSET(addr);
+ u32 page = BAT_EA_11(addr);
+ page &= ~bl17;
+ page |= BATL_BRPN(PowerPC::ppcState.spr[spr + 1 + i * 2]);
+ // fixme: check access rights
+ *result = page | offset;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
// Block Address Translation
static u32 TranslateBlockAddress(const u32 addr, const XCheckTLBFlag _Flag)
{
u32 result = 0;
UReg_MSR& m_MSR = ((UReg_MSR&)PowerPC::ppcState.msr);
+ u32 batu = (m_MSR.PR ? BATU_Vp : BATU_Vs);
// Check for enhanced mode (secondary BAT enable) using 8 BATs
- int bats = (Core::g_CoreStartupParameter.bWii && HID4.SBE)?8:4;
+ bool enhanced_bats = Core::g_CoreStartupParameter.bWii && HID4.SBE;
- for (int i = 0; i < bats; i++)
+ if (_Flag != FLAG_OPCODE)
{
- if (_Flag != FLAG_OPCODE)
- {
- u32 bl17 = ~(BATU_BL(PowerPC::ppcState.spr[SPR_DBAT0U + i * 2]) << 17);
- u32 addr2 = addr & (bl17 | 0xf001ffff);
- u32 batu = (m_MSR.PR ? BATU_Vp : BATU_Vs);
-
- if (BATU_BEPI(addr2) == BATU_BEPI(PowerPC::ppcState.spr[SPR_DBAT0U + i * 2]))
- {
- // bat applies to this address
- if (PowerPC::ppcState.spr[SPR_DBAT0U + i * 2] & batu)
- {
- // bat entry valid
- u32 offset = BAT_EA_OFFSET(addr);
- u32 page = BAT_EA_11(addr);
- page &= ~bl17;
- page |= BATL_BRPN(PowerPC::ppcState.spr[SPR_DBAT0L + i * 2]);
- // fixme: check access rights
- result = page | offset;
- return result;
- }
- }
- }
- else
- {
- u32 bl17 = ~(BATU_BL(PowerPC::ppcState.spr[SPR_IBAT0U + i * 2]) << 17);
- u32 addr2 = addr & (bl17 | 0xf001ffff);
- u32 batu = (m_MSR.PR ? BATU_Vp : BATU_Vs);
-
- if (BATU_BEPI(addr2) == BATU_BEPI(PowerPC::ppcState.spr[SPR_IBAT0U + i * 2]))
- {
- // bat applies to this address
- if (PowerPC::ppcState.spr[SPR_IBAT0U + i * 2] & batu)
- {
- // bat entry valid
- u32 offset = BAT_EA_OFFSET(addr);
- u32 page = BAT_EA_11(addr);
- page &= ~bl17;
- page |= BATL_BRPN(PowerPC::ppcState.spr[SPR_IBAT0L + i * 2]);
- // fixme: check access rights
- result = page | offset;
- return result;
- }
- }
- }
+ if (!CheckAddrBats(addr, &result, batu, SPR_DBAT0U) && enhanced_bats)
+ CheckAddrBats(addr, &result, batu, SPR_DBAT4U);
}
- return 0;
+ else
+ {
+ if (!CheckAddrBats(addr, &result, batu, SPR_IBAT0U) && enhanced_bats)
+ CheckAddrBats(addr, &result, batu, SPR_IBAT4U);
+ }
+ return result;
}
// Translate effective address using BAT or PAT. Returns 0 if the address cannot be translated.