SPARC: Move tlb state into the tlb.
authorGabe Black <gblack@eecs.umich.edu>
Mon, 13 Aug 2007 23:06:50 +0000 (16:06 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Mon, 13 Aug 2007 23:06:50 +0000 (16:06 -0700)
Each "strand" may need to have a private copy of this state, but I couldn't
find anywhere in the spec that said that after looking briefly.
This prevents writes to the thread context in o3 which was causing the
pipeline to be flushed and stopping any forward progress. The other ASI
accessible state will probably need to be accessed differently if/when we get
O3 full system up and running.

--HG--
extra : convert_revision : fa7fba812d7f76564ef4a23818e60f536710d557

src/arch/sparc/miscregfile.cc
src/arch/sparc/miscregfile.hh
src/arch/sparc/regfile.cc
src/arch/sparc/tlb.cc
src/arch/sparc/tlb.hh

index 0300694cceae3fa53c9760f089297f1f8d391475..7b9c734332c90efb3f08affb63cd70bf48a2803b 100644 (file)
@@ -54,11 +54,7 @@ string SparcISA::getMiscRegName(RegIndex index)
          "wstate",*/ "gl",
          "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
          "hstick_cmpr",
-         "fsr", "prictx", "secctx", "partId", "lsuCtrlReg", "itbTsbC0Ps0",
-         "itbTsbC0Ps1", "iTlbC0Cnfg", "itbTsbCXPs0", "itbTsbCXPs1",
-         "iTlbCXCnfg","iTlbSfsr", "iTlbTagAcs", "dtbTsbC0Ps0",
-         "dtbTsbC0Ps1", "dTlbC0Cnfg", "dtbTsbCXPs0", "dtbTsbCXPs1",
-         "dTlbCXCnfg","dTlbSfsr", "dTlbSfar", "dTlbTagAcs",
+         "fsr", "prictx", "secctx", "partId", "lsuCtrlReg",
          "scratch0", "scratch1", "scratch2", "scratch3", "scratch4",
          "scratch5", "scratch6", "scratch7", "cpuMondoHead", "cpuMondoTail",
          "devMondoHead", "devMondoTail", "resErrorHead", "resErrorTail",
@@ -113,25 +109,6 @@ void MiscRegFile::clear()
     partId = 0;
     lsuCtrlReg = 0;
 
-    iTlbC0TsbPs0 = 0;
-    iTlbC0TsbPs1 = 0;
-    iTlbC0Config = 0;
-    iTlbCXTsbPs0 = 0;
-    iTlbCXTsbPs1 = 0;
-    iTlbCXConfig = 0;
-    iTlbSfsr = 0;
-    iTlbTagAccess = 0;
-
-    dTlbC0TsbPs0 = 0;
-    dTlbC0TsbPs1 = 0;
-    dTlbC0Config = 0;
-    dTlbCXTsbPs0 = 0;
-    dTlbCXTsbPs1 = 0;
-    dTlbCXConfig = 0;
-    dTlbSfsr = 0;
-    dTlbSfar = 0;
-    dTlbTagAccess = 0;
-
     memset(scratchPad, 0, sizeof(scratchPad));
 #if FULL_SYSTEM
     tickCompare = NULL;
@@ -262,42 +239,6 @@ MiscReg MiscRegFile::readRegNoEffect(int miscReg)
       case MISCREG_MMU_LSU_CTRL:
         return lsuCtrlReg;
 
-      case MISCREG_MMU_ITLB_C0_TSB_PS0:
-        return iTlbC0TsbPs0;
-      case MISCREG_MMU_ITLB_C0_TSB_PS1:
-        return iTlbC0TsbPs1;
-      case MISCREG_MMU_ITLB_C0_CONFIG:
-        return iTlbC0Config;
-      case MISCREG_MMU_ITLB_CX_TSB_PS0:
-        return iTlbCXTsbPs0;
-      case MISCREG_MMU_ITLB_CX_TSB_PS1:
-        return iTlbCXTsbPs1;
-      case MISCREG_MMU_ITLB_CX_CONFIG:
-        return iTlbCXConfig;
-      case MISCREG_MMU_ITLB_SFSR:
-        return iTlbSfsr;
-      case MISCREG_MMU_ITLB_TAG_ACCESS:
-        return iTlbTagAccess;
-
-      case MISCREG_MMU_DTLB_C0_TSB_PS0:
-        return dTlbC0TsbPs0;
-      case MISCREG_MMU_DTLB_C0_TSB_PS1:
-        return dTlbC0TsbPs1;
-      case MISCREG_MMU_DTLB_C0_CONFIG:
-        return dTlbC0Config;
-      case MISCREG_MMU_DTLB_CX_TSB_PS0:
-        return dTlbCXTsbPs0;
-      case MISCREG_MMU_DTLB_CX_TSB_PS1:
-        return dTlbCXTsbPs1;
-      case MISCREG_MMU_DTLB_CX_CONFIG:
-        return dTlbCXConfig;
-      case MISCREG_MMU_DTLB_SFSR:
-        return dTlbSfsr;
-      case MISCREG_MMU_DTLB_SFAR:
-        return dTlbSfar;
-      case MISCREG_MMU_DTLB_TAG_ACCESS:
-        return dTlbTagAccess;
-
       case MISCREG_SCRATCHPAD_R0:
         return scratchPad[0];
       case MISCREG_SCRATCHPAD_R1:
@@ -519,59 +460,6 @@ void MiscRegFile::setRegNoEffect(int miscReg, const MiscReg &val)
         lsuCtrlReg = val;
         break;
 
-      case MISCREG_MMU_ITLB_C0_TSB_PS0:
-        iTlbC0TsbPs0 = val;
-        break;
-      case MISCREG_MMU_ITLB_C0_TSB_PS1:
-        iTlbC0TsbPs1 = val;
-        break;
-      case MISCREG_MMU_ITLB_C0_CONFIG:
-        iTlbC0Config = val;
-        break;
-      case MISCREG_MMU_ITLB_CX_TSB_PS0:
-        iTlbCXTsbPs0 = val;
-        break;
-      case MISCREG_MMU_ITLB_CX_TSB_PS1:
-        iTlbCXTsbPs1 = val;
-        break;
-      case MISCREG_MMU_ITLB_CX_CONFIG:
-        iTlbCXConfig = val;
-        break;
-      case MISCREG_MMU_ITLB_SFSR:
-        iTlbSfsr = val;
-        break;
-      case MISCREG_MMU_ITLB_TAG_ACCESS:
-        iTlbTagAccess = val;
-        break;
-
-      case MISCREG_MMU_DTLB_C0_TSB_PS0:
-        dTlbC0TsbPs0 = val;
-        break;
-      case MISCREG_MMU_DTLB_C0_TSB_PS1:
-        dTlbC0TsbPs1 = val;
-        break;
-      case MISCREG_MMU_DTLB_C0_CONFIG:
-        dTlbC0Config = val;
-        break;
-      case MISCREG_MMU_DTLB_CX_TSB_PS0:
-        dTlbCXTsbPs0 = val;
-        break;
-      case MISCREG_MMU_DTLB_CX_TSB_PS1:
-        dTlbCXTsbPs1 = val;
-        break;
-      case MISCREG_MMU_DTLB_CX_CONFIG:
-        dTlbCXConfig = val;
-        break;
-      case MISCREG_MMU_DTLB_SFSR:
-        dTlbSfsr = val;
-        break;
-      case MISCREG_MMU_DTLB_SFAR:
-        dTlbSfar = val;
-        break;
-      case MISCREG_MMU_DTLB_TAG_ACCESS:
-        dTlbTagAccess = val;
-        break;
-
       case MISCREG_SCRATCHPAD_R0:
         scratchPad[0] = val;
         break;
@@ -733,23 +621,6 @@ void MiscRegFile::serialize(std::ostream & os)
     SERIALIZE_SCALAR(secContext);
     SERIALIZE_SCALAR(partId);
     SERIALIZE_SCALAR(lsuCtrlReg);
-    SERIALIZE_SCALAR(iTlbC0TsbPs0);
-    SERIALIZE_SCALAR(iTlbC0TsbPs1);
-    SERIALIZE_SCALAR(iTlbC0Config);
-    SERIALIZE_SCALAR(iTlbCXTsbPs0);
-    SERIALIZE_SCALAR(iTlbCXTsbPs1);
-    SERIALIZE_SCALAR(iTlbCXConfig);
-    SERIALIZE_SCALAR(iTlbSfsr);
-    SERIALIZE_SCALAR(iTlbTagAccess);
-    SERIALIZE_SCALAR(dTlbC0TsbPs0);
-    SERIALIZE_SCALAR(dTlbC0TsbPs1);
-    SERIALIZE_SCALAR(dTlbC0Config);
-    SERIALIZE_SCALAR(dTlbCXTsbPs0);
-    SERIALIZE_SCALAR(dTlbCXTsbPs1);
-    SERIALIZE_SCALAR(dTlbCXConfig);
-    SERIALIZE_SCALAR(dTlbSfsr);
-    SERIALIZE_SCALAR(dTlbSfar);
-    SERIALIZE_SCALAR(dTlbTagAccess);
     SERIALIZE_ARRAY(scratchPad,8);
     SERIALIZE_SCALAR(cpu_mondo_head);
     SERIALIZE_SCALAR(cpu_mondo_tail);
@@ -827,23 +698,6 @@ void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
     UNSERIALIZE_SCALAR(secContext);
     UNSERIALIZE_SCALAR(partId);
     UNSERIALIZE_SCALAR(lsuCtrlReg);
-    UNSERIALIZE_SCALAR(iTlbC0TsbPs0);
-    UNSERIALIZE_SCALAR(iTlbC0TsbPs1);
-    UNSERIALIZE_SCALAR(iTlbC0Config);
-    UNSERIALIZE_SCALAR(iTlbCXTsbPs0);
-    UNSERIALIZE_SCALAR(iTlbCXTsbPs1);
-    UNSERIALIZE_SCALAR(iTlbCXConfig);
-    UNSERIALIZE_SCALAR(iTlbSfsr);
-    UNSERIALIZE_SCALAR(iTlbTagAccess);
-    UNSERIALIZE_SCALAR(dTlbC0TsbPs0);
-    UNSERIALIZE_SCALAR(dTlbC0TsbPs1);
-    UNSERIALIZE_SCALAR(dTlbC0Config);
-    UNSERIALIZE_SCALAR(dTlbCXTsbPs0);
-    UNSERIALIZE_SCALAR(dTlbCXTsbPs1);
-    UNSERIALIZE_SCALAR(dTlbCXConfig);
-    UNSERIALIZE_SCALAR(dTlbSfsr);
-    UNSERIALIZE_SCALAR(dTlbSfar);
-    UNSERIALIZE_SCALAR(dTlbTagAccess);
     UNSERIALIZE_ARRAY(scratchPad,8);
     UNSERIALIZE_SCALAR(cpu_mondo_head);
     UNSERIALIZE_SCALAR(cpu_mondo_tail);
index 867f959e196948485aa5c6e2a6a89ca66ed89740..3e17779a9ffac4f44fec51388d078f5c4a1c2a57 100644 (file)
@@ -100,25 +100,6 @@ namespace SparcISA
         MISCREG_MMU_PART_ID,
         MISCREG_MMU_LSU_CTRL,
 
-        MISCREG_MMU_ITLB_C0_TSB_PS0,
-        MISCREG_MMU_ITLB_C0_TSB_PS1,
-        MISCREG_MMU_ITLB_C0_CONFIG,
-        MISCREG_MMU_ITLB_CX_TSB_PS0,
-        MISCREG_MMU_ITLB_CX_TSB_PS1,
-        MISCREG_MMU_ITLB_CX_CONFIG,
-        MISCREG_MMU_ITLB_SFSR,
-        MISCREG_MMU_ITLB_TAG_ACCESS, /* 50 */
-
-        MISCREG_MMU_DTLB_C0_TSB_PS0,
-        MISCREG_MMU_DTLB_C0_TSB_PS1,
-        MISCREG_MMU_DTLB_C0_CONFIG,
-        MISCREG_MMU_DTLB_CX_TSB_PS0,
-        MISCREG_MMU_DTLB_CX_TSB_PS1,
-        MISCREG_MMU_DTLB_CX_CONFIG,
-        MISCREG_MMU_DTLB_SFSR,
-        MISCREG_MMU_DTLB_SFAR,
-        MISCREG_MMU_DTLB_TAG_ACCESS,
-
         /** Scratchpad regiscers **/
         MISCREG_SCRATCHPAD_R0, /* 60 */
         MISCREG_SCRATCHPAD_R1,
@@ -241,25 +222,6 @@ namespace SparcISA
         uint16_t partId;
         uint64_t lsuCtrlReg;
 
-        uint64_t iTlbC0TsbPs0;
-        uint64_t iTlbC0TsbPs1;
-        uint64_t iTlbC0Config;
-        uint64_t iTlbCXTsbPs0;
-        uint64_t iTlbCXTsbPs1;
-        uint64_t iTlbCXConfig;
-        uint64_t iTlbSfsr;
-        uint64_t iTlbTagAccess;
-
-        uint64_t dTlbC0TsbPs0;
-        uint64_t dTlbC0TsbPs1;
-        uint64_t dTlbC0Config;
-        uint64_t dTlbCXTsbPs0;
-        uint64_t dTlbCXTsbPs1;
-        uint64_t dTlbCXConfig;
-        uint64_t dTlbSfsr;
-        uint64_t dTlbSfar;
-        uint64_t dTlbTagAccess;
-
         uint64_t scratchPad[8];
 
         uint64_t cpu_mondo_head;
index 667b1f002e807c3484807978b6899da42f37cda5..d6be52424e291d089bd04fc7a0d401dc7e5ed3e1 100644 (file)
@@ -326,42 +326,6 @@ void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest)
     dest->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL,
             src->readMiscRegNoEffect(MISCREG_MMU_LSU_CTRL));
 
