arch,cpu: "virtualize" the TLB interface.

CPUs have historically instantiated the architecture specific version
of the TLBs to avoid a virtual function call, making them a little bit
more dependent on what the current ISA is. Some simple performance
measurement, the x86 twolf regression on the atomic CPU, shows that
there isn't actually any performance benefit, and if anything the
simulator goes slightly faster (although still within margin of error)
when the TLB functions are virtual.

This change switches everything outside of the architectures themselves
to use the generic BaseTLB type, and then inside the ISA for them to
cast that to their architecture specific type to call into architecture
specific interfaces.

The ARM TLB needed the most adjustment since it was using non-standard
translation function signatures. Specifically, they all took an extra
"type" parameter which defaulted to normal, and translateTiming
returned a Fault. translateTiming actually doesn't need to return a
Fault because everywhere that consumed it just stored it into a
structure which it then deleted(?), and the fault is stored in the
Translation object when the translation is done.

A little more work is needed to fully obviate the arch/tlb.hh header,
so the TheISA::TLB type is still visible outside of the ISAs.
Specifically, the TlbEntry type is used in the generic PageTable which
lives in src/mem.

Change-Id: I51b68ee74411f9af778317eff222f9349d2ed575
Reviewed-on: https://gem5-review.googlesource.com/6921
Maintainer: Gabe Black <gabeblack@google.com>
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc
index 1e8231b..4d72104 100644
--- a/src/arch/alpha/ev5.cc
+++ b/src/arch/alpha/ev5.cc
@@ -43,6 +43,24 @@
 
 namespace AlphaISA {
 
+template<typename T>
+TLB *
+getITBPtr(T *tc)
+{
+    auto tlb = dynamic_cast<TLB *>(tc->getITBPtr());
+    assert(tlb);
+    return tlb;
+}
+
+template<typename T>
+TLB *
+getDTBPtr(T *tc)
+{
+    auto tlb = dynamic_cast<TLB *>(tc->getDTBPtr());
+    assert(tlb);
+    return tlb;
+}
+
 ////////////////////////////////////////////////////////////////////////
 //
 //  Machine dependent functions
@@ -161,7 +179,7 @@
 
       case IPR_DTB_PTE:
         {
-            TlbEntry &entry = tc->getDTBPtr()->index(1);
+            TlbEntry &entry = getDTBPtr(tc)->index(1);
 
             retval |= ((uint64_t)entry.ppn & ULL(0x7ffffff)) << 32;
             retval |= ((uint64_t)entry.xre & ULL(0xf)) << 8;
@@ -358,21 +376,21 @@
         // really a control write
         ipr[idx] = 0;
 
-        tc->getDTBPtr()->flushAll();
+        getDTBPtr(tc)->flushAll();
         break;
 
       case IPR_DTB_IAP:
         // really a control write
         ipr[idx] = 0;
 
-        tc->getDTBPtr()->flushProcesses();
+        getDTBPtr(tc)->flushProcesses();
         break;
 
       case IPR_DTB_IS:
         // really a control write
         ipr[idx] = val;
 
-        tc->getDTBPtr()->flushAddr(val, DTB_ASN_ASN(ipr[IPR_DTB_ASN]));
+        getDTBPtr(tc)->flushAddr(val, DTB_ASN_ASN(ipr[IPR_DTB_ASN]));
         break;
 
       case IPR_DTB_TAG: {
@@ -395,7 +413,7 @@
           entry.asn = DTB_ASN_ASN(ipr[IPR_DTB_ASN]);
 
           // insert new TAG/PTE value into data TLB
-          tc->getDTBPtr()->insert(val, entry);
+          getDTBPtr(tc)->insert(val, entry);
       }
         break;
 
@@ -419,7 +437,7 @@
           entry.asn = ITB_ASN_ASN(ipr[IPR_ITB_ASN]);
 
           // insert new TAG/PTE value into data TLB
-          tc->getITBPtr()->insert(ipr[IPR_ITB_TAG], entry);
+          getITBPtr(tc)->insert(ipr[IPR_ITB_TAG], entry);
       }
         break;
 
@@ -427,21 +445,21 @@
         // really a control write
         ipr[idx] = 0;
 
-        tc->getITBPtr()->flushAll();
+        getITBPtr(tc)->flushAll();
         break;
 
       case IPR_ITB_IAP:
         // really a control write
         ipr[idx] = 0;
 
-        tc->getITBPtr()->flushProcesses();
+        getITBPtr(tc)->flushProcesses();
         break;
 
       case IPR_ITB_IS:
         // really a control write
         ipr[idx] = val;
 
-        tc->getITBPtr()->flushAddr(val, ITB_ASN_ASN(ipr[IPR_ITB_ASN]));
+        getITBPtr(tc)->flushAddr(val, ITB_ASN_ASN(ipr[IPR_ITB_ASN]));
         break;
 
       default:
diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc
index 59d9500..4a829cd 100644
--- a/src/arch/alpha/faults.cc
+++ b/src/arch/alpha/faults.cc
@@ -202,7 +202,7 @@
         panic("Tried to execute unmapped address %#x.\n", pc);
     } else {
         VAddr vaddr(pc);
-        tc->getITBPtr()->insert(vaddr.page(), entry);
+        dynamic_cast<TLB *>(tc->getITBPtr())->insert(vaddr.page(), entry);
     }
 }
 
@@ -224,7 +224,7 @@
     if (!success) {
         panic("Tried to access unmapped address %#x.\n", (Addr)vaddr);
     } else {
-        tc->getDTBPtr()->insert(vaddr.page(), entry);
+        dynamic_cast<TLB *>(tc->getDTBPtr())->insert(vaddr.page(), entry);
     }
 }
 
diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc
index fcd2b51..f77c458 100644
--- a/src/arch/alpha/tlb.cc
+++ b/src/arch/alpha/tlb.cc
@@ -616,13 +616,6 @@
 }
 
 Fault
-TLB::translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode)
-{
-    panic("Not implemented\n");
-    return NoFault;
-}
-
-Fault
 TLB::finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const
 {
     return NoFault;
diff --git a/src/arch/alpha/tlb.hh b/src/arch/alpha/tlb.hh
index b9b6228..08166bc 100644
--- a/src/arch/alpha/tlb.hh
+++ b/src/arch/alpha/tlb.hh
@@ -141,14 +141,13 @@
     Fault translateInst(RequestPtr req, ThreadContext *tc);
 
   public:
-    Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
-    void translateTiming(RequestPtr req, ThreadContext *tc,
-                         Translation *translation, Mode mode);
-    /**
-     * translateFunctional stub function for future CheckerCPU support
-     */
-    Fault translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode);
-    Fault finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const;
+    Fault translateAtomic(
+            RequestPtr req, ThreadContext *tc, Mode mode) override;
+    void translateTiming(
+            RequestPtr req, ThreadContext *tc,
+            Translation *translation, Mode mode) override;
+    Fault finalizePhysical(
+            RequestPtr req, ThreadContext *tc, Mode mode) const override;
 };
 
 } // namespace AlphaISA
diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc
index 44e4ff3..7096889 100644
--- a/src/arch/arm/isa.cc
+++ b/src/arch/arm/isa.cc
@@ -39,9 +39,9 @@
  */
 
 #include "arch/arm/isa.hh"
-
 #include "arch/arm/pmu.hh"
 #include "arch/arm/system.hh"
+#include "arch/arm/tlb.hh"
 #include "cpu/base.hh"
 #include "cpu/checker/cpu.hh"
 #include "debug/Arm.hh"
@@ -821,6 +821,28 @@
     }
 }
 
