From 31fd18ab156f86ec2fced0641d2c76fba60a7d2d Mon Sep 17 00:00:00 2001 From: Nathanael Premillieu Date: Tue, 26 May 2015 03:21:42 -0400 Subject: 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. --- src/arch/arm/tlb.cc | 11 +++++------ src/arch/arm/tlb.hh | 1 + src/arch/arm/utility.cc | 32 ++++++++++++++++++++++++++++++++ src/arch/arm/utility.hh | 2 ++ 4 files changed, 40 insertions(+), 6 deletions(-) (limited to 'src/arch/arm') diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc index 61c2eb9d6..dfda14d30 100644 --- a/src/arch/arm/tlb.cc +++ b/src/arch/arm/tlb.cc @@ -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(); } @@ -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; } diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh index 6ed89af7c..fba5775aa 100644 --- a/src/arch/arm/tlb.hh +++ b/src/arch/arm/tlb.hh @@ -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; diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc index e4a8f506f..34fcfd482 100644 --- a/src/arch/arm/utility.cc +++ b/src/arch/arm/utility.cc @@ -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) { diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh index 0c29ac90e..9268a0d5c 100644 --- a/src/arch/arm/utility.hh +++ b/src/arch/arm/utility.hh @@ -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 -- cgit v1.2.3