-    dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_C0_TSB_PS0,
-            src->readMiscRegNoEffect(MISCREG_MMU_ITLB_C0_TSB_PS0));
-    dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_C0_TSB_PS1,
-            src->readMiscRegNoEffect(MISCREG_MMU_ITLB_C0_TSB_PS1));
-    dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_C0_CONFIG,
-            src->readMiscRegNoEffect(MISCREG_MMU_ITLB_C0_CONFIG));
-    dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_CX_TSB_PS0,
-            src->readMiscRegNoEffect(MISCREG_MMU_ITLB_CX_TSB_PS0));
-    dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_CX_TSB_PS1,
-            src->readMiscRegNoEffect(MISCREG_MMU_ITLB_CX_TSB_PS1));
-    dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_CX_CONFIG,
-            src->readMiscRegNoEffect(MISCREG_MMU_ITLB_CX_CONFIG));
-    dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_SFSR,
-            src->readMiscRegNoEffect(MISCREG_MMU_ITLB_SFSR));
-    dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_TAG_ACCESS,
-            src->readMiscRegNoEffect(MISCREG_MMU_ITLB_TAG_ACCESS));
-
-    dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_C0_TSB_PS0,
-            src->readMiscRegNoEffect(MISCREG_MMU_DTLB_C0_TSB_PS0));
-    dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_C0_TSB_PS1,
-            src->readMiscRegNoEffect(MISCREG_MMU_DTLB_C0_TSB_PS1));
-    dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_C0_CONFIG,
-            src->readMiscRegNoEffect(MISCREG_MMU_DTLB_C0_CONFIG));
-    dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_CX_TSB_PS0,
-            src->readMiscRegNoEffect(MISCREG_MMU_DTLB_CX_TSB_PS0));
-    dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_CX_TSB_PS1,
-            src->readMiscRegNoEffect(MISCREG_MMU_DTLB_CX_TSB_PS1));
-    dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_CX_CONFIG,
-            src->readMiscRegNoEffect(MISCREG_MMU_DTLB_CX_CONFIG));
-    dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_SFSR,
-            src->readMiscRegNoEffect(MISCREG_MMU_DTLB_SFSR));
-    dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_SFAR,
-            src->readMiscRegNoEffect(MISCREG_MMU_DTLB_SFAR));
-    dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_TAG_ACCESS,
-            src->readMiscRegNoEffect(MISCREG_MMU_DTLB_TAG_ACCESS));
-
     // Scratchpad Registers
     dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R0,
             src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R0));
