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?
This commit is contained in:
parent
d159bc9998
commit
08ab2d3110
|
@ -841,64 +841,54 @@ static u32 TranslatePageAddress(const u32 _Address, const XCheckTLBFlag _Flag)
|
||||||
#define BAT_EA_11(v) ((v)&0x0ffe0000)
|
#define BAT_EA_11(v) ((v)&0x0ffe0000)
|
||||||
#define BAT_EA_4(v) ((v)&0xf0000000)
|
#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
|
// Block Address Translation
|
||||||
static u32 TranslateBlockAddress(const u32 addr, const XCheckTLBFlag _Flag)
|
static u32 TranslateBlockAddress(const u32 addr, const XCheckTLBFlag _Flag)
|
||||||
{
|
{
|
||||||
u32 result = 0;
|
u32 result = 0;
|
||||||
UReg_MSR& m_MSR = ((UReg_MSR&)PowerPC::ppcState.msr);
|
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);
|
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 (!CheckAddrBats(addr, &result, batu, SPR_DBAT0U) && enhanced_bats)
|
||||||
if (PowerPC::ppcState.spr[SPR_DBAT0U + i * 2] & batu)
|
CheckAddrBats(addr, &result, batu, SPR_DBAT4U);
|
||||||
{
|
|
||||||
// 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
|
else
|
||||||
{
|
{
|
||||||
u32 bl17 = ~(BATU_BL(PowerPC::ppcState.spr[SPR_IBAT0U + i * 2]) << 17);
|
if (!CheckAddrBats(addr, &result, batu, SPR_IBAT0U) && enhanced_bats)
|
||||||
u32 addr2 = addr & (bl17 | 0xf001ffff);
|
CheckAddrBats(addr, &result, batu, SPR_IBAT4U);
|
||||||
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;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Translate effective address using BAT or PAT. Returns 0 if the address cannot be translated.
|
// Translate effective address using BAT or PAT. Returns 0 if the address cannot be translated.
|
||||||
u32 TranslateAddress(const u32 _Address, const XCheckTLBFlag _Flag)
|
u32 TranslateAddress(const u32 _Address, const XCheckTLBFlag _Flag)
|
||||||
|
|
Loading…
Reference in New Issue