Merge pull request #908 from FioraAeterna/fixenhancedbat

MMU: fix enhanced BAT support
This commit is contained in:
Dolphin Bot 2014-09-02 05:46:03 +02:00
commit e5705a9273
1 changed files with 37 additions and 47 deletions

View File

@ -846,64 +846,54 @@ 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);
// Check for enhanced mode (secondary BAT enable) using 8 BATs
int bats = (Core::g_CoreStartupParameter.bWii && HID4.SBE)?8:4;
for (int i = 0; i < bats; i++)
{
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]))
// Check for enhanced mode (secondary BAT enable) using 8 BATs
bool enhanced_bats = Core::g_CoreStartupParameter.bWii && HID4.SBE;
if (_Flag != FLAG_OPCODE)
{
// 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;
}
}
if (!CheckAddrBats(addr, &result, batu, SPR_DBAT0U) && enhanced_bats)
CheckAddrBats(addr, &result, batu, SPR_DBAT4U);
}
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;
if (!CheckAddrBats(addr, &result, batu, SPR_IBAT0U) && enhanced_bats)
CheckAddrBats(addr, &result, batu, SPR_IBAT4U);
}
return result;
}
}
}
}
return 0;
}
// Translate effective address using BAT or PAT. Returns 0 if the address cannot be translated.
u32 TranslateAddress(const u32 _Address, const XCheckTLBFlag _Flag)