index 0def62f5394ac4e28aa97f21ff9ed50bf8991095..e184429ab83b0a62d463e88167684dbcf492b39f 100644 (file)
@@ -60,6 +60,15 @@ TLB::TLB(const std::string &name, int s)
 
     for (int x = 0; x < size; x++)
         freeList.push_back(&tlb[x]);
+
+    c0_tsb_ps0 = 0;
+    c0_tsb_ps1 = 0;
+    c0_config = 0;
+    cx_tsb_ps0 = 0;
+    cx_tsb_ps1 = 0;
+    cx_config = 0;
+    sfsr = 0;
+    tag_access = 0;
 }
 
 void
@@ -393,12 +402,8 @@ TLB::validVirtualAddress(Addr va, bool am)
 }
 
 void
-TLB::writeSfsr(ThreadContext *tc, int reg,  bool write, ContextType ct,
-        bool se, FaultTypes ft, int asi)
+TLB::writeSfsr(bool write, ContextType ct, bool se, FaultTypes ft, int asi)
 {
-    uint64_t sfsr;
-    sfsr = tc->readMiscRegNoEffect(reg);
-
     if (sfsr & 0x1)
         sfsr = 0x3;
     else
@@ -411,51 +416,35 @@ TLB::writeSfsr(ThreadContext *tc, int reg,  bool write, ContextType ct,
         sfsr |= 1 << 6;
     sfsr |= ft << 7;
     sfsr |= asi << 16;
-    tc->setMiscReg(reg, sfsr);
 }
 
 void
-TLB::writeTagAccess(ThreadContext *tc, int reg, Addr va, int context)
+TLB::writeTagAccess(Addr va, int context)
 {
     DPRINTF(TLB, "TLB: Writing Tag Access: va: %#X ctx: %#X value: %#X\n",
             va, context, mbits(va, 63,13) | mbits(context,12,0));
 
-    tc->setMiscReg(reg, mbits(va, 63,13) | mbits(context,12,0));
+    tag_access = mbits(va, 63,13) | mbits(context,12,0);
 }
 
 void
-ITB::writeSfsr(ThreadContext *tc, bool write, ContextType ct,
-        bool se, FaultTypes ft, int asi)
+ITB::writeSfsr(bool write, ContextType ct, bool se, FaultTypes ft, int asi)
 {
     DPRINTF(TLB, "TLB: ITB Fault:  w=%d ct=%d ft=%d asi=%d\n",
              (int)write, ct, ft, asi);
-    TLB::writeSfsr(tc, MISCREG_MMU_ITLB_SFSR, write, ct, se, ft, asi);
+    TLB::writeSfsr(write, ct, se, ft, asi);
 }
 
 void
-ITB::writeTagAccess(ThreadContext *tc, Addr va, int context)
-{
-    TLB::writeTagAccess(tc, MISCREG_MMU_ITLB_TAG_ACCESS, va, context);
-}
-
-void
-DTB::writeSfr(ThreadContext *tc, Addr a, bool write, ContextType ct,
+DTB::writeSfsr(Addr a, bool write, ContextType ct,
         bool se, FaultTypes ft, int asi)
 {
     DPRINTF(TLB, "TLB: DTB Fault: A=%#x w=%d ct=%d ft=%d asi=%d\n",
             a, (int)write, ct, ft, asi);
-    TLB::writeSfsr(tc, MISCREG_MMU_DTLB_SFSR, write, ct, se, ft, asi);
-    tc->setMiscReg(MISCREG_MMU_DTLB_SFAR, a);
-}
-
-void
-DTB::writeTagAccess(ThreadContext *tc, Addr va, int context)
-{
-    TLB::writeTagAccess(tc, MISCREG_MMU_DTLB_TAG_ACCESS, va, context);
+    TLB::writeSfsr(write, ct, se, ft, asi);
+    sfar = a;
 }
 
-
-
 Fault
 ITB::translate(RequestPtr &req, ThreadContext *tc)
 {
@@ -521,7 +510,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
 
     // If the access is unaligned trap
     if (vaddr & 0x3) {
-        writeSfsr(tc, false, ct, false, OtherFault, asi);
+        writeSfsr(false, ct, false, OtherFault, asi);
         return new MemAddressNotAligned;
     }
 
@@ -529,7 +518,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
         vaddr = vaddr & VAddrAMask;
 
     if (!validVirtualAddress(vaddr, addr_mask)) {
-        writeSfsr(tc, false, ct, false, VaOutOfRange, asi);
+        writeSfsr(false, ct, false, VaOutOfRange, asi);
         return new InstructionAccessException;
     }
 
@@ -542,7 +531,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
     }
 
     if (e == NULL || !e->valid) {
-        writeTagAccess(tc, vaddr, context);
+        writeTagAccess(vaddr, context);
         if (real)
             return new InstructionRealTranslationMiss;
         else
@@ -551,8 +540,8 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
 
     // were not priviledged accesing priv page
     if (!priv && e->pte.priv()) {
-        writeTagAccess(tc, vaddr, context);
-        writeSfsr(tc, false, ct, false, PrivViolation, asi);
+        writeTagAccess(vaddr, context);
+        writeSfsr(false, ct, false, PrivViolation, asi);
         return new InstructionAccessException;
     }
 
@@ -661,12 +650,12 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
         // We need to check for priv level/asi priv
         if (!priv && !hpriv && !AsiIsUnPriv(asi)) {
             // It appears that context should be Nucleus in these cases?
-            writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi);
+            writeSfsr(vaddr, write, Nucleus, false, IllegalAsi, asi);
             return new PrivilegedAction;
         }
 
         if (!hpriv && AsiIsHPriv(asi)) {
-            writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi);
+            writeSfsr(vaddr, write, Nucleus, false, IllegalAsi, asi);
             return new DataAccessException;
         }
 
@@ -719,7 +708,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
 
     // If the asi is unaligned trap
     if (vaddr & size-1) {
-        writeSfr(tc, vaddr, false, ct, false, OtherFault, asi);
+        writeSfsr(vaddr, false, ct, false, OtherFault, asi);
         return new MemAddressNotAligned;
     }
 
@@ -727,7 +716,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
         vaddr = vaddr & VAddrAMask;
 
     if (!validVirtualAddress(vaddr, addr_mask)) {
-        writeSfr(tc, vaddr, false, ct, true, VaOutOfRange, asi);
+        writeSfsr(vaddr, false, ct, true, VaOutOfRange, asi);
         return new DataAccessException;
     }
 
@@ -745,7 +734,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
     e = lookup(vaddr, part_id, real, context);
 
     if (e == NULL || !e->valid) {
-        writeTagAccess(tc, vaddr, context);
+        writeTagAccess(vaddr, context);
         DPRINTF(TLB, "TLB: DTB Failed to find matching TLB entry\n");
         if (real)
             return new DataRealTranslationMiss;
@@ -755,26 +744,26 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
     }
 
     if (!priv && e->pte.priv()) {
-        writeTagAccess(tc, vaddr, context);
-        writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), PrivViolation, asi);
+        writeTagAccess(vaddr, context);
+        writeSfsr(vaddr, write, ct, e->pte.sideffect(), PrivViolation, asi);
         return new DataAccessException;
     }
 
     if (write && !e->pte.writable()) {
-        writeTagAccess(tc, vaddr, context);
-        writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), OtherFault, asi);
+        writeTagAccess(vaddr, context);
+        writeSfsr(vaddr, write, ct, e->pte.sideffect(), OtherFault, asi);
         return new FastDataAccessProtection;
     }
 
     if (e->pte.nofault() && !AsiIsNoFault(asi)) {
-        writeTagAccess(tc, vaddr, context);
-        writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), LoadFromNfo, asi);
+        writeTagAccess(vaddr, context);
+        writeSfsr(vaddr, write, ct, e->pte.sideffect(), LoadFromNfo, asi);
         return new DataAccessException;
     }
 
     if (e->pte.sideffect() && AsiIsNoFault(asi)) {
-        writeTagAccess(tc, vaddr, context);
-        writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), SideEffect, asi);
+        writeTagAccess(vaddr, context);
+        writeSfsr(vaddr, write, ct, e->pte.sideffect(), SideEffect, asi);
         return new DataAccessException;
     }
 
