From 08ab2d3110282acfcca6646c215b08ef9d573845 Mon Sep 17 00:00:00 2001 From: Fiora Date: Sat, 30 Aug 2014 05:38:55 -0700 Subject: [PATCH] MMU: fix enhanced BAT support I don't know what I can test this on, but it was definitely broken before. Seems to be a few clock cycles faster too due to the refactoring? --- Source/Core/Core/HW/MemmapFunctions.cpp | 84 +++++++++++-------------- 1 file changed, 37 insertions(+), 47 deletions(-) diff --git a/Source/Core/Core/HW/MemmapFunctions.cpp b/Source/Core/Core/HW/MemmapFunctions.cpp index c06a8cb9cb..28828eb601 100644 --- a/Source/Core/Core/HW/MemmapFunctions.cpp +++ b/Source/Core/Core/HW/MemmapFunctions.cpp @@ -841,63 +841,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.