arm: Clean up and document decoder API
[gem5.git] / src / arch / mips / tlb.cc
index b73eae72f1d944874bf96b1b01e772b8563d3daf..b43797541491e14caeb85588d4950939ad772e3e 100644 (file)
@@ -29,6 +29,8 @@
  * Authors: Nathan Binkert
  *          Steve Reinhardt
  *          Jaidev Patwardhan
+ *          Zhengxing Li
+ *          Deyuan Guo
  */
 
 #include <string>
@@ -43,6 +45,8 @@
 #include "base/str.hh"
 #include "base/trace.hh"
 #include "cpu/thread_context.hh"
+#include "debug/MipsPRA.hh"
+#include "debug/TLB.hh"
 #include "mem/page_table.hh"
 #include "params/MipsTLB.hh"
 #include "sim/process.hh"
@@ -55,21 +59,6 @@ using namespace MipsISA;
 //  MIPS TLB
 //
 
-static inline mode_type
-getOperatingMode(MiscReg Stat)
-{
-    if ((Stat & 0x10000006) != 0 || (Stat & 0x18) ==0) {
-        return mode_kernel;
-    } else if ((Stat & 0x18) == 0x8) {
-        return mode_supervisor;
-    } else if ((Stat & 0x18) == 0x10) {
-        return mode_user;
-    } else {
-        return mode_number;
-    }
-}
-
-
 TLB::TLB(const Params *p)
     : BaseTLB(p), size(p->size), nlu(0)
 {
@@ -127,7 +116,6 @@ int
 TLB::probeEntry(Addr vpn, uint8_t asn) const
 {
     // assume not found...
-    PTE *retval = NULL;
     int Ind = -1;
     PageTable::const_iterator i = lookupTable.find(vpn);
     if (i != lookupTable.end()) {
@@ -142,7 +130,6 @@ TLB::probeEntry(Addr vpn, uint8_t asn) const
             if (((vpn & InvMask) == (VPN & InvMask)) &&
                     (pte->G  || (asn == pte->asid))) {
                 // We have a VPN + ASID Match
-                retval = pte;
                 Ind = index;
                 break;
             }
@@ -182,7 +169,7 @@ TLB::insertAt(PTE &pte, unsigned Index, int _smallPages)
                  (pte.D0 << 2) | (pte.V0 <<1) | pte.G),
                 ((pte.PFN1 <<6) | (pte.C1 << 3) |
                  (pte.D1 << 2) | (pte.V1 <<1) | pte.G));
-        if (table[Index].V0 == true || table[Index].V1 == true) {
+        if (table[Index].V0 || table[Index].V1) {
             // Previous entry is valid
             PageTable::iterator i = lookupTable.find(table[Index].VPN);
             lookupTable.erase(i);
@@ -293,7 +280,9 @@ TLB::regStats()
 Fault
 TLB::translateInst(RequestPtr req, ThreadContext *tc)
 {
-#if !FULL_SYSTEM
+    if (FullSystem)
+        panic("translateInst not implemented in MIPS.\n");
+
     Process * p = tc->getProcessPtr();
 
     Fault fault = p->pTable->translate(req);
@@ -301,122 +290,13 @@ TLB::translateInst(RequestPtr req, ThreadContext *tc)
         return fault;
 
     return NoFault;
-#else
-    Addr vaddr = req->getVaddr();
-
-    bool misaligned = (req->getSize() - 1) & vaddr;
-
-    if (IsKSeg0(vaddr)) {
-        // Address will not be translated through TLB, set response, and go!
-        req->setPaddr(KSeg02Phys(vaddr));
-        if (getOperatingMode(tc->readMiscReg(MISCREG_STATUS)) != mode_kernel ||
-                misaligned) {
-            AddressErrorFault *Flt = new AddressErrorFault();
-            /* BadVAddr must be set */
-            Flt->badVAddr = vaddr;
-            return Flt;
-        }
-    } else if(IsKSeg1(vaddr)) {
-        // Address will not be translated through TLB, set response, and go!
-        req->setPaddr(KSeg02Phys(vaddr));
-    } else {
-      /* 
-       * This is an optimization - smallPages is updated every time a TLB
-       * operation is performed. That way, we don't need to look at
-       * Config3 _ SP and PageGrain _ ESP every time we do a TLB lookup
-       */
-      Addr VPN;
-      if (smallPages == 1) {
-        VPN = (vaddr >> 11);
-      } else {
-        VPN = ((vaddr >> 11) & 0xFFFFFFFC);
-      }
-      uint8_t Asid = req->getAsid();
-      if (misaligned) {
-          // Unaligned address!
-          AddressErrorFault *Flt = new AddressErrorFault();
-          /* BadVAddr must be set */
-          Flt->badVAddr = vaddr;
-          return Flt;
-      }
-      PTE *pte = lookup(VPN,Asid);
-      if (pte != NULL) {
-          // Ok, found something
-          /* Check for valid bits */
-          int EvenOdd;
-          bool Valid;
-          if ((((vaddr) >> pte->AddrShiftAmount) & 1) == 0) {
-              // Check even bits
-              Valid = pte->V0;
-              EvenOdd = 0;
-          } else {
-              // Check odd bits
-              Valid = pte->V1;
-              EvenOdd = 1;
-          }
-
-          if (Valid == false) {
-              //Invalid entry
-              ItbInvalidFault *Flt = new ItbInvalidFault();
-              /* EntryHi VPN, ASID fields must be set */
-              Flt->entryHiAsid = Asid;
-              Flt->entryHiVPN2 = (VPN >> 2);
-              Flt->entryHiVPN2X = (VPN & 0x3);
-
-              /* BadVAddr must be set */
-              Flt->badVAddr = vaddr;
-
-              /* Context must be set */
-              Flt->contextBadVPN2 = (VPN >> 2);
-              return Flt;
-          } else {
-              // Ok, this is really a match, set paddr
-              Addr PAddr;
-              if (EvenOdd == 0) {
-                PAddr = pte->PFN0;
-              } else {
-                PAddr = pte->PFN1;
-              }
-              PAddr >>= (pte->AddrShiftAmount - 12);
-              PAddr <<= pte->AddrShiftAmount;
-              PAddr |= (vaddr & pte->OffsetMask);
-              req->setPaddr(PAddr);
-            }
-        } else {
-            // Didn't find any match, return a TLB Refill Exception
-            ItbRefillFault *Flt = new ItbRefillFault();
-            /* EntryHi VPN, ASID fields must be set */
-            Flt->entryHiAsid = Asid;
-            Flt->entryHiVPN2 = (VPN >> 2);
-            Flt->entryHiVPN2X = (VPN & 0x3);
-
-            /* BadVAddr must be set */
-            Flt->badVAddr = vaddr;
-
-            /* Context must be set */
-            Flt->contextBadVPN2 = (VPN >> 2);
-            return Flt;
-        }
-    }
-    return checkCacheability(req);
-#endif
 }
 
 Fault
 TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
 {
-#if !FULL_SYSTEM
-    //@TODO: This should actually use TLB instead of going directly
-    //       to the page table in syscall mode.
-    /**
-     * Check for alignment faults
-     */
-    if (req->getVaddr() & (req->getSize() - 1)) {
-        DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(),
-                req->getSize());
-        return new AlignmentFault();
-    }
-
+    if (FullSystem)
+        panic("translateData not implemented in MIPS.\n");
 
     Process * p = tc->getProcessPtr();
 
@@ -425,122 +305,6 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
         return fault;
 
     return NoFault;
-#else
-    Addr vaddr = req->getVaddr();
-
-    bool misaligned = (req->getSize() - 1) & vaddr;
-
-    if (IsKSeg0(vaddr)) {
-        // Address will not be translated through TLB, set response, and go!
-        req->setPaddr(KSeg02Phys(vaddr));
-        if (getOperatingMode(tc->readMiscReg(MISCREG_STATUS)) != mode_kernel ||
-                misaligned) {
-            StoreAddressErrorFault *Flt = new StoreAddressErrorFault();
-            /* BadVAddr must be set */
-            Flt->badVAddr = vaddr;
-
-            return Flt;
-        }
-    } else if(IsKSeg1(vaddr)) {
-      // Address will not be translated through TLB, set response, and go!
-      req->setPaddr(KSeg02Phys(vaddr));
-    } else {
-        /* 
-         * This is an optimization - smallPages is updated every time a TLB
-         * operation is performed. That way, we don't need to look at
-         * Config3 _ SP and PageGrain _ ESP every time we do a TLB lookup
-         */
-        Addr VPN = (vaddr >> 11) & 0xFFFFFFFC;
-        if (smallPages == 1) {
-            VPN = vaddr >> 11;
-        }
-        uint8_t Asid = req->getAsid();
-        PTE *pte = lookup(VPN, Asid);
-        if (misaligned) {
-            // Unaligned address!
-            StoreAddressErrorFault *Flt = new StoreAddressErrorFault();
-            /* BadVAddr must be set */
-            Flt->badVAddr = vaddr;
-            return Flt;
-        }
-        if (pte != NULL) {
-            // Ok, found something
-            /* Check for valid bits */
-            int EvenOdd;
-            bool Valid;
-            bool Dirty;
-            if ((((vaddr >> pte->AddrShiftAmount) & 1)) == 0) {
-                // Check even bits
-                Valid = pte->V0;
-                Dirty = pte->D0;
-                EvenOdd = 0;
-            } else {
-                // Check odd bits
-                Valid = pte->V1;
-                Dirty = pte->D1;
-                EvenOdd = 1;
-            }
-
-            if (Valid == false) {
-                //Invalid entry
-                DtbInvalidFault *Flt = new DtbInvalidFault();
-                /* EntryHi VPN, ASID fields must be set */
-                Flt->entryHiAsid = Asid;
-                Flt->entryHiVPN2 = (VPN>>2);
-                Flt->entryHiVPN2X = (VPN & 0x3);
-
-                /* BadVAddr must be set */
-                Flt->badVAddr = vaddr;
-
-                /* Context must be set */
-                Flt->contextBadVPN2 = (VPN >> 2);
-
-                return Flt;
-            } else {
-                // Ok, this is really a match, set paddr
-                if (!Dirty) {
-                    TLBModifiedFault *Flt = new TLBModifiedFault();
-                    /* EntryHi VPN, ASID fields must be set */
-                    Flt->entryHiAsid = Asid;
-                    Flt->entryHiVPN2 = (VPN >> 2);
-                    Flt->entryHiVPN2X = (VPN & 0x3);
-
-                    /* BadVAddr must be set */
-                    Flt->badVAddr = vaddr;
-
-                    /* Context must be set */
-                    Flt->contextBadVPN2 = (VPN >> 2);
-                    return Flt;
-                }
-                Addr PAddr;
-                if (EvenOdd == 0) {
-                    PAddr = pte->PFN0;
-                } else {
-                    PAddr = pte->PFN1;
-                }
-                PAddr >>= (pte->AddrShiftAmount - 12);
-                PAddr <<= pte->AddrShiftAmount;
-                PAddr |= (vaddr & pte->OffsetMask);
-                req->setPaddr(PAddr);
-            }
-        } else {
-            // Didn't find any match, return a TLB Refill Exception
-            DtbRefillFault *Flt = new DtbRefillFault();
-            /* EntryHi VPN, ASID fields must be set */
-            Flt->entryHiAsid = Asid;
-            Flt->entryHiVPN2 = (VPN >> 2);
-            Flt->entryHiVPN2X = (VPN & 0x3);
-
-            /* BadVAddr must be set */
-            Flt->badVAddr = vaddr;
-
-            /* Context must be set */
-            Flt->contextBadVPN2 = (VPN >> 2);
-            return Flt;
-        }
-    }
-    return checkCacheability(req);
-#endif
 }
 
 Fault
@@ -560,6 +324,19 @@ TLB::translateTiming(RequestPtr req, ThreadContext *tc,
     translation->finish(translateAtomic(req, tc, mode), req, tc, mode);
 }
 
+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;
+}
+
 
 MipsISA::PTE &
 TLB::index(bool advance)