@@ -806,7 +795,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
     /** Normal flow ends here. */
 handleIntRegAccess:
     if (!hpriv) {
-        writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
+        writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi);
         if (priv)
             return new DataAccessException;
          else
@@ -815,7 +804,7 @@ handleIntRegAccess:
 
     if (asi == ASI_SWVR_UDB_INTR_W && !write ||
                     asi == ASI_SWVR_UDB_INTR_R && write) {
-        writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
+        writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi);
         return new DataAccessException;
     }
 
@@ -824,25 +813,25 @@ handleIntRegAccess:
 
 handleScratchRegAccess:
     if (vaddr > 0x38 || (vaddr >= 0x20 && vaddr < 0x30 && !hpriv)) {
-        writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
+        writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi);
         return new DataAccessException;
     }
     goto regAccessOk;
 
 handleQueueRegAccess:
     if (!priv  && !hpriv) {
-        writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
+        writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi);
         return new PrivilegedAction;
     }
     if (!hpriv && vaddr & 0xF || vaddr > 0x3f8 || vaddr < 0x3c0) {
-        writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
+        writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi);
         return new DataAccessException;
     }
     goto regAccessOk;
 
 handleSparcErrorRegAccess:
     if (!hpriv) {
-        writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
+        writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi);
         if (priv)
             return new DataAccessException;
          else
