Merge pull request #908 from FioraAeterna/fixenhancedbat
MMU: fix enhanced BAT support
This commit is contained in:
commit
e5705a9273
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue