MIPS: Consolidate TLB related faults.
authorGabe Black <gblack@eecs.umich.edu>
Mon, 19 Sep 2011 13:17:20 +0000 (06:17 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Mon, 19 Sep 2011 13:17:20 +0000 (06:17 -0700)
Pass in a bool to indicate if the fault is from a store instead of having two
different classes. The classes were also misleadingly named since loads are
also processed by the DTB but should return ITB faults since they aren't
stores. The TLB may be returning the wrong fault in this case, but I haven't
looked at it closely.

src/arch/mips/faults.cc
src/arch/mips/faults.hh
src/arch/mips/tlb.cc

index 038b738835929364a1969f0adc0f75d22aade3f2..c69bd1bd34503822abbe518da2e1659d94b65d63 100644 (file)
@@ -85,17 +85,11 @@ template <> FaultVals MipsFault<TrapFault>::vals =
 template <> FaultVals MipsFault<BreakpointFault>::vals =
     { "Breakpoint", 0x0180 };
 
-template <> FaultVals MipsFault<ItbInvalidFault>::vals =
-    { "Invalid TLB Entry Exception (I-Fetch/LW)", 0x0180 };
+template <> FaultVals MipsFault<TlbInvalidFault>::vals =
+    { "Invalid TLB Entry Exception", 0x0180 };
 
-template <> FaultVals MipsFault<ItbRefillFault>::vals =
-    { "TLB Refill Exception (I-Fetch/LW)", 0x0180 };
-
-template <> FaultVals MipsFault<DtbInvalidFault>::vals =
-    { "Invalid TLB Entry Exception (Store)", 0x0180 };
-
-template <> FaultVals MipsFault<DtbRefillFault>::vals =
-    { "TLB Refill Exception (Store)", 0x0180 };
+template <> FaultVals MipsFault<TlbRefillFault>::vals =
+    { "TLB Refill Exception", 0x0180 };
 
 template <> FaultVals MipsFault<TLBModifiedFault>::vals =
     { "TLB Modified Exception", 0x0180 };
@@ -199,9 +193,10 @@ BreakpointFault::invoke(ThreadContext *tc, StaticInstPtr inst)
 }
 
 void
-DtbInvalidFault::invoke(ThreadContext *tc, StaticInstPtr inst)
+TlbInvalidFault::invoke(ThreadContext *tc, StaticInstPtr inst)
 {
     DPRINTF(MipsPRA, "%s encountered.\n", name());
+    setExceptionState(tc, store ? 0x3 : 0x2);
 
     tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr);
     EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI);
@@ -213,8 +208,6 @@ DtbInvalidFault::invoke(ThreadContext *tc, StaticInstPtr inst)
     ContextReg context = tc->readMiscReg(MISCREG_CONTEXT);
     context.badVPN2 = contextBadVPN2;
     tc->setMiscRegNoEffect(MISCREG_CONTEXT, context);
-    setExceptionState(tc, 0x3);
-
 
     // Set new PC
     Addr HandlerBase;
@@ -238,66 +231,11 @@ AddressErrorFault::invoke(ThreadContext *tc, StaticInstPtr inst)
 }
 
 void
-ItbInvalidFault::invoke(ThreadContext *tc, StaticInstPtr inst)
-{
-    DPRINTF(MipsPRA, "%s encountered.\n", name());
-    setExceptionState(tc, 0x2);
-    tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr);
-    EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI);
-    entryHi.asid = entryHiAsid;
-    entryHi.vpn2 = entryHiVPN2;
-    entryHi.vpn2x = entryHiVPN2X;
-    tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi);
-
-    ContextReg context = tc->readMiscReg(MISCREG_CONTEXT);
-    context.badVPN2 = contextBadVPN2;
-    tc->setMiscRegNoEffect(MISCREG_CONTEXT, context);
-
-
-    // Set new PC
-    Addr HandlerBase;
-    // Offset 0x180 - General Exception Vector
-    HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE);
-    setHandlerPC(HandlerBase,tc);
-    DPRINTF(MipsPRA, "Exception Handler At: %x , EPC set to %x\n",
-            HandlerBase, tc->readMiscReg(MISCREG_EPC));
-}
-
-void
-ItbRefillFault::invoke(ThreadContext *tc, StaticInstPtr inst)
+TlbRefillFault::invoke(ThreadContext *tc, StaticInstPtr inst)
 {
     DPRINTF(MipsPRA, "%s encountered (%x).\n", name(), MISCREG_BADVADDR);
-    Addr HandlerBase;
-    tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr);
-    EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI);
-    entryHi.asid = entryHiAsid;
-    entryHi.vpn2 = entryHiVPN2;
-    entryHi.vpn2x = entryHiVPN2X;
-    tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi);
-    ContextReg context = tc->readMiscReg(MISCREG_CONTEXT);
-    context.badVPN2 = contextBadVPN2;
-    tc->setMiscRegNoEffect(MISCREG_CONTEXT, context);
-
-    StatusReg status = tc->readMiscReg(MISCREG_STATUS);
-    // Since handler depends on EXL bit, must check EXL bit before setting it!!
-    // See MIPS ARM Vol 3, Revision 2, Page 38
-    if (status.exl == 1) {
-        // Offset 0x180 - General Exception Vector
-        HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE);
-    } else {
-        // Offset 0x000
-        HandlerBase = tc->readMiscReg(MISCREG_EBASE);
-    }
+    setExceptionState(tc, store ? 0x3 : 0x2);
 
-    setExceptionState(tc, 0x2);
-    setHandlerPC(HandlerBase, tc);
-}
-
-void
-DtbRefillFault::invoke(ThreadContext *tc, StaticInstPtr inst)
-{
-    // Set new PC
-    DPRINTF(MipsPRA, "%s encountered.\n", name());
     Addr HandlerBase;
     tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr);
     EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI);