@@ -869,6 +858,8 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
     DPRINTF(IPR, "Memory Mapped IPR Read: asi=%#X a=%#x\n",
          (uint32_t)pkt->req->getAsi(), pkt->getAddr());
 
+    ITB * itb = tc->getITBPtr();
+
     switch (asi) {
       case ASI_LSU_CONTROL_REG:
         assert(va == 0);
@@ -892,51 +883,51 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
         break;
       case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0:
         assert(va == 0);
-        pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS0));
+        pkt->set(c0_tsb_ps0);
         break;
       case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS1:
         assert(va == 0);
-        pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS1));
+        pkt->set(c0_tsb_ps1);
         break;
       case ASI_DMMU_CTXT_ZERO_CONFIG:
         assert(va == 0);
-        pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG));
+        pkt->set(c0_config);
         break;
       case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS0:
         assert(va == 0);
-        pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS0));
+        pkt->set(itb->c0_tsb_ps0);
         break;
       case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS1:
         assert(va == 0);
-        pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS1));
+        pkt->set(itb->c0_tsb_ps1);
         break;
       case ASI_IMMU_CTXT_ZERO_CONFIG:
         assert(va == 0);
-        pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG));
+        pkt->set(itb->c0_config);
         break;
       case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS0:
         assert(va == 0);
