mem: update stuff for changes to Packet and Request
[gem5.git] / src / arch / alpha / faults.cc
index 1497293518d73a6e1471a4b0bbcc411f00e198fb..e89cf5c6405ee3b4331db2aedd8887246b2dbf5d 100644 (file)
  *          Kevin Lim
  */
 
+#include "arch/alpha/ev5.hh"
 #include "arch/alpha/faults.hh"
+#include "arch/alpha/tlb.hh"
 #include "cpu/thread_context.hh"
 #include "cpu/base.hh"
 #include "base/trace.hh"
-#if FULL_SYSTEM
-#include "arch/alpha/ev5.hh"
-#else
+#if !FULL_SYSTEM
 #include "sim/process.hh"
 #include "mem/page_table.hh"
 #endif
 
-namespace AlphaISA
-{
+namespace AlphaISA {
 
 FaultName MachineCheckFault::_name = "mchk";
 FaultVect MachineCheckFault::_vect = 0x0401;
@@ -83,10 +82,6 @@ FaultName DtbAlignmentFault::_name = "unalign";
 FaultVect DtbAlignmentFault::_vect = 0x0301;
 FaultStat DtbAlignmentFault::_count;
 
-FaultName ItbMissFault::_name = "itbmiss";
-FaultVect ItbMissFault::_vect = 0x0181;
-FaultStat ItbMissFault::_count;
-
 FaultName ItbPageFault::_name = "itbmiss";
 FaultVect ItbPageFault::_vect = 0x0181;
 FaultStat ItbPageFault::_count;
@@ -113,69 +108,105 @@ FaultStat IntegerOverflowFault::_count;
 
 #if FULL_SYSTEM
 
-void AlphaFault::invoke(ThreadContext * tc)
+void
+AlphaFault::invoke(ThreadContext *tc)
 {
     FaultBase::invoke(tc);
     countStat()++;
 
     // exception restart address
     if (setRestartAddress() || !(tc->readPC() & 0x3))
-        tc->setMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR, tc->readPC());
+        tc->setMiscRegNoEffect(IPR_EXC_ADDR, tc->readPC());
 
     if (skipFaultingInstruction()) {
         // traps...  skip faulting instruction.
-        tc->setMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR,
-                   tc->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR) + 4);
+        tc->setMiscRegNoEffect(IPR_EXC_ADDR,
+                   tc->readMiscRegNoEffect(IPR_EXC_ADDR) + 4);
     }
 
-    tc->setPC(tc->readMiscRegNoEffect(AlphaISA::IPR_PAL_BASE) + vect());
+    tc->setPC(tc->readMiscRegNoEffect(IPR_PAL_BASE) + vect());
     tc->setNextPC(tc->readPC() + sizeof(MachInst));
 }
 
-void ArithmeticFault::invoke(ThreadContext * tc)
+void
+ArithmeticFault::invoke(ThreadContext *tc)
 {
     FaultBase::invoke(tc);
     panic("Arithmetic traps are unimplemented!");
 }
 
-void DtbFault::invoke(ThreadContext * tc)
+void
+DtbFault::invoke(ThreadContext *tc)
 {
     // Set fault address and flags.  Even though we're modeling an
     // EV5, we use the EV6 technique of not latching fault registers
     // on VPTE loads (instead of locking the registers until IPR_VA is
     // read, like the EV5).  The EV6 approach is cleaner and seems to
     // work with EV5 PAL code, but not the other way around.
-    if (!tc->misspeculating()
-        && !(reqFlags & VPTE) && !(reqFlags & NO_FAULT)) {
+    if (!tc->misspeculating() &&
+        reqFlags.none(Request::VPTE|Request::NO_FAULT)) {
         // set VA register with faulting address
-        tc->setMiscRegNoEffect(AlphaISA::IPR_VA, vaddr);
+        tc->setMiscRegNoEffect(IPR_VA, vaddr);
 
         // set MM_STAT register flags
-        tc->setMiscRegNoEffect(AlphaISA::IPR_MM_STAT,
-            (((EV5::Opcode(tc->getInst()) & 0x3f) << 11)
-             | ((EV5::Ra(tc->getInst()) & 0x1f) << 6)
-             (flags & 0x3f)));
+        tc->setMiscRegNoEffect(IPR_MM_STAT,
+            (((Opcode(tc->getInst()) & 0x3f) << 11) |
+             ((Ra(tc->getInst()) & 0x1f) << 6) |
+             (flags & 0x3f)));
 
         // set VA_FORM register with faulting formatted address
-        tc->setMiscRegNoEffect(AlphaISA::IPR_VA_FORM,
-            tc->readMiscRegNoEffect(AlphaISA::IPR_MVPTBR) | (vaddr.vpn() << 3));
+        tc->setMiscRegNoEffect(IPR_VA_FORM,
+            tc->readMiscRegNoEffect(IPR_MVPTBR) | (vaddr.vpn() << 3));
     }
 
     AlphaFault::invoke(tc);
 }
 
-void ItbFault::invoke(ThreadContext * tc)
+void
+ItbFault::invoke(ThreadContext *tc)
 {
     if (!tc->misspeculating()) {
-        tc->setMiscRegNoEffect(AlphaISA::IPR_ITB_TAG, pc);
-        tc->setMiscRegNoEffect(AlphaISA::IPR_IFAULT_VA_FORM,
-                       tc->readMiscRegNoEffect(AlphaISA::IPR_IVPTBR) |
-                       (AlphaISA::VAddr(pc).vpn() << 3));
+        tc->setMiscRegNoEffect(IPR_ITB_TAG, pc);
+        tc->setMiscRegNoEffect(IPR_IFAULT_VA_FORM,
+            tc->readMiscRegNoEffect(IPR_IVPTBR) | (VAddr(pc).vpn() << 3));
     }
 
     AlphaFault::invoke(tc);
 }
 
+#else
+
+void
+ItbPageFault::invoke(ThreadContext *tc)
+{
+    Process *p = tc->getProcessPtr();
+    TlbEntry entry;
+    bool success = p->pTable->lookup(pc, entry);
+    if (!success) {
+        panic("Tried to execute unmapped address %#x.\n", pc);
+    } else {
+        VAddr vaddr(pc);
+        tc->getITBPtr()->insert(vaddr.page(), entry);
+    }
+}
+
+void
+NDtbMissFault::invoke(ThreadContext *tc)
+{
+    Process *p = tc->getProcessPtr();
+    TlbEntry entry;
+    bool success = p->pTable->lookup(vaddr, entry);
+    if (!success) {
+        p->checkAndAllocNextPage(vaddr);
+        success = p->pTable->lookup(vaddr, entry);
+    }
+    if (!success) {
+        panic("Tried to access unmapped address %#x.\n", (Addr)vaddr);
+    } else {
+        tc->getDTBPtr()->insert(vaddr.page(), entry);
+    }
+}
+
 #endif
 
 } // namespace AlphaISA