arm: Make address translation faster with better caching

This patch adds better caching of the sys regs for AArch64, thus
avoiding unnecessary calls to tc->readMiscReg(MISCREG_CPSR) in the
non-faulting case.
This commit is contained in:
Nathanael Premillieu 2015-05-26 03:21:42 -04:00
parent 53a360985b
commit 31fd18ab15
4 changed files with 40 additions and 6 deletions

View file

@ -546,7 +546,7 @@ TLB::translateSe(RequestPtr req, ThreadContext *tc, Mode mode,
Addr vaddr_tainted = req->getVaddr();
Addr vaddr = 0;
if (aarch64)
vaddr = purifyTaggedAddr(vaddr_tainted, tc, aarch64EL);
vaddr = purifyTaggedAddr(vaddr_tainted, tc, aarch64EL, ttbcr);
else
vaddr = vaddr_tainted;
uint32_t flags = req->getFlags();
@ -765,7 +765,7 @@ TLB::checkPermissions64(TlbEntry *te, RequestPtr req, Mode mode,
assert(aarch64);
Addr vaddr_tainted = req->getVaddr();
Addr vaddr = purifyTaggedAddr(vaddr_tainted, tc, aarch64EL);
Addr vaddr = purifyTaggedAddr(vaddr_tainted, tc, aarch64EL, ttbcr);
uint32_t flags = req->getFlags();
bool is_fetch = (mode == Execute);
@ -959,7 +959,7 @@ TLB::translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
Addr vaddr_tainted = req->getVaddr();
Addr vaddr = 0;
if (aarch64)
vaddr = purifyTaggedAddr(vaddr_tainted, tc, aarch64EL);
vaddr = purifyTaggedAddr(vaddr_tainted, tc, aarch64EL, ttbcr);
else
vaddr = vaddr_tainted;
uint32_t flags = req->getFlags();
@ -1110,7 +1110,6 @@ TLB::translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
// Generate Illegal Inst Set State fault if IL bit is set in CPSR
if (fault == NoFault) {
CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
if (aarch64 && is_fetch && cpsr.il == 1) {
return std::make_shared<IllegalInstSetStateFault>();
}
@ -1222,7 +1221,7 @@ TLB::updateMiscReg(ThreadContext *tc, ArmTranslationType tranType)
}
DPRINTF(TLBVerbose, "TLB variables changed!\n");
CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
cpsr = tc->readMiscReg(MISCREG_CPSR);
// Dependencies: SCR/SCR_EL3, CPSR
isSecure = inSecureState(tc);
isSecure &= (tranType & HypMode) == 0;
@ -1328,7 +1327,7 @@ TLB::getTE(TlbEntry **te, RequestPtr req, ThreadContext *tc, Mode mode,
Addr vaddr = 0;
ExceptionLevel target_el = aarch64 ? aarch64EL : EL1;
if (aarch64) {
vaddr = purifyTaggedAddr(vaddr_tainted, tc, target_el);
vaddr = purifyTaggedAddr(vaddr_tainted, tc, target_el, ttbcr);
} else {
vaddr = vaddr_tainted;
}

View file

@ -312,6 +312,7 @@ class TLB : public BaseTLB
// translateFunctional/translateSe/translateFs checks if they are
// invalid and call updateMiscReg if necessary.
protected:
CPSR cpsr;
bool aarch64;
ExceptionLevel aarch64EL;
SCTLR sctlr;

View file

@ -271,6 +271,38 @@ isBigEndian64(ThreadContext *tc)
}
}
Addr
purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el,
TTBCR tcr)
{
switch (el) {
case EL0:
case EL1:
if (bits(addr, 55, 48) == 0xFF && tcr.tbi1)
return addr | mask(63, 55);
else if (!bits(addr, 55, 48) && tcr.tbi0)
return bits(addr,55, 0);
break;
// @todo: uncomment this to enable Virtualization
// case EL2:
// assert(ArmSystem::haveVirtualization());
// tcr = tc->readMiscReg(MISCREG_TCR_EL2);
// if (tcr.tbi)
// return addr & mask(56);
// break;
case EL3:
assert(ArmSystem::haveSecurity(tc));
if (tcr.tbi)
return addr & mask(56);
break;
default:
panic("Invalid exception level");
break;
}
return addr; // Nothing to do if this is not a tagged address
}
Addr
purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el)
{

View file

@ -168,6 +168,8 @@ bool isBigEndian64(ThreadContext *tc);
* @param el The controlled exception level.
* @return The purified address.
*/
Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el,
TTBCR tcr);
Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el);
static inline bool