-        pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS0));
+        pkt->set(cx_tsb_ps0);
         break;
       case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS1:
         assert(va == 0);
-        pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS1));
+        pkt->set(cx_tsb_ps1);
         break;
       case ASI_DMMU_CTXT_NONZERO_CONFIG:
         assert(va == 0);
-        pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG));
+        pkt->set(cx_config);
         break;
       case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS0:
         assert(va == 0);
-        pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS0));
+        pkt->set(itb->cx_tsb_ps0);
         break;
       case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS1:
         assert(va == 0);
-        pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS1));
+        pkt->set(itb->cx_tsb_ps1);
         break;
       case ASI_IMMU_CTXT_NONZERO_CONFIG:
         assert(va == 0);
-        pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG));
+        pkt->set(itb->cx_config);
         break;
       case ASI_SPARC_ERROR_STATUS_REG:
         pkt->set((uint64_t)0);
@@ -948,14 +939,14 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
       case ASI_IMMU:
         switch (va) {
           case 0x0:
-            temp = tc->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS);
+            temp = itb->tag_access;
             pkt->set(bits(temp,63,22) | bits(temp,12,0) << 48);
             break;
           case 0x18:
-            pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_SFSR));
+            pkt->set(itb->sfsr);
             break;
           case 0x30:
-            pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS));
+            pkt->set(itb->tag_access);
             break;
           default:
             goto doMmuReadError;
@@ -964,17 +955,17 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
       case ASI_DMMU:
         switch (va) {
           case 0x0:
-            temp = tc->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS);
+            temp = tag_access;
             pkt->set(bits(temp,63,22) | bits(temp,12,0) << 48);
             break;
           case 0x18:
-            pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_SFSR));
+            pkt->set(sfsr);
             break;
           case 0x20:
-            pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_SFAR));
+            pkt->set(sfar);
             break;
           case 0x30:
-            pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS));
+            pkt->set(tag_access);
             break;
           case 0x80:
             pkt->set(tc->readMiscReg(MISCREG_MMU_PART_ID));
@@ -985,35 +976,35 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
         break;
       case ASI_DMMU_TSB_PS0_PTR_REG:
         pkt->set(MakeTsbPtr(Ps0,
-            tc->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS),
-            tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS0),
-            tc->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG),
-            tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS0),
-            tc->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG)));
+            tag_access,
+            c0_tsb_ps0,
+            c0_config,
+            cx_tsb_ps0,
+            cx_config));
         break;
       case ASI_DMMU_TSB_PS1_PTR_REG:
         pkt->set(MakeTsbPtr(Ps1,
-                tc->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS),
-                tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS1),
-                tc->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG),
-                tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS1),
-                tc->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG)));
+                tag_access,
+                c0_tsb_ps1,
+                c0_config,
+                cx_tsb_ps1,
+                cx_config));
         break;
       case ASI_IMMU_TSB_PS0_PTR_REG:
           pkt->set(MakeTsbPtr(Ps0,
-                tc->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS),
-                tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS0),
-                tc->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG),
-                tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS0),
-                tc->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG)));
+                itb->tag_access,
+                itb->c0_tsb_ps0,
+                itb->c0_config,
+                itb->cx_tsb_ps0,
+                itb->cx_config));
         break;
       case ASI_IMMU_TSB_PS1_PTR_REG:
           pkt->set(MakeTsbPtr(Ps1,
-                tc->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS),
-                tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS1),
-                tc->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG),
-                tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS1),
-                tc->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG)));
+                itb->tag_access,
+                itb->c0_tsb_ps1,
+                itb->c0_config,
+                itb->cx_tsb_ps1,
+                itb->cx_config));
         break;
       case ASI_SWVR_INTR_RECEIVE:
         pkt->set(tc->getCpuPtr()->get_interrupts(IT_INT_VEC));
@@ -1053,6 +1044,8 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
     DPRINTF(IPR, "Memory Mapped IPR Write: asi=%#X a=%#x d=%#X\n",
          (uint32_t)asi, va, data);
 