@@ -305,7 +243,6 @@ DtbRefillFault::invoke(ThreadContext *tc, StaticInstPtr inst)
     entryHi.vpn2 = entryHiVPN2;
     entryHi.vpn2x = entryHiVPN2X;
     tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi);
-
     ContextReg context = tc->readMiscReg(MISCREG_CONTEXT);
     context.badVPN2 = contextBadVPN2;
     tc->setMiscRegNoEffect(MISCREG_CONTEXT, context);
@@ -313,16 +250,13 @@ DtbRefillFault::invoke(ThreadContext *tc, StaticInstPtr inst)
     StatusReg status = tc->readMiscReg(MISCREG_STATUS);
     // Since handler depends on EXL bit, must check EXL bit before setting it!!
     // See MIPS ARM Vol 3, Revision 2, Page 38
-    if (status.exl) {
+    if (status.exl == 1) {
         // Offset 0x180 - General Exception Vector
         HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE);
     } else {
         // Offset 0x000
         HandlerBase = tc->readMiscReg(MISCREG_EBASE);
     }
-
-    setExceptionState(tc, 0x3);
-
     setHandlerPC(HandlerBase, tc);
 }
 
index 0b3d6ce30853e9b57b1869a62af3aa51113570f3..dfb3b4ab59f9bcb3ba3c32aa6841e82124839b66 100644 (file)
@@ -199,27 +199,13 @@ class BreakpointFault : public MipsFault<BreakpointFault>
 #endif
 };
 
-class ItbRefillFault : public MipsFault<ItbRefillFault>
-{
-  public:
-    ItbRefillFault(Addr asid, Addr vaddr, Addr vpn)
-    {
-        entryHiAsid = asid;
-        entryHiVPN2 = vpn >> 2;
-        entryHiVPN2X = vpn & 0x3;
-        badVAddr = vaddr;
-        contextBadVPN2 = vpn >> 2;
-    }
-#if FULL_SYSTEM
-    void invoke(ThreadContext * tc,
-            StaticInstPtr inst = StaticInst::nullStaticInstPtr);
-#endif
-};
-
-class DtbRefillFault : public MipsFault<DtbRefillFault>
+class TlbRefillFault : public MipsFault<TlbRefillFault>
 {
+  protected:
+    bool store;
   public:
-    DtbRefillFault(Addr asid, Addr vaddr, Addr vpn)
+    TlbRefillFault(Addr asid, Addr vaddr, Addr vpn, bool _store) :
+        store(_store)
     {
         entryHiAsid = asid;
         entryHiVPN2 = vpn >> 2;
@@ -233,10 +219,13 @@ class DtbRefillFault : public MipsFault<DtbRefillFault>
 #endif
 };
 
-class ItbInvalidFault : public MipsFault<ItbInvalidFault>
+class TlbInvalidFault : public MipsFault<TlbInvalidFault>
 {
+  protected:
+    bool store;
   public:
-    ItbInvalidFault(Addr asid, Addr vaddr, Addr vpn)
+    TlbInvalidFault(Addr asid, Addr vaddr, Addr vpn, bool _store) :
+        store(_store)
     {
         entryHiAsid = asid;
         entryHiVPN2 = vpn >> 2;
@@ -267,23 +256,6 @@ class TLBModifiedFault : public MipsFault<TLBModifiedFault>
 #endif
 };
 
-class DtbInvalidFault : public MipsFault<DtbInvalidFault>
-{
-  public:
-    DtbInvalidFault(Addr asid, Addr vaddr, Addr vpn)
-    {
-        entryHiAsid = asid;
-        entryHiVPN2 = vpn >> 2;
-        entryHiVPN2X = vpn & 0x3;
-        badVAddr = vaddr;
-        contextBadVPN2 = vpn >> 2;
-    }
-#if FULL_SYSTEM
-    void invoke(ThreadContext * tc,
-            StaticInst::StaticInstPtr inst = nullStaticInstPtr);
-#endif
-};
-
 class DspStateDisabledFault : public MipsFault<DspStateDisabledFault>
 {
   public:
index 1336ee7d02b69a8a35d8aae35d3b090eb2516a7d..31595b53def6ac005cdfd4f76079095535e506c9 100644 (file)
@@ -352,7 +352,7 @@ TLB::translateInst(RequestPtr req, ThreadContext *tc)
           }
 
           if (Valid == false) {
-              return new ItbInvalidFault(Asid, vaddr, vpn);
+              return new InvalidFault(Asid, vaddr, vpn, false);
           } else {
               // Ok, this is really a match, set paddr
               Addr PAddr;
@@ -368,7 +368,7 @@ TLB::translateInst(RequestPtr req, ThreadContext *tc)
             }
         } else {
             // Didn't find any match, return a TLB Refill Exception
-            return new ItbRefillFault(Asid, vaddr, vpn);
+            return new RefillFault(Asid, vaddr, vpn, false);
         }
     }
     return checkCacheability(req);
@@ -447,7 +447,7 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
             }
 
             if (Valid == false) {
-                return new DtbInvalidFault(Asid, vaddr, VPN);
+                return new InvalidFault(Asid, vaddr, VPN, true);
             } else {
                 // Ok, this is really a match, set paddr
                 if (!Dirty) {
@@ -466,7 +466,7 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
             }
         } else {
             // Didn't find any match, return a TLB Refill Exception
-            return new DtbRefillFault(Asid, vaddr, VPN);
+            return new RefillFault(Asid, vaddr, VPN, true);
         }
     }
     return checkCacheability(req);