+namespace {
+
+template<typename T>
+TLB *
+getITBPtr(T *tc)
+{
+    auto tlb = dynamic_cast<TLB *>(tc->getITBPtr());
+    assert(tlb);
+    return tlb;
+}
+
+template<typename T>
+TLB *
+getDTBPtr(T *tc)
+{
+    auto tlb = dynamic_cast<TLB *>(tc->getDTBPtr());
+    assert(tlb);
+    return tlb;
+}
+
+} // anonymous namespace
+
 void
 ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
 {
@@ -843,8 +865,8 @@
         int old_mode = old_cpsr.mode;
         CPSR cpsr = val;
         if (old_mode != cpsr.mode) {
-            tc->getITBPtr()->invalidateMiscReg();
-            tc->getDTBPtr()->invalidateMiscReg();
+            getITBPtr(tc)->invalidateMiscReg();
+            getDTBPtr(tc)->invalidateMiscReg();
         }
 
         DPRINTF(Arm, "Updating CPSR from %#x to %#x f:%d i:%d a:%d mode:%#x\n",
@@ -1088,8 +1110,8 @@
             }
             break;
           case MISCREG_SCR:
-            tc->getITBPtr()->invalidateMiscReg();
-            tc->getDTBPtr()->invalidateMiscReg();
+            getITBPtr(tc)->invalidateMiscReg();
+            getDTBPtr(tc)->invalidateMiscReg();
             break;
           case MISCREG_SCTLR:
             {
@@ -1101,8 +1123,8 @@
                 SCTLR new_sctlr = newVal;
                 new_sctlr.nmfi =  ((bool)sctlr.nmfi) && !haveVirtualization;
                 miscRegs[sctlr_idx] = (MiscReg)new_sctlr;
-                tc->getITBPtr()->invalidateMiscReg();
-                tc->getDTBPtr()->invalidateMiscReg();
+                getITBPtr(tc)->invalidateMiscReg();
+                getDTBPtr(tc)->invalidateMiscReg();
             }
           case MISCREG_MIDR:
           case MISCREG_ID_PFR0:
@@ -1148,17 +1170,16 @@
             sys = tc->getSystemPtr();
             for (x = 0; x < sys->numContexts(); x++) {
                 oc = sys->getThreadContext(x);
-                assert(oc->getITBPtr() && oc->getDTBPtr());
-                oc->getITBPtr()->flushAllSecurity(secure_lookup, target_el);
-                oc->getDTBPtr()->flushAllSecurity(secure_lookup, target_el);
+                getITBPtr(oc)->flushAllSecurity(secure_lookup, target_el);
+                getDTBPtr(oc)->flushAllSecurity(secure_lookup, target_el);
 
                 // If CheckerCPU is connected, need to notify it of a flush
                 CheckerCPU *checker = oc->getCheckerCpuPtr();
                 if (checker) {
-                    checker->getITBPtr()->flushAllSecurity(secure_lookup,
-                                                           target_el);
-                    checker->getDTBPtr()->flushAllSecurity(secure_lookup,
-                                                           target_el);
+                    getITBPtr(checker)->flushAllSecurity(secure_lookup,
+                                                         target_el);
+                    getDTBPtr(checker)->flushAllSecurity(secure_lookup,
+                                                         target_el);
                 }
             }
             return;
@@ -1168,7 +1189,7 @@
             target_el = 1; // el 0 and 1 are handled together
             scr = readMiscReg(MISCREG_SCR, tc);
             secure_lookup = haveSecurity && !scr.ns;
-            tc->getITBPtr()->flushAllSecurity(secure_lookup, target_el);
+            getITBPtr(tc)->flushAllSecurity(secure_lookup, target_el);
             return;
           // TLBI all entries, EL0&1, data side
           case MISCREG_DTLBIALL:
@@ -1176,7 +1197,7 @@
             target_el = 1; // el 0 and 1 are handled together
             scr = readMiscReg(MISCREG_SCR, tc);
             secure_lookup = haveSecurity && !scr.ns;
-            tc->getDTBPtr()->flushAllSecurity(secure_lookup, target_el);
+            getDTBPtr(tc)->flushAllSecurity(secure_lookup, target_el);
             return;
           // TLBI based on VA, EL0&1 inner sharable (ignored)
           case MISCREG_TLBIMVAIS:
@@ -1188,19 +1209,18 @@
             sys = tc->getSystemPtr();
             for (x = 0; x < sys->numContexts(); x++) {
                 oc = sys->getThreadContext(x);
-                assert(oc->getITBPtr() && oc->getDTBPtr());
-                oc->getITBPtr()->flushMvaAsid(mbits(newVal, 31, 12),
+                getITBPtr(oc)->flushMvaAsid(mbits(newVal, 31, 12),
                                               bits(newVal, 7,0),
                                               secure_lookup, target_el);
-                oc->getDTBPtr()->flushMvaAsid(mbits(newVal, 31, 12),
+                getDTBPtr(oc)->flushMvaAsid(mbits(newVal, 31, 12),
                                               bits(newVal, 7,0),
                                               secure_lookup, target_el);
 
                 CheckerCPU *checker = oc->getCheckerCpuPtr();
                 if (checker) {
-                    checker->getITBPtr()->flushMvaAsid(mbits(newVal, 31, 12),
+                    getITBPtr(checker)->flushMvaAsid(mbits(newVal, 31, 12),
                         bits(newVal, 7,0), secure_lookup, target_el);
-                    checker->getDTBPtr()->flushMvaAsid(mbits(newVal, 31, 12),
+                    getDTBPtr(checker)->flushMvaAsid(mbits(newVal, 31, 12),
                         bits(newVal, 7,0), secure_lookup, target_el);
                 }
             }
@@ -1215,16 +1235,15 @@
             sys = tc->getSystemPtr();
             for (x = 0; x < sys->numContexts(); x++) {
                 oc = sys->getThreadContext(x);
-                assert(oc->getITBPtr() && oc->getDTBPtr());
-                oc->getITBPtr()->flushAsid(bits(newVal, 7,0),
+                getITBPtr(oc)->flushAsid(bits(newVal, 7,0),
                     secure_lookup, target_el);
-                oc->getDTBPtr()->flushAsid(bits(newVal, 7,0),
+                getDTBPtr(oc)->flushAsid(bits(newVal, 7,0),
                     secure_lookup, target_el);
                 CheckerCPU *checker = oc->getCheckerCpuPtr();
                 if (checker) {
-                    checker->getITBPtr()->flushAsid(bits(newVal, 7,0),
+                    getITBPtr(checker)->flushAsid(bits(newVal, 7,0),
                         secure_lookup, target_el);
-                    checker->getDTBPtr()->flushAsid(bits(newVal, 7,0),
+                    getDTBPtr(checker)->flushAsid(bits(newVal, 7,0),
                         secure_lookup, target_el);
                 }
             }
@@ -1255,7 +1274,7 @@
             target_el = 1; // el 0 and 1 are handled together
             scr = readMiscReg(MISCREG_SCR, tc);
             secure_lookup = haveSecurity && !scr.ns;
-            tc->getITBPtr()->flushMvaAsid(mbits(newVal, 31, 12),
+            getITBPtr(tc)->flushMvaAsid(mbits(newVal, 31, 12),
                 bits(newVal, 7,0), secure_lookup, target_el);
             return;
           // TLBI by address and asid, EL0&1, data side only
@@ -1264,7 +1283,7 @@
             target_el = 1; // el 0 and 1 are handled together
             scr = readMiscReg(MISCREG_SCR, tc);
             secure_lookup = haveSecurity && !scr.ns;
-            tc->getDTBPtr()->flushMvaAsid(mbits(newVal, 31, 12),
+            getDTBPtr(tc)->flushMvaAsid(mbits(newVal, 31, 12),
                 bits(newVal, 7,0), secure_lookup, target_el);
             return;
           // TLBI by ASID, EL0&1, instrution side only
@@ -1273,7 +1292,7 @@
             target_el = 1; // el 0 and 1 are handled together
             scr = readMiscReg(MISCREG_SCR, tc);
             secure_lookup = haveSecurity && !scr.ns;
-            tc->getITBPtr()->flushAsid(bits(newVal, 7,0), secure_lookup,
+            getITBPtr(tc)->flushAsid(bits(newVal, 7,0), secure_lookup,
                                        target_el);
             return;
           // TLBI by ASID EL0&1 data size only
@@ -1282,7 +1301,7 @@
             target_el = 1; // el 0 and 1 are handled together
             scr = readMiscReg(MISCREG_SCR, tc);
             secure_lookup = haveSecurity && !scr.ns;
-            tc->getDTBPtr()->flushAsid(bits(newVal, 7,0), secure_lookup,
+            getDTBPtr(tc)->flushAsid(bits(newVal, 7,0), secure_lookup,
                                        target_el);
             return;
           // Invalidate entire Non-secure Hyp/Non-Hyp Unified TLB
@@ -1380,17 +1399,16 @@
             sys = tc->getSystemPtr();
             for (x = 0; x < sys->numContexts(); x++) {
                 oc = sys->getThreadContext(x);
-                assert(oc->getITBPtr() && oc->getDTBPtr());
                 asid = bits(newVal, 63, 48);
                 if (!haveLargeAsid64)
                     asid &= mask(8);
-                oc->getITBPtr()->flushAsid(asid, secure_lookup, target_el);
-                oc->getDTBPtr()->flushAsid(asid, secure_lookup, target_el);
+                getITBPtr(oc)->flushAsid(asid, secure_lookup, target_el);
+                getDTBPtr(oc)->flushAsid(asid, secure_lookup, target_el);
                 CheckerCPU *checker = oc->getCheckerCpuPtr();
                 if (checker) {
-                    checker->getITBPtr()->flushAsid(asid,
+                    getITBPtr(checker)->flushAsid(asid,
                         secure_lookup, target_el);
-                    checker->getDTBPtr()->flushAsid(asid,
+                    getDTBPtr(checker)->flushAsid(asid,
                         secure_lookup, target_el);
                 }
             }
@@ -1411,18 +1429,17 @@
             for (x = 0; x < sys->numContexts(); x++) {
                 // @todo: extra controls on TLBI broadcast?
                 oc = sys->getThreadContext(x);
-                assert(oc->getITBPtr() && oc->getDTBPtr());
                 Addr va = ((Addr) bits(newVal, 43, 0)) << 12;
-                oc->getITBPtr()->flushMva(va,
+                getITBPtr(oc)->flushMva(va,
                     secure_lookup, false, target_el);
-                oc->getDTBPtr()->flushMva(va,
+                getDTBPtr(oc)->flushMva(va,
                     secure_lookup, false, target_el);
 
                 CheckerCPU *checker = oc->getCheckerCpuPtr();
                 if (checker) {
-                    checker->getITBPtr()->flushMva(va,
+                    getITBPtr(checker)->flushMva(va,
                         secure_lookup, false, target_el);
-                    checker->getDTBPtr()->flushMva(va,
+                    getDTBPtr(checker)->flushMva(va,
                         secure_lookup, false, target_el);
                 }
             }
@@ -1439,18 +1456,17 @@
             sys = tc->getSystemPtr();
             for (x = 0; x < sys->numContexts(); x++) {
                 oc = sys->getThreadContext(x);
-                assert(oc->getITBPtr() && oc->getDTBPtr());
                 Addr ipa = ((Addr) bits(newVal, 35, 0)) << 12;
-                oc->getITBPtr()->flushIpaVmid(ipa,
+                getITBPtr(oc)->flushIpaVmid(ipa,
                     secure_lookup, false, target_el);
-                oc->getDTBPtr()->flushIpaVmid(ipa,
+                getDTBPtr(oc)->flushIpaVmid(ipa,
                     secure_lookup, false, target_el);
 
                 CheckerCPU *checker = oc->getCheckerCpuPtr();
                 if (checker) {
-                    checker->getITBPtr()->flushIpaVmid(ipa,
+                    getITBPtr(checker)->flushIpaVmid(ipa,
                         secure_lookup, false, target_el);
-                    checker->getDTBPtr()->flushIpaVmid(ipa,
+                    getDTBPtr(checker)->flushIpaVmid(ipa,
                         secure_lookup, false, target_el);
                 }
             }
@@ -1578,7 +1594,8 @@
               warn("Translating via MISCREG(%d) in functional mode! Fix Me!\n", misc_reg);
               Request req(0, val, 0, flags,  Request::funcMasterId,
                           tc->pcState().pc(), tc->contextId());
-              fault = tc->getDTBPtr()->translateFunctional(&req, tc, mode, tranType);
+              fault = getDTBPtr(tc)->translateFunctional(
+                      &req, tc, mode, tranType);
               TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
               HCR   hcr   = readMiscRegNoEffect(MISCREG_HCR);
 
@@ -1588,10 +1605,10 @@
                   if (haveLPAE && (ttbcr.eae || tranType & TLB::HypMode ||
                      ((tranType & TLB::S1S2NsTran) && hcr.vm) )) {
                       newVal = (paddr & mask(39, 12)) |
-                               (tc->getDTBPtr()->getAttr());
+                               (getDTBPtr(tc)->getAttr());
                   } else {
                       newVal = (paddr & 0xfffff000) |
-                               (tc->getDTBPtr()->getAttr());
+                               (getDTBPtr(tc)->getAttr());
                   }
                   DPRINTF(MiscRegs,
                           "MISCREG: Translated addr 0x%08x: PAR: 0x%08x\n",
@@ -1670,8 +1687,8 @@
             M5_FALLTHROUGH;
           case MISCREG_SCTLR_EL1:
             {
-                tc->getITBPtr()->invalidateMiscReg();
-                tc->getDTBPtr()->invalidateMiscReg();
+                getITBPtr(tc)->invalidateMiscReg();
+                getDTBPtr(tc)->invalidateMiscReg();
                 setMiscRegNoEffect(misc_reg, newVal);
             }
             M5_FALLTHROUGH;
@@ -1694,8 +1711,8 @@
           case MISCREG_TTBR1_EL1:
           case MISCREG_TTBR0_EL2:
           case MISCREG_TTBR0_EL3:
-            tc->getITBPtr()->invalidateMiscReg();
-            tc->getDTBPtr()->invalidateMiscReg();
+            getITBPtr(tc)->invalidateMiscReg();
+            getDTBPtr(tc)->invalidateMiscReg();
             break;
           case MISCREG_NZCV:
             {
@@ -1829,13 +1846,13 @@
                 req->setVirt(0, val, 0, flags,  Request::funcMasterId,
                                tc->pcState().pc());
                 req->setContext(tc->contextId());
-                fault = tc->getDTBPtr()->translateFunctional(req, tc, mode,
-                                                             tranType);
+                fault = getDTBPtr(tc)->translateFunctional(req, tc, mode,
+                                                           tranType);
 
                 MiscReg newVal;
                 if (fault == NoFault) {
                     Addr paddr = req->getPaddr();
-                    uint64_t attr = tc->getDTBPtr()->getAttr();
+                    uint64_t attr = getDTBPtr(tc)->getAttr();
                     uint64_t attr1 = attr >> 56;
                     if (!attr1 || attr1 ==0x44) {
                         attr |= 0x100;
@@ -1907,17 +1924,16 @@
     System *sys = tc->getSystemPtr();
     for (int x = 0; x < sys->numContexts(); x++) {
         ThreadContext *oc = sys->getThreadContext(x);
-        assert(oc->getITBPtr() && oc->getDTBPtr());
-        oc->getITBPtr()->flushMvaAsid(va, asid,
+        getITBPtr(oc)->flushMvaAsid(va, asid,
                                       secure_lookup, target_el);
-        oc->getDTBPtr()->flushMvaAsid(va, asid,
+        getDTBPtr(oc)->flushMvaAsid(va, asid,
                                       secure_lookup, target_el);
 
         CheckerCPU *checker = oc->getCheckerCpuPtr();
         if (checker) {
-            checker->getITBPtr()->flushMvaAsid(
+            getITBPtr(checker)->flushMvaAsid(
                 va, asid, secure_lookup, target_el);
-            checker->getDTBPtr()->flushMvaAsid(
+            getDTBPtr(checker)->flushMvaAsid(
                 va, asid, secure_lookup, target_el);
         }
     }
@@ -1929,16 +1945,15 @@
     System *sys = tc->getSystemPtr();
     for (int x = 0; x < sys->numContexts(); x++) {
         ThreadContext *oc = sys->getThreadContext(x);
-        assert(oc->getITBPtr() && oc->getDTBPtr());
-        oc->getITBPtr()->flushAllSecurity(secure_lookup, target_el);
-        oc->getDTBPtr()->flushAllSecurity(secure_lookup, target_el);
+        getITBPtr(oc)->flushAllSecurity(secure_lookup, target_el);
+        getDTBPtr(oc)->flushAllSecurity(secure_lookup, target_el);
 
         // If CheckerCPU is connected, need to notify it of a flush
         CheckerCPU *checker = oc->getCheckerCpuPtr();
         if (checker) {
-            checker->getITBPtr()->flushAllSecurity(secure_lookup,
+            getITBPtr(checker)->flushAllSecurity(secure_lookup,
                                                    target_el);
-            checker->getDTBPtr()->flushAllSecurity(secure_lookup,
+            getDTBPtr(checker)->flushAllSecurity(secure_lookup,
                                                    target_el);
         }
     }
@@ -1950,14 +1965,13 @@
     System *sys = tc->getSystemPtr();
     for (int x = 0; x < sys->numContexts(); x++) {
       ThreadContext *oc = sys->getThreadContext(x);
-      assert(oc->getITBPtr() && oc->getDTBPtr());
-      oc->getITBPtr()->flushAllNs(hyp, target_el);
-      oc->getDTBPtr()->flushAllNs(hyp, target_el);
+      getITBPtr(oc)->flushAllNs(hyp, target_el);
+      getDTBPtr(oc)->flushAllNs(hyp, target_el);
 
       CheckerCPU *checker = oc->getCheckerCpuPtr();
       if (checker) {
-          checker->getITBPtr()->flushAllNs(hyp, target_el);
-          checker->getDTBPtr()->flushAllNs(hyp, target_el);
+          getITBPtr(checker)->flushAllNs(hyp, target_el);
+          getDTBPtr(checker)->flushAllNs(hyp, target_el);
       }
     }
 }
@@ -1969,17 +1983,16 @@
     System *sys = tc->getSystemPtr();
     for (int x = 0; x < sys->numContexts(); x++) {
         ThreadContext *oc = sys->getThreadContext(x);
-        assert(oc->getITBPtr() && oc->getDTBPtr());
-        oc->getITBPtr()->flushMva(mbits(newVal, 31,12),
+        getITBPtr(oc)->flushMva(mbits(newVal, 31,12),
             secure_lookup, hyp, target_el);
-        oc->getDTBPtr()->flushMva(mbits(newVal, 31,12),
+        getDTBPtr(oc)->flushMva(mbits(newVal, 31,12),
             secure_lookup, hyp, target_el);
 
         CheckerCPU *checker = oc->getCheckerCpuPtr();
         if (checker) {
-            checker->getITBPtr()->flushMva(mbits(newVal, 31,12),
+            getITBPtr(checker)->flushMva(mbits(newVal, 31,12),
                 secure_lookup, hyp, target_el);
-            checker->getDTBPtr()->flushMva(mbits(newVal, 31,12),
+            getDTBPtr(checker)->flushMva(mbits(newVal, 31,12),
                 secure_lookup, hyp, target_el);
         }
     }
diff --git a/src/arch/arm/stage2_mmu.cc b/src/arch/arm/stage2_mmu.cc
index a2ae8cc..5c28d07 100755
--- a/src/arch/arm/stage2_mmu.cc
+++ b/src/arch/arm/stage2_mmu.cc
@@ -97,16 +97,15 @@
     return fault;
 }
 
-Fault
+void
 Stage2MMU::readDataTimed(ThreadContext *tc, Addr descAddr,
                          Stage2Translation *translation, int numBytes,
                          Request::Flags flags)
 {
-    Fault fault;
     // translate to physical address using the second stage MMU
-    translation->setVirt(descAddr, numBytes, flags | Request::PT_WALK, masterId);
-    fault = translation->translateTiming(tc);
-    return fault;
+    translation->setVirt(
+            descAddr, numBytes, flags | Request::PT_WALK, masterId);
+    translation->translateTiming(tc);
 }
 
 Stage2MMU::Stage2Translation::Stage2Translation(Stage2MMU &_parent,
diff --git a/src/arch/arm/stage2_mmu.hh b/src/arch/arm/stage2_mmu.hh
index 9543c74..b01b081 100755
--- a/src/arch/arm/stage2_mmu.hh
+++ b/src/arch/arm/stage2_mmu.hh
@@ -96,9 +96,9 @@
             req.setVirt(0, vaddr, size, flags, masterId, 0);
         }
 
-        Fault translateTiming(ThreadContext *tc)
+        void translateTiming(ThreadContext *tc)
         {
-            return (parent.stage2Tlb()->translateTiming(&req, tc, this, BaseTLB::Read));
+            parent.stage2Tlb()->translateTiming(&req, tc, this, BaseTLB::Read);
         }
     };
 
@@ -114,9 +114,9 @@
 
     Fault readDataUntimed(ThreadContext *tc, Addr oVAddr, Addr descAddr,
         uint8_t *data, int numBytes, Request::Flags flags, bool isFunctional);
-    Fault readDataTimed(ThreadContext *tc, Addr descAddr,
-                        Stage2Translation *translation, int numBytes,
-                        Request::Flags flags);
+    void readDataTimed(ThreadContext *tc, Addr descAddr,
+                       Stage2Translation *translation, int numBytes,
+                       Request::Flags flags);
 
     TLB* stage1Tlb() const { return _stage1Tlb; }
     TLB* stage2Tlb() const { return _stage2Tlb; }
diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc
index 63b67f5..88f6eae 100644
--- a/src/arch/arm/table_walker.cc
+++ b/src/arch/arm/table_walker.cc
@@ -1790,8 +1790,8 @@
         if (!currState->doingStage2) {
             statWalkServiceTime.sample(curTick() - currState->startTime);
             DPRINTF(TLBVerbose, "calling translateTiming again\n");
-            currState->fault = tlb->translateTiming(currState->req, currState->tc,
-                currState->transState, currState->mode);
+            tlb->translateTiming(currState->req, currState->tc,
+                                 currState->transState, currState->mode);
             statWalksShortTerminatedAtLevel[0]++;
         }
 
@@ -1835,8 +1835,8 @@
         if (!currState->doingStage2) {
             statWalkServiceTime.sample(curTick() - currState->startTime);
             DPRINTF(TLBVerbose, "calling translateTiming again\n");
-            currState->fault = tlb->translateTiming(currState->req,
-                currState->tc, currState->transState, currState->mode);
+            tlb->translateTiming(currState->req, currState->tc,
+                                 currState->transState, currState->mode);
             statWalksShortTerminatedAtLevel[1]++;
         }
     }
@@ -1915,9 +1915,8 @@
         if (!currState->doingStage2) {
             DPRINTF(TLBVerbose, "calling translateTiming again\n");
             statWalkServiceTime.sample(curTick() - currState->startTime);
-            currState->fault = tlb->translateTiming(currState->req, currState->tc,
-                                                    currState->transState,
-                                                    currState->mode);
+            tlb->translateTiming(currState->req, currState->tc,
+                                 currState->transState, currState->mode);
             statWalksLongTerminatedAtLevel[(unsigned) curr_lookup_level]++;
         }
 
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index de7ebf8..d3f44c3 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -1183,7 +1183,7 @@
     return fault;
 }
 
-Fault
+void
 TLB::translateTiming(RequestPtr req, ThreadContext *tc,
     Translation *translation, Mode mode, TLB::ArmTranslationType tranType)
 {
@@ -1191,12 +1191,13 @@
 
     if (directToStage2) {
         assert(stage2Tlb);
-        return stage2Tlb->translateTiming(req, tc, translation, mode, tranType);
+        stage2Tlb->translateTiming(req, tc, translation, mode, tranType);
+        return;
     }
 
     assert(translation);
 
-    return translateComplete(req, tc, translation, mode, tranType, isStage2);
+    translateComplete(req, tc, translation, mode, tranType, isStage2);
 }
 
 Fault
diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh
index f5849f3..7521e71 100644
--- a/src/arch/arm/tlb.hh
+++ b/src/arch/arm/tlb.hh
@@ -333,14 +333,27 @@
     Fault translateSe(RequestPtr req, ThreadContext *tc, Mode mode,
             Translation *translation, bool &delay, bool timing);
     Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode,
-            ArmTranslationType tranType = NormalTran);
-    Fault translateTiming(RequestPtr req, ThreadContext *tc,
+            ArmTranslationType tranType);
+    Fault
+    translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode) override
+    {
+        return translateAtomic(req, tc, mode, NormalTran);
+    }
+    void translateTiming(
+            RequestPtr req, ThreadContext *tc,
             Translation *translation, Mode mode,
-            ArmTranslationType tranType = NormalTran);
+            ArmTranslationType tranType);
+    void
+    translateTiming(RequestPtr req, ThreadContext *tc,
+                    Translation *translation, Mode mode) override
+    {
+        translateTiming(req, tc, translation, mode, NormalTran);
+    }
     Fault translateComplete(RequestPtr req, ThreadContext *tc,
             Translation *translation, Mode mode, ArmTranslationType tranType,
             bool callFromS2);
-    Fault finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const;
+    Fault finalizePhysical(
+            RequestPtr req, ThreadContext *tc, Mode mode) const override;
 
     void drainResume() override;
 
diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc
index a58ca81..b26564c 100644
--- a/src/arch/arm/utility.cc
+++ b/src/arch/arm/utility.cc
@@ -171,8 +171,8 @@
     dest->pcState(src->pcState());
 
     // Invalidate the tlb misc register cache
-    dest->getITBPtr()->invalidateMiscReg();
-    dest->getDTBPtr()->invalidateMiscReg();
+    dynamic_cast<TLB *>(dest->getITBPtr())->invalidateMiscReg();
+    dynamic_cast<TLB *>(dest->getDTBPtr())->invalidateMiscReg();
 }
 
 bool
diff --git a/src/arch/generic/tlb.hh b/src/arch/generic/tlb.hh
index aef52a1..e0becf7 100644
--- a/src/arch/generic/tlb.hh
+++ b/src/arch/generic/tlb.hh
@@ -60,32 +60,6 @@
   public:
     enum Mode { Read, Write, Execute };
 
-  public:
-    virtual void demapPage(Addr vaddr, uint64_t asn) = 0;
-
-    /**
-     * Remove all entries from the TLB
-     */
-    virtual void flushAll() = 0;
-
-    /**
-     * Take over from an old tlb context
-     */
-    virtual void takeOverFrom(BaseTLB *otlb) = 0;
-
-    /**
-     * Get the table walker master port if present. This is used for
-     * migrating port connections during a CPU takeOverFrom()
-     * call. For architectures that do not have a table walker, NULL
-     * is returned, hence the use of a pointer rather than a
-     * reference.
-     *
-     * @return A pointer to the walker master port or NULL if not present
-     */
-    virtual BaseMasterPort* getMasterPort() { return NULL; }
-
-    void memInvalidate() { flushAll(); }
-
     class Translation
     {
       public:
@@ -113,22 +87,20 @@
          */
         virtual bool squashed() const { return false; }
     };
-};
-
-class GenericTLB : public BaseTLB
-{
-  protected:
-    GenericTLB(const Params *p)
-        : BaseTLB(p)
-    {}
 
   public:
-    void demapPage(Addr vaddr, uint64_t asn) override;
+    virtual void demapPage(Addr vaddr, uint64_t asn) = 0;
 
-    Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
-    void translateTiming(RequestPtr req, ThreadContext *tc,
-                         Translation *translation, Mode mode);
-
+    virtual Fault translateAtomic(
+            RequestPtr req, ThreadContext *tc, Mode mode) = 0;
+    virtual void translateTiming(
+            RequestPtr req, ThreadContext *tc,
+            Translation *translation, Mode mode) = 0;
+    virtual Fault
+    translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode)
+    {
+        panic("Not implemented.\n");
+    }
 
     /**
      * Do post-translation physical address finalization.
@@ -144,7 +116,51 @@
      * @param mode Request type (read/write/execute).
      * @return A fault on failure, NoFault otherwise.
      */
-    Fault finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const;
+    virtual Fault finalizePhysical(
+            RequestPtr req, ThreadContext *tc, Mode mode) const = 0;
+
+    /**
+     * Remove all entries from the TLB
+     */
+    virtual void flushAll() = 0;
+
+    /**
+     * Take over from an old tlb context
+     */
+    virtual void takeOverFrom(BaseTLB *otlb) = 0;
+
+    /**
+     * Get the table walker master port if present. This is used for
+     * migrating port connections during a CPU takeOverFrom()
+     * call. For architectures that do not have a table walker, NULL
+     * is returned, hence the use of a pointer rather than a
+     * reference.
+     *
+     * @return A pointer to the walker master port or NULL if not present
+     */
+    virtual BaseMasterPort* getMasterPort() { return NULL; }
+
+    void memInvalidate() { flushAll(); }
+};
+
+class GenericTLB : public BaseTLB
+{
+  protected:
+    GenericTLB(const Params *p)
+        : BaseTLB(p)
+    {}
+
+  public:
+    void demapPage(Addr vaddr, uint64_t asn) override;
+
+    Fault translateAtomic(
+        RequestPtr req, ThreadContext *tc, Mode mode) override;
+    void translateTiming(
+        RequestPtr req, ThreadContext *tc,
+        Translation *translation, Mode mode) override;
+
+    Fault finalizePhysical(
+        RequestPtr req, ThreadContext *tc, Mode mode) const override;
 };
 
 #endif // __ARCH_GENERIC_TLB_HH__
diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa
index a349f1a..9a05982 100644
--- a/src/arch/mips/isa/decoder.isa
+++ b/src/arch/mips/isa/decoder.isa
@@ -737,7 +737,8 @@
                 format CP0TLB {
                     0x01: tlbr({{
                         MipsISA::PTE *PTEntry =
-                            xc->tcBase()->getITBPtr()->
+                            dynamic_cast<MipsISA::TLB *>(
+                                xc->tcBase()->getITBPtr())->
                                 getEntry(Index & 0x7FFFFFFF);
                         if (PTEntry == NULL) {
                             fatal("Invalid PTE Entry received on "
@@ -817,7 +818,8 @@
                         newEntry.OffsetMask =
                             (1 << newEntry.AddrShiftAmount) - 1;
 
-                        MipsISA::TLB *Ptr = xc->tcBase()->getITBPtr();
+                        auto ptr = dynamic_cast<MipsISA::TLB *>(
+                            xc->tcBase()->getITBPtr());
                         Config3Reg config3 = Config3;
                         PageGrainReg pageGrain = PageGrain;
                         int SP = 0;
@@ -825,7 +827,7 @@
                             bits(pageGrain, pageGrain.esp) == 1) {
                             SP = 1;
                         }
-                        Ptr->insertAt(newEntry, Index & 0x7FFFFFFF, SP);
+                        ptr->insertAt(newEntry, Index & 0x7FFFFFFF, SP);
                     }});
                     0x06: tlbwr({{
                         //Create PTE
@@ -882,7 +884,8 @@
                         newEntry.OffsetMask =
                             (1 << newEntry.AddrShiftAmount) - 1;
 
-                        MipsISA::TLB *Ptr = xc->tcBase()->getITBPtr();
+                        auto ptr = dynamic_cast<MipsISA::TLB *>(
+                            xc->tcBase()->getITBPtr());
                         Config3Reg config3 = Config3;
                         PageGrainReg pageGrain = PageGrain;
                         int SP = 0;
@@ -890,7 +893,7 @@
                             bits(pageGrain, pageGrain.esp) == 1) {
                             SP = 1;
                         }
-                        Ptr->insertAt(newEntry, Random, SP);
+                        ptr->insertAt(newEntry, Random, SP);
                     }});
 
                     0x08: tlbp({{
@@ -905,8 +908,9 @@
                             // Mask off lower 2 bits
                             vpn = ((EntryHi >> 11) & 0xFFFFFFFC);
                         }
-                        tlbIndex = xc->tcBase()->getITBPtr()->
-                                   probeEntry(vpn, entryHi.asid);
+                        tlbIndex = dynamic_cast<MipsISA::TLB *>(
+                            xc->tcBase()->getITBPtr())->
+                            probeEntry(vpn, entryHi.asid);
                         // Check TLB for entry matching EntryHi
                         if (tlbIndex != -1) {
                             Index = tlbIndex;
diff --git a/src/arch/mips/tlb.cc b/src/arch/mips/tlb.cc
index 87a4594..a18149d 100644
--- a/src/arch/mips/tlb.cc
+++ b/src/arch/mips/tlb.cc
@@ -329,13 +329,6 @@
 }
 
 Fault
-TLB::translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode)
-{
-    panic("Not implemented\n");
-    return NoFault;
-}
-
-Fault
 TLB::finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const
 {
     return NoFault;
diff --git a/src/arch/mips/tlb.hh b/src/arch/mips/tlb.hh
index af91831..626812a 100644
--- a/src/arch/mips/tlb.hh
+++ b/src/arch/mips/tlb.hh
@@ -112,15 +112,13 @@
 
     void regStats() override;
 
-    Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
-    void translateTiming(RequestPtr req, ThreadContext *tc,
-            Translation *translation, Mode mode);
-
-    /** Function stub for CheckerCPU compilation issues. MIPS does not
-     *  support the Checker model at the moment.
-     */
-    Fault translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode);
-    Fault finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const;
+    Fault translateAtomic(
+            RequestPtr req, ThreadContext *tc, Mode mode) override;
+    void translateTiming(
+            RequestPtr req, ThreadContext *tc,
+            Translation *translation, Mode mode) override;
+    Fault finalizePhysical(
+            RequestPtr req, ThreadContext *tc, Mode mode) const override;
 
   private:
     Fault translateInst(RequestPtr req, ThreadContext *tc);
diff --git a/src/arch/power/tlb.cc b/src/arch/power/tlb.cc
index 4172778..ff2f94f 100644
--- a/src/arch/power/tlb.cc
+++ b/src/arch/power/tlb.cc
@@ -330,13 +330,6 @@
 }
 
 Fault
-TLB::translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode)
-{
-    panic("Not implemented\n");
-    return NoFault;
-}
-
-Fault
 TLB::finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const
 {
     return NoFault;
diff --git a/src/arch/power/tlb.hh b/src/arch/power/tlb.hh
index de03da0..ca82d0b 100644
--- a/src/arch/power/tlb.hh
+++ b/src/arch/power/tlb.hh
@@ -162,14 +162,13 @@
     static Fault checkCacheability(RequestPtr &req);
     Fault translateInst(RequestPtr req, ThreadContext *tc);
     Fault translateData(RequestPtr req, ThreadContext *tc, bool write);
-    Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
-    void translateTiming(RequestPtr req, ThreadContext *tc,
-                         Translation *translation, Mode mode);
-    /** Stub function for CheckerCPU compilation support.  Power ISA not
-     *  supported by Checker at the moment
-     */
-    Fault translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode);
-    Fault finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const;
+    Fault translateAtomic(
+            RequestPtr req, ThreadContext *tc, Mode mode) override;
+    void translateTiming(
+            RequestPtr req, ThreadContext *tc,
+            Translation *translation, Mode mode) override;
+    Fault finalizePhysical(
+            RequestPtr req, ThreadContext *tc, Mode mode) const override;
 
     // Checkpointing
     void serialize(CheckpointOut &cp) const override;
diff --git a/src/arch/riscv/tlb.cc b/src/arch/riscv/tlb.cc
index c47260e..0c5962e 100644
--- a/src/arch/riscv/tlb.cc
+++ b/src/arch/riscv/tlb.cc
@@ -341,13 +341,6 @@
 }
 
 Fault
-TLB::translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode)
-{
-    panic("Not implemented\n");
-    return NoFault;
-}
-
-Fault
 TLB::finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const
 {
     return NoFault;
diff --git a/src/arch/riscv/tlb.hh b/src/arch/riscv/tlb.hh
index 92d66f1..ce63fd3 100644
--- a/src/arch/riscv/tlb.hh
+++ b/src/arch/riscv/tlb.hh
@@ -111,15 +111,13 @@
 
     void regStats() override;
 
-    Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
-    void translateTiming(RequestPtr req, ThreadContext *tc,
-            Translation *translation, Mode mode);
-
-    /** Function stub for CheckerCPU compilation issues. RISC-V does not
-     *  support the Checker model at the moment.
-     */
-    Fault translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode);
-    Fault finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const;
+    Fault translateAtomic(
+            RequestPtr req, ThreadContext *tc, Mode mode) override;
+    void translateTiming(
+            RequestPtr req, ThreadContext *tc,
+            Translation *translation, Mode mode) override;
+    Fault finalizePhysical(
+            RequestPtr req, ThreadContext *tc, Mode mode) const override;
 
   private:
     Fault translateInst(RequestPtr req, ThreadContext *tc);
diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc
index 13e9c19..5466115 100644
--- a/src/arch/sparc/faults.cc
+++ b/src/arch/sparc/faults.cc
@@ -669,8 +669,8 @@
         // false for syscall emulation mode regardless of whether the
         // address is real in preceding code. Not sure sure that this is
         // correct, but also not sure if it matters at all.
-        tc->getITBPtr()->insert(alignedvaddr, partition_id, context_id,
-                                false, entry.pte);
+        dynamic_cast<TLB *>(tc->getITBPtr())->
+            insert(alignedvaddr, partition_id, context_id, false, entry.pte);
     }
 }
 
@@ -757,8 +757,8 @@
         // false for syscall emulation mode regardless of whether the
         // address is real in preceding code. Not sure sure that this is
         // correct, but also not sure if it matters at all.
-        tc->getDTBPtr()->insert(alignedvaddr, partition_id, context_id,
-                                false, entry.pte);
+        dynamic_cast<TLB *>(tc->getDTBPtr())->
+            insert(alignedvaddr, partition_id, context_id, false, entry.pte);
     }
 }
 
diff --git a/src/arch/sparc/mmapped_ipr.hh b/src/arch/sparc/mmapped_ipr.hh
index e7d27ee..35e4d89 100644
--- a/src/arch/sparc/mmapped_ipr.hh
+++ b/src/arch/sparc/mmapped_ipr.hh
@@ -51,7 +51,7 @@
     if (GenericISA::isGenericIprAccess(pkt))
         return GenericISA::handleGenericIprRead(xc, pkt);
     else
-        return xc->getDTBPtr()->doMmuRegRead(xc, pkt);
+        return dynamic_cast<TLB *>(xc->getDTBPtr())->doMmuRegRead(xc, pkt);
 }
 
 inline Cycles
@@ -60,7 +60,7 @@
     if (GenericISA::isGenericIprAccess(pkt))
         return GenericISA::handleGenericIprWrite(xc, pkt);
     else
-        return xc->getDTBPtr()->doMmuRegWrite(xc, pkt);
+        return dynamic_cast<TLB *>(xc->getDTBPtr())->doMmuRegWrite(xc, pkt);
 }
 
 
diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc
index 51eb83a..997bfe9 100644
--- a/src/arch/sparc/tlb.cc
+++ b/src/arch/sparc/tlb.cc
@@ -849,13 +849,6 @@
 }
 
 Fault
-TLB::translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode)
-{
-    panic("Not implemented\n");
-    return NoFault;
-}
-
-Fault
 TLB::finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const
 {
     return NoFault;
@@ -871,7 +864,7 @@
     DPRINTF(IPR, "Memory Mapped IPR Read: asi=%#X a=%#x\n",
          (uint32_t)pkt->req->getArchFlags(), pkt->getAddr());
 
-    TLB *itb = tc->getITBPtr();
+    TLB *itb = dynamic_cast<TLB *>(tc->getITBPtr());
 
     switch (asi) {
       case ASI_LSU_CONTROL_REG:
@@ -1067,7 +1060,7 @@
     DPRINTF(IPR, "Memory Mapped IPR Write: asi=%#X a=%#x d=%#X\n",
          (uint32_t)asi, va, data);
 
-    TLB *itb = tc->getITBPtr();
+    TLB *itb = dynamic_cast<TLB *>(tc->getITBPtr());
 
     switch (asi) {
       case ASI_LSU_CONTROL_REG:
@@ -1171,8 +1164,8 @@
         real_insert = bits(va, 9,9);
         pte.populate(data, bits(va,10,10) ? PageTableEntry::sun4v :
                 PageTableEntry::sun4u);
-        tc->getITBPtr()->insert(va_insert, part_insert, ct_insert, real_insert,
-                pte, entry_insert);
+        itb->insert(va_insert, part_insert, ct_insert, real_insert,
+                    pte, entry_insert);
         break;
       case ASI_DTLB_DATA_ACCESS_REG:
         entry_insert = bits(va, 8,3);
@@ -1209,15 +1202,14 @@
         switch (bits(va,7,6)) {
           case 0: // demap page
             if (!ignore)
-                tc->getITBPtr()->demapPage(mbits(va,63,13), part_id,
-                        bits(va,9,9), ctx_id);
+                itb->demapPage(mbits(va,63,13), part_id, bits(va,9,9), ctx_id);
             break;
           case 1: // demap context
             if (!ignore)
-                tc->getITBPtr()->demapContext(part_id, ctx_id);
+                itb->demapContext(part_id, ctx_id);
             break;
           case 2:
-            tc->getITBPtr()->demapAll(part_id);
+            itb->demapAll(part_id);
             break;
           default:
             panic("Invalid type for IMMU demap\n");
@@ -1303,7 +1295,7 @@
 TLB::GetTsbPtr(ThreadContext *tc, Addr addr, int ctx, Addr *ptrs)
 {
     uint64_t tag_access = mbits(addr,63,13) | mbits(ctx,12,0);
-    TLB * itb = tc->getITBPtr();
+    TLB *itb = dynamic_cast<TLB *>(tc->getITBPtr());
     ptrs[0] = MakeTsbPtr(Ps0, tag_access,
                 c0_tsb_ps0,
                 c0_config,
diff --git a/src/arch/sparc/tlb.hh b/src/arch/sparc/tlb.hh
index 12d5ef7..7437ec3 100644
--- a/src/arch/sparc/tlb.hh
+++ b/src/arch/sparc/tlb.hh
@@ -163,14 +163,13 @@
 
     void dumpAll();
 
-    Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
-    void translateTiming(RequestPtr req, ThreadContext *tc,
-            Translation *translation, Mode mode);
-    /** Stub function for compilation support with CheckerCPU. SPARC ISA
-     *  does not support the Checker model at the moment
-     */
-    Fault translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode);
-    Fault finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const;
+    Fault translateAtomic(
+            RequestPtr req, ThreadContext *tc, Mode mode) override;
+    void translateTiming(
+            RequestPtr req, ThreadContext *tc,
+            Translation *translation, Mode mode) override;
+    Fault finalizePhysical(
+            RequestPtr req, ThreadContext *tc, Mode mode) const override;
     Cycles doMmuRegRead(ThreadContext *tc, Packet *pkt);
     Cycles doMmuRegWrite(ThreadContext *tc, Packet *pkt);
     void GetTsbPtr(ThreadContext *tc, Addr addr, int ctx, Addr *ptrs);
diff --git a/src/arch/sparc/vtophys.cc b/src/arch/sparc/vtophys.cc
index 6ba62eb..88f1c4a 100644
--- a/src/arch/sparc/vtophys.cc
+++ b/src/arch/sparc/vtophys.cc
@@ -83,8 +83,8 @@
     // int sec_context = bits(tlbdata,63,48);
 
     PortProxy &mem = tc->getPhysProxy();
-    TLB* itb = tc->getITBPtr();
-    TLB* dtb = tc->getDTBPtr();
+    TLB* itb = dynamic_cast<TLB *>(tc->getITBPtr());
+    TLB* dtb = dynamic_cast<TLB *>(tc->getDTBPtr());
     TlbEntry* tbe;
     PageTableEntry pte;
     Addr tsbs[4];
diff --git a/src/arch/x86/isa.cc b/src/arch/x86/isa.cc
index f092f44..28c50f3 100644
--- a/src/arch/x86/isa.cc
+++ b/src/arch/x86/isa.cc
@@ -216,8 +216,8 @@
                 }
             }
             if (toggled.pg) {
-                tc->getITBPtr()->flushAll();
-                tc->getDTBPtr()->flushAll();
+                dynamic_cast<TLB *>(tc->getITBPtr())->flushAll();
+                dynamic_cast<TLB *>(tc->getDTBPtr())->flushAll();
             }
             //This must always be 1.
             newCR0.et = 1;
@@ -233,15 +233,15 @@
       case MISCREG_CR2:
         break;
       case MISCREG_CR3:
-        tc->getITBPtr()->flushNonGlobal();
-        tc->getDTBPtr()->flushNonGlobal();
+        dynamic_cast<TLB *>(tc->getITBPtr())->flushNonGlobal();
+        dynamic_cast<TLB *>(tc->getDTBPtr())->flushNonGlobal();
         break;
       case MISCREG_CR4:
         {
             CR4 toggled = regVal[miscReg] ^ val;
             if (toggled.pae || toggled.pse || toggled.pge) {
-                tc->getITBPtr()->flushAll();
-                tc->getDTBPtr()->flushAll();
+                dynamic_cast<TLB *>(tc->getITBPtr())->flushAll();
+                dynamic_cast<TLB *>(tc->getDTBPtr())->flushAll();
             }
         }
         break;
diff --git a/src/arch/x86/remote_gdb.cc b/src/arch/x86/remote_gdb.cc
index 7961397..a6fdabd 100644
--- a/src/arch/x86/remote_gdb.cc
+++ b/src/arch/x86/remote_gdb.cc
@@ -72,7 +72,8 @@
 RemoteGDB::acc(Addr va, size_t len)
 {
     if (FullSystem) {
-        Walker *walker = context->getDTBPtr()->getWalker();
+        Walker *walker = dynamic_cast<TLB *>(
+            context->getDTBPtr())->getWalker();
         unsigned logBytes;
         Fault fault = walker->startFunctional(context, va, logBytes,
                                               BaseTLB::Read);
diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc
index e954c9c..0b1df9e 100644
--- a/src/arch/x86/tlb.cc
+++ b/src/arch/x86/tlb.cc
@@ -440,13 +440,6 @@
         translation->finish(fault, req, tc, mode);
 }
 
-Fault
-TLB::translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode)
-{
-    panic("Not implemented\n");
-    return NoFault;
-}
-
 Walker *
 TLB::getWalker()
 {
diff --git a/src/arch/x86/tlb.hh b/src/arch/x86/tlb.hh
index d036b74..c3dc83b 100644
--- a/src/arch/x86/tlb.hh
+++ b/src/arch/x86/tlb.hh
@@ -122,13 +122,11 @@
             return ++lruSeq;
         }
 
-        Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
-        void translateTiming(RequestPtr req, ThreadContext *tc,
-                Translation *translation, Mode mode);
-        /** Stub function for compilation support of CheckerCPU. x86 ISA does
-         *  not support Checker model at the moment
-         */
-        Fault translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode);
+        Fault translateAtomic(
+            RequestPtr req, ThreadContext *tc, Mode mode) override;
+        void translateTiming(
+            RequestPtr req, ThreadContext *tc,
+            Translation *translation, Mode mode) override;
 
         /**
          * Do post-translation physical address finalization.
@@ -144,7 +142,7 @@
          * @return A fault on failure, NoFault otherwise.
          */
         Fault finalizePhysical(RequestPtr req, ThreadContext *tc,
-                               Mode mode) const;
+                               Mode mode) const override;
 
         TlbEntry * insert(Addr vpn, TlbEntry &entry);
 
diff --git a/src/arch/x86/vtophys.cc b/src/arch/x86/vtophys.cc
index 9b76d89..d0287f2 100644
--- a/src/arch/x86/vtophys.cc
+++ b/src/arch/x86/vtophys.cc
@@ -60,7 +60,7 @@
     Addr
     vtophys(ThreadContext *tc, Addr vaddr)
     {
-        Walker *walker = tc->getDTBPtr()->getWalker();
+        Walker *walker = dynamic_cast<TLB *>(tc->getDTBPtr())->getWalker();
         unsigned logBytes;
         Addr addr = vaddr;
         Fault fault = walker->startFunctional(
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index 2c3ca08..4fd804b 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -51,7 +51,7 @@
 #include <sstream>
 #include <string>
 
-#include "arch/tlb.hh"
+#include "arch/generic/tlb.hh"
 #include "base/cprintf.hh"
 #include "base/loader/symtab.hh"
 #include "base/logging.hh"
@@ -313,7 +313,7 @@
 }
 
 void
-BaseCPU::mwaitAtomic(ThreadID tid, ThreadContext *tc, TheISA::TLB *dtb)
+BaseCPU::mwaitAtomic(ThreadID tid, ThreadContext *tc, BaseTLB *dtb)
 {
     assert(tid < numThreads);
     AddressMonitor &monitor = addressMonitor[tid];
diff --git a/src/cpu/base.hh b/src/cpu/base.hh
index 52598fd..8673d23 100644
--- a/src/cpu/base.hh
+++ b/src/cpu/base.hh
@@ -626,7 +626,7 @@
   public:
     void armMonitor(ThreadID tid, Addr address);
     bool mwait(ThreadID tid, PacketPtr pkt);
-    void mwaitAtomic(ThreadID tid, ThreadContext *tc, TheISA::TLB *dtb);
+    void mwaitAtomic(ThreadID tid, ThreadContext *tc, BaseTLB *dtb);
     AddressMonitor *getCpuAddrMonitor(ThreadID tid)
     {
         assert(tid < numThreads);
diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh
index 213106b..b1a4574 100644
--- a/src/cpu/checker/cpu.hh
+++ b/src/cpu/checker/cpu.hh
@@ -62,12 +62,7 @@
 #include "params/CheckerCPU.hh"
 #include "sim/eventq.hh"
 
-// forward declarations
-namespace TheISA
-{
-    class TLB;
-}
-
+class BaseTLB;
 template <class>
 class BaseDynInst;
 class ThreadContext;
@@ -140,8 +135,8 @@
 
     ThreadContext *tc;
 
-    TheISA::TLB *itb;
-    TheISA::TLB *dtb;
+    BaseTLB *itb;
+    BaseTLB *dtb;
 
     Addr dbg_vtophys(Addr addr);
 
@@ -166,8 +161,8 @@
     // Primary thread being run.
     SimpleThread *thread;
 
-    TheISA::TLB* getITBPtr() { return itb; }
-    TheISA::TLB* getDTBPtr() { return dtb; }
+    BaseTLB* getITBPtr() { return itb; }
+    BaseTLB* getDTBPtr() { return dtb; }
 
     virtual Counter totalInsts() const override
     {
diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh
index 5208932..975bd9f 100644
--- a/src/cpu/checker/thread_context.hh
+++ b/src/cpu/checker/thread_context.hh
@@ -112,9 +112,9 @@
         actualTC->setThreadId(id);
     }
 
-    TheISA::TLB *getITBPtr() { return actualTC->getITBPtr(); }
+    BaseTLB *getITBPtr() { return actualTC->getITBPtr(); }
 
-    TheISA::TLB *getDTBPtr() { return actualTC->getDTBPtr(); }
+    BaseTLB *getDTBPtr() { return actualTC->getDTBPtr(); }
 
     CheckerCPU *getCheckerCpuPtr()
     {
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index 28ccd15..10af087 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -123,8 +123,8 @@
         SwitchedOut
     };
 
-    TheISA::TLB * itb;
-    TheISA::TLB * dtb;
+    BaseTLB *itb;
+    BaseTLB *dtb;
 
     /** Overall CPU status. */
     Status _status;
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index 0cf8a47..6cca77a 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -51,8 +51,8 @@
 #include <map>
 #include <queue>
 
+#include "arch/generic/tlb.hh"
 #include "arch/isa_traits.hh"
-#include "arch/tlb.hh"
 #include "arch/utility.hh"
 #include "arch/vtophys.hh"
 #include "base/random.hh"
diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh
index ac4ceed..2256a8a 100755
--- a/src/cpu/o3/thread_context.hh
+++ b/src/cpu/o3/thread_context.hh
@@ -79,10 +79,10 @@
     O3ThreadState<Impl> *thread;
 
     /** Returns a pointer to the ITB. */
-    TheISA::TLB *getITBPtr() { return cpu->itb; }
+    BaseTLB *getITBPtr() { return cpu->itb; }
 
     /** Returns a pointer to the DTB. */
-    TheISA::TLB *getDTBPtr() { return cpu->dtb; }
+    BaseTLB *getDTBPtr() { return cpu->dtb; }
 
     CheckerCPU *getCheckerCpuPtr() { return NULL; }
 
diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index 1f12afb..36a2cb0 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -45,7 +45,6 @@
 
 #include "arch/kernel_stats.hh"
 #include "arch/stacktrace.hh"
-#include "arch/tlb.hh"
 #include "arch/utility.hh"
 #include "arch/vtophys.hh"
 #include "base/cp_annotate.hh"
diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc
index c775983..f86aced 100644
--- a/src/cpu/simple_thread.cc
+++ b/src/cpu/simple_thread.cc
@@ -62,8 +62,8 @@
 
 // constructor
 SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
-                           Process *_process, TheISA::TLB *_itb,
-                           TheISA::TLB *_dtb, TheISA::ISA *_isa)
+                           Process *_process, BaseTLB *_itb,
+                           BaseTLB *_dtb, TheISA::ISA *_isa)
     : ThreadState(_cpu, _thread_num, _process), isa(_isa),
       predicate(false), system(_sys),
       itb(_itb), dtb(_dtb)
@@ -74,7 +74,7 @@
 }
 
 SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
-                           TheISA::TLB *_itb, TheISA::TLB *_dtb,
+                           BaseTLB *_itb, BaseTLB *_dtb,
                            TheISA::ISA *_isa, bool use_kernel_stats)
     : ThreadState(_cpu, _thread_num, NULL), isa(_isa), system(_sys), itb(_itb),
       dtb(_dtb)
diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh
index 4ea8b91..3c64082 100644
--- a/src/cpu/simple_thread.hh
+++ b/src/cpu/simple_thread.hh
@@ -46,10 +46,10 @@
 #define __CPU_SIMPLE_THREAD_HH__
 
 #include "arch/decoder.hh"
+#include "arch/generic/tlb.hh"
 #include "arch/isa.hh"
 #include "arch/isa_traits.hh"
 #include "arch/registers.hh"
-#include "arch/tlb.hh"
 #include "arch/types.hh"
 #include "base/types.hh"
 #include "config/the_isa.hh"
@@ -135,19 +135,19 @@
 
     System *system;
 
-    TheISA::TLB *itb;
-    TheISA::TLB *dtb;
+    BaseTLB *itb;
+    BaseTLB *dtb;
 
     TheISA::Decoder decoder;
 
     // constructor: initialize SimpleThread from given process structure
     // FS
     SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system,
-                 TheISA::TLB *_itb, TheISA::TLB *_dtb, TheISA::ISA *_isa,
+                 BaseTLB *_itb, BaseTLB *_dtb, TheISA::ISA *_isa,
                  bool use_kernel_stats = true);
     // SE
     SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system,
-                 Process *_process, TheISA::TLB *_itb, TheISA::TLB *_dtb,
+                 Process *_process, BaseTLB *_itb, BaseTLB *_dtb,
                  TheISA::ISA *_isa);
 
     virtual ~SimpleThread();
@@ -201,9 +201,9 @@
 
     BaseCPU *getCpuPtr() { return baseCpu; }
 
-    TheISA::TLB *getITBPtr() { return itb; }
+    BaseTLB *getITBPtr() { return itb; }
 
-    TheISA::TLB *getDTBPtr() { return dtb; }
+    BaseTLB *getDTBPtr() { return dtb; }
 
     CheckerCPU *getCheckerCpuPtr() { return NULL; }
 
diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh
index 66b2f75..1e30649 100644
--- a/src/cpu/thread_context.hh
+++ b/src/cpu/thread_context.hh
@@ -58,9 +58,9 @@
 namespace TheISA
 {
     class Decoder;
-    class TLB;
 }
 class BaseCPU;
+class BaseTLB;
 class CheckerCPU;
 class Checkpoint;
 class EndQuiesceEvent;
@@ -136,9 +136,9 @@
 
     virtual void setContextId(int id) = 0;
 
-    virtual TheISA::TLB *getITBPtr() = 0;
+    virtual BaseTLB *getITBPtr() = 0;
 
-    virtual TheISA::TLB *getDTBPtr() = 0;
+    virtual BaseTLB *getDTBPtr() = 0;
 
     virtual CheckerCPU *getCheckerCpuPtr() = 0;
 
@@ -394,9 +394,9 @@
 
     void setContextId(int id) { actualTC->setContextId(id); }
 
-    TheISA::TLB *getITBPtr() { return actualTC->getITBPtr(); }
+    BaseTLB *getITBPtr() { return actualTC->getITBPtr(); }
 
-    TheISA::TLB *getDTBPtr() { return actualTC->getDTBPtr(); }
+    BaseTLB *getDTBPtr() { return actualTC->getDTBPtr(); }
 
     CheckerCPU *getCheckerCpuPtr() { return actualTC->getCheckerCpuPtr(); }
 
diff --git a/src/mem/multi_level_page_table.hh b/src/mem/multi_level_page_table.hh
index a69d6ce..402c371 100644
--- a/src/mem/multi_level_page_table.hh
+++ b/src/mem/multi_level_page_table.hh
@@ -38,7 +38,6 @@
 
 #include <string>
 
-#include "arch/tlb.hh"
 #include "base/types.hh"
 #include "config/the_isa.hh"
 #include "mem/page_table.hh"
diff --git a/src/mem/multi_level_page_table_impl.hh b/src/mem/multi_level_page_table_impl.hh
index 07ac924..7cd32db 100644
--- a/src/mem/multi_level_page_table_impl.hh
+++ b/src/mem/multi_level_page_table_impl.hh
@@ -35,7 +35,6 @@
 #include <string>
 
 #include "arch/isa_traits.hh"
-#include "arch/tlb.hh"
 #include "base/trace.hh"
 #include "config/the_isa.hh"
 #include "debug/MMU.hh"