+    ITB * itb = tc->getITBPtr();
+
     switch (asi) {
       case ASI_LSU_CONTROL_REG:
         assert(va == 0);
@@ -1077,51 +1070,51 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
         break;
       case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0:
         assert(va == 0);
-        tc->setMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS0, data);
+        c0_tsb_ps0 = data;
         break;
       case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS1:
         assert(va == 0);
-        tc->setMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS1, data);
+        c0_tsb_ps1 = data;
         break;
       case ASI_DMMU_CTXT_ZERO_CONFIG:
         assert(va == 0);
-        tc->setMiscReg(MISCREG_MMU_DTLB_C0_CONFIG, data);
+        c0_config = data;
         break;
       case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS0:
         assert(va == 0);
-        tc->setMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS0, data);
+        itb->c0_tsb_ps0 = data;
         break;
       case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS1:
         assert(va == 0);
-        tc->setMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS1, data);
+        itb->c0_tsb_ps1 = data;
         break;
       case ASI_IMMU_CTXT_ZERO_CONFIG:
         assert(va == 0);
-        tc->setMiscReg(MISCREG_MMU_ITLB_C0_CONFIG, data);
+        itb->c0_config = data;
         break;
       case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS0:
         assert(va == 0);
-        tc->setMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS0, data);
+        cx_tsb_ps0 = data;
         break;
       case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS1:
         assert(va == 0);
-        tc->setMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS1, data);
+        cx_tsb_ps1 = data;
         break;
       case ASI_DMMU_CTXT_NONZERO_CONFIG:
         assert(va == 0);
-        tc->setMiscReg(MISCREG_MMU_DTLB_CX_CONFIG, data);
+        cx_config = data;
         break;
       case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS0:
         assert(va == 0);
-        tc->setMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS0, data);
+        itb->cx_tsb_ps0 = data;
         break;
       case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS1:
         assert(va == 0);
-        tc->setMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS1, data);
+        itb->cx_tsb_ps1 = data;
         break;
       case ASI_IMMU_CTXT_NONZERO_CONFIG:
         assert(va == 0);
-        tc->setMiscReg(MISCREG_MMU_ITLB_CX_CONFIG, data);
+        itb->cx_config = data;
         break;
       case ASI_SPARC_ERROR_EN_REG:
       case ASI_SPARC_ERROR_STATUS_REG:
@@ -1134,11 +1127,11 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
       case ASI_IMMU:
         switch (va) {
           case 0x18:
-            tc->setMiscReg(MISCREG_MMU_ITLB_SFSR, data);
+            itb->sfsr = data;
             break;
           case 0x30:
             sext<59>(bits(data, 59,0));
-            tc->setMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS, data);
+            itb->tag_access = data;
             break;
           default:
             goto doMmuWriteError;
@@ -1148,7 +1141,7 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
         entry_insert = bits(va, 8,3);
       case ASI_ITLB_DATA_IN_REG:
         assert(entry_insert != -1 || mbits(va,10,9) == va);
-        ta_insert = tc->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS);
+        ta_insert = itb->tag_access;
         va_insert = mbits(ta_insert, 63,13);
         ct_insert = mbits(ta_insert, 12,0);
         part_insert = tc->readMiscReg(MISCREG_MMU_PART_ID);
@@ -1162,7 +1155,7 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
         entry_insert = bits(va, 8,3);
       case ASI_DTLB_DATA_IN_REG:
         assert(entry_insert != -1 || mbits(va,10,9) == va);
-        ta_insert = tc->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS);
+        ta_insert = tag_access;
         va_insert = mbits(ta_insert, 63,13);
         ct_insert = mbits(ta_insert, 12,0);
         part_insert = tc->readMiscReg(MISCREG_MMU_PART_ID);
@@ -1209,11 +1202,11 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
       case ASI_DMMU:
         switch (va) {
           case 0x18:
-            tc->setMiscReg(MISCREG_MMU_DTLB_SFSR, data);
+            sfsr = data;
             break;
           case 0x30:
             sext<59>(bits(data, 59,0));
-            tc->setMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS, data);
+            tag_access = data;
             break;
           case 0x80:
             tc->setMiscReg(MISCREG_MMU_PART_ID, data);
@@ -1281,26 +1274,27 @@ void
 DTB::GetTsbPtr(ThreadContext *tc, Addr addr, int ctx, Addr *ptrs)
 {
     uint64_t tag_access = mbits(addr,63,13) | mbits(ctx,12,0);
+    ITB * itb = tc->getITBPtr();
     ptrs[0] = MakeTsbPtr(Ps0, tag_access,
-                tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS0),
-                tc->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG),
-                tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS0),
-                tc->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG));
+                c0_tsb_ps0,
+                c0_config,
+                cx_tsb_ps0,
+                cx_config);
     ptrs[1] = MakeTsbPtr(Ps1, tag_access,
-                tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS1),
-                tc->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG),
-                tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS1),
-                tc->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG));
+                c0_tsb_ps1,
+                c0_config,
+                cx_tsb_ps1,
+                cx_config);
     ptrs[2] = MakeTsbPtr(Ps0, tag_access,
-                tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS0),
-                tc->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG),
-                tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS0),
-                tc->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG));
+                itb->c0_tsb_ps0,
+                itb->c0_config,
+                itb->cx_tsb_ps0,
+                itb->cx_config);
     ptrs[3] = MakeTsbPtr(Ps1, tag_access,
-                tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS1),
-                tc->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG),
-                tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS1),
-                tc->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG));
+                itb->c0_tsb_ps1,
+                itb->c0_config,
+                itb->cx_tsb_ps1,
+                itb->cx_config);
 }
 
 
