arm: Make address translation faster with better caching
authorNathanael Premillieu <Nathanael.Premillieu@arm.com>
Tue, 26 May 2015 07:21:42 +0000 (03:21 -0400)
committerNathanael Premillieu <Nathanael.Premillieu@arm.com>
Tue, 26 May 2015 07:21:42 +0000 (03:21 -0400)
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
src/arch/arm/tlb.hh
src/arch/arm/utility.cc
src/arch/arm/utility.hh

index 61c2eb9d60af34651df0c12645b27b094b21393f..dfda14d307271cade83d3b97d971df819259b6c5 100644 (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;
     }
index 6ed89af7c1d2da649d31b66c47f4a77767223c1a..fba5775aa3f9d5188373909aacf32945c44357f8 100644 (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;
index e4a8f506f72c14650b2f157dd1aa1ef81d0df71f..34fcfd48259a52db0efb62f7107441b77844e994 100644 (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)
 {
index 0c29ac90ec483277b2e3482cb60096130322594e..9268a0d5cf6a7245e810a6145cccc4ba8d69e66c 100644 (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