@@ -1358,6 +1352,15 @@ TLB::serialize(std::ostream &os)
         nameOut(os, csprintf("%s.PTE%d", name(), x));
         tlb[x].serialize(os);
     }
+
+    SERIALIZE_SCALAR(c0_tsb_ps0);
+    SERIALIZE_SCALAR(c0_tsb_ps1);
+    SERIALIZE_SCALAR(c0_config);
+    SERIALIZE_SCALAR(cx_tsb_ps0);
+    SERIALIZE_SCALAR(cx_tsb_ps1);
+    SERIALIZE_SCALAR(cx_config);
+    SERIALIZE_SCALAR(sfsr);
+    SERIALIZE_SCALAR(tag_access);
 }
 
 void
@@ -1387,6 +1390,29 @@ TLB::unserialize(Checkpoint *cp, const std::string &section)
             lookupTable.insert(tlb[x].range, &tlb[x]);
 
     }
+
+    UNSERIALIZE_SCALAR(c0_tsb_ps0);
+    UNSERIALIZE_SCALAR(c0_tsb_ps1);
+    UNSERIALIZE_SCALAR(c0_config);
+    UNSERIALIZE_SCALAR(cx_tsb_ps0);
+    UNSERIALIZE_SCALAR(cx_tsb_ps1);
+    UNSERIALIZE_SCALAR(cx_config);
+    UNSERIALIZE_SCALAR(sfsr);
+    UNSERIALIZE_SCALAR(tag_access);
+}
+
+void
+DTB::serialize(std::ostream &os)
+{
+    TLB::serialize(os);
+    SERIALIZE_SCALAR(sfar);
+}
+
+void
+DTB::unserialize(Checkpoint *cp, const std::string &section)
+{
+    TLB::unserialize(cp, section);
+    UNSERIALIZE_SCALAR(sfar);
 }
 
 /* end namespace SparcISA */ }
index b5f02c62e94872cfc7c7f6f72029c7afe7d77fe0..e1111db8dbc50e8e76f89662606387bcd74aea1d 100644 (file)
@@ -46,6 +46,17 @@ namespace SparcISA
 
 class TLB : public SimObject
 {
+    //TLB state
+  protected:
+    uint64_t c0_tsb_ps0;
+    uint64_t c0_tsb_ps1;
+    uint64_t c0_config;
+    uint64_t cx_tsb_ps0;
+    uint64_t cx_tsb_ps1;
+    uint64_t cx_config;
+    uint64_t sfsr;
+    uint64_t tag_access;
+
   protected:
     TlbMap lookupTable;;
     typedef TlbMap::iterator MapIter;
@@ -120,13 +131,13 @@ class TLB : public SimObject
     /** Checks if the virtual address provided is a valid one. */
     bool validVirtualAddress(Addr va, bool am);
 
-    void writeSfsr(ThreadContext *tc, int reg, bool write, ContextType ct,
+    void writeSfsr(bool write, ContextType ct,
             bool se, FaultTypes ft, int asi);
 
     void clearUsedBits();
 
 
-    void writeTagAccess(ThreadContext *tc, int reg, Addr va, int context);
+    void writeTagAccess(Addr va, int context);
 
   public:
     TLB(const std::string &name, int size);
@@ -152,18 +163,21 @@ class ITB : public TLB
 
     Fault translate(RequestPtr &req, ThreadContext *tc);
   private:
-    void writeSfsr(ThreadContext *tc, bool write, ContextType ct,
+    void writeSfsr(bool write, ContextType ct,
             bool se, FaultTypes ft, int asi);
-    void writeTagAccess(ThreadContext *tc, Addr va, int context);
     TlbEntry *cacheEntry;
     friend class DTB;
 };
 
 class DTB : public TLB
 {
+    //DTLB specific state
+  protected:
+    uint64_t sfar;
   public:
     DTB(const std::string &name, int size) : TLB(name, size)
     {
+        sfar = 0;
         cacheEntry[0] = NULL;
         cacheEntry[1] = NULL;
     }
@@ -173,10 +187,13 @@ class DTB : public TLB
     Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt);
     void GetTsbPtr(ThreadContext *tc, Addr addr, int ctx, Addr *ptrs);
 
+    // Checkpointing
+    virtual void serialize(std::ostream &os);
+    virtual void unserialize(Checkpoint *cp, const std::string &section);
+
   private:
-    void writeSfr(ThreadContext *tc, Addr a, bool write, ContextType ct,
+    void writeSfsr(Addr a, bool write, ContextType ct,
             bool se, FaultTypes ft, int asi);
-    void writeTagAccess(ThreadContext *tc, Addr va, int context);
 
     uint64_t MakeTsbPtr(TsbPageSize ps, uint64_t tag_access, uint64_t c0_tsb,
         uint64_t c0_config, uint64_t cX_tsb, uint64_t cX_config);