Merge gblack@m5.eecs.umich.edu:/bk/multiarch
[gem5.git] / arch / alpha / alpha_memory.cc
index 81a1902a0892c61a1686db8e8474db3131727ad3..615ce92a4f890bd557bae2a4c06abc09fb2447f0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001-2004 The Regents of The University of Michigan
+ * Copyright (c) 2001-2005 The Regents of The University of Michigan
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,6 +34,7 @@
 #include "base/inifile.hh"
 #include "base/str.hh"
 #include "base/trace.hh"
+#include "config/alpha_tlaser.hh"
 #include "cpu/exec_context.hh"
 #include "sim/builder.hh"
 
@@ -68,24 +69,27 @@ AlphaTLB::~AlphaTLB()
 AlphaISA::PTE *
 AlphaTLB::lookup(Addr vpn, uint8_t asn) const
 {
-    DPRINTF(TLB, "lookup %#x, asn %#x\n", vpn, (int)asn);
+    // assume not found...
+    AlphaISA::PTE *retval = NULL;
 
     PageTable::const_iterator i = lookupTable.find(vpn);
-    if (i == lookupTable.end())
-        return NULL;
-
-    while (i->first == vpn) {
-        int index = i->second;
-        AlphaISA::PTE *pte = &table[index];
-        assert(pte->valid);
-        if (vpn == pte->tag && (pte->asma || pte->asn == asn))
-            return pte;
+    if (i != lookupTable.end()) {
+        while (i->first == vpn) {
+            int index = i->second;
+            AlphaISA::PTE *pte = &table[index];
+            assert(pte->valid);
+            if (vpn == pte->tag && (pte->asma || pte->asn == asn)) {
+                retval = pte;
+                break;
+            }
 
-        ++i;
+            ++i;
+        }
     }
 
-    // not found...
-    return NULL;
+    DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn,
+            retval ? "hit" : "miss", retval ? retval->ppn : 0);
+    return retval;
 }
 
 
@@ -104,7 +108,7 @@ AlphaTLB::checkCacheability(MemReqPtr &req)
      */
 
 
-#ifdef ALPHA_TLASER
+#if ALPHA_TLASER
     if (req->paddr & PAddrUncachedBit39) {
 #else
     if (req->paddr & PAddrUncachedBit43) {
@@ -126,7 +130,7 @@ AlphaTLB::checkCacheability(MemReqPtr &req)
             // mark request as uncacheable
             req->flags |= UNCACHEABLE;
 
-#ifndef ALPHA_TLASER
+#if !ALPHA_TLASER
             // Clear bits 42:35 of the physical address (10-2 in Tsunami manual)
             req->paddr &= PAddrUncachedMask;
 #endif
@@ -173,6 +177,7 @@ AlphaTLB::insert(Addr addr, AlphaISA::PTE &pte)
 void
 AlphaTLB::flushAll()
 {
+    DPRINTF(TLB, "flushAll\n");
     memset(table, 0, sizeof(AlphaISA::PTE[size]));
     lookupTable.clear();
     nlu = 0;
@@ -188,13 +193,16 @@ AlphaTLB::flushProcesses()
         AlphaISA::PTE *pte = &table[index];
         assert(pte->valid);
 
+        // we can't increment i after we erase it, so save a copy and
+        // increment it to get the next entry now
+        PageTable::iterator cur = i;
+        ++i;
+
         if (!pte->asma) {
             DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn);
             pte->valid = false;
-            lookupTable.erase(i);
+            lookupTable.erase(cur);
         }
-
-        ++i;
     }
 }
 
@@ -295,7 +303,7 @@ AlphaITB::fault(Addr pc, ExecContext *xc) const
 }
 
 
-Fault
+Fault *
 AlphaITB::translate(MemReqPtr &req) const
 {
     InternalProcReg *ipr = req->xc->regs.ipr;
@@ -304,7 +312,7 @@ AlphaITB::translate(MemReqPtr &req) const
         // strip off PAL PC marker (lsb is 1)
         req->paddr = (req->vaddr & ~3) & PAddrImplMask;
         hits++;
-        return No_Fault;
+        return NoFault;
     }
 
     if (req->flags & PHYSICAL) {
@@ -314,13 +322,13 @@ AlphaITB::translate(MemReqPtr &req) const
         if (!validVirtualAddress(req->vaddr)) {
             fault(req->vaddr, req->xc);
             acv++;
-            return ITB_Acv_Fault;
+            return ItbAcvFault;
         }
 
 
         // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13> for EV5
         // VA<47:41> == 0x7e, VA<40:13> maps directly to PA<40:13> for EV6
-#ifdef ALPHA_TLASER
+#if ALPHA_TLASER
         if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) &&
             VAddrSpaceEV5(req->vaddr) == 2) {
 #else
@@ -331,12 +339,12 @@ AlphaITB::translate(MemReqPtr &req) const
                 AlphaISA::mode_kernel) {
                 fault(req->vaddr, req->xc);
                 acv++;
-                return ITB_Acv_Fault;
+                return ItbAcvFault;
             }
 
             req->paddr = req->vaddr & PAddrImplMask;
 
-#ifndef ALPHA_TLASER
+#if !ALPHA_TLASER
             // sign extend the physical address properly
             if (req->paddr & PAddrUncachedBit40)
                 req->paddr |= ULL(0xf0000000000);
@@ -352,7 +360,7 @@ AlphaITB::translate(MemReqPtr &req) const
             if (!pte) {
                 fault(req->vaddr, req->xc);
                 misses++;
-                return ITB_Fault_Fault;
+                return ItbPageFault;
             }
 
             req->paddr = (pte->ppn << AlphaISA::PageShift) +
@@ -363,7 +371,7 @@ AlphaITB::translate(MemReqPtr &req) const
                 // instruction access fault
                 fault(req->vaddr, req->xc);
                 acv++;
-                return ITB_Acv_Fault;
+                return ItbAcvFault;
             }
 
             hits++;
@@ -372,11 +380,11 @@ AlphaITB::translate(MemReqPtr &req) const
 
     // check that the physical address is ok (catch bad physical addresses)
     if (req->paddr & ~PAddrImplMask)
-        return Machine_Check_Fault;
+        return MachineCheckFault;
 
     checkCacheability(req);
 
-    return No_Fault;
+    return NoFault;
 }
 
 ///////////////////////////////////////////////////////////////////////
@@ -485,7 +493,7 @@ AlphaDTB::fault(MemReqPtr &req, uint64_t flags) const
     }
 }
 
-Fault
+Fault *
 AlphaDTB::translate(MemReqPtr &req, bool write) const
 {
     RegFile *regs = &req->xc->regs;
@@ -501,7 +509,9 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const
      */
     if (req->vaddr & (req->size - 1)) {
         fault(req, write ? MM_STAT_WR_MASK : 0);
-        return Alignment_Fault;
+        DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->vaddr,
+                req->size);
+        return AlignmentFault;
     }
 
     if (pc & 0x1) {
@@ -520,11 +530,11 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const
                   MM_STAT_ACV_MASK);
 
             if (write) { write_acv++; } else { read_acv++; }
-            return DTB_Fault_Fault;
+            return DtbPageFault;
         }
 
         // Check for "superpage" mapping
-#ifdef ALPHA_TLASER
+#if ALPHA_TLASER
         if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) &&
             VAddrSpaceEV5(req->vaddr) == 2) {
 #else
@@ -537,12 +547,12 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const
                 fault(req, ((write ? MM_STAT_WR_MASK : 0) |
                             MM_STAT_ACV_MASK));
                 if (write) { write_acv++; } else { read_acv++; }
-                return DTB_Acv_Fault;
+                return DtbAcvFault;
             }
 
             req->paddr = req->vaddr & PAddrImplMask;
 
-#ifndef ALPHA_TLASER
+#if !ALPHA_TLASER
             // sign extend the physical address properly
             if (req->paddr & PAddrUncachedBit40)
                 req->paddr |= ULL(0xf0000000000);
@@ -565,7 +575,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const
                 fault(req, (write ? MM_STAT_WR_MASK : 0) |
                       MM_STAT_DTB_MISS_MASK);
                 if (write) { write_misses++; } else { read_misses++; }
-                return (req->flags & VPTE) ? Pdtb_Miss_Fault : Ndtb_Miss_Fault;
+                return (req->flags & VPTE) ? (Fault *)PDtbMissFault : (Fault *)NDtbMissFault;
             }
 
             req->paddr = (pte->ppn << AlphaISA::PageShift) +
@@ -578,25 +588,25 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const
                           MM_STAT_ACV_MASK |
                           (pte->fonw ? MM_STAT_FONW_MASK : 0));
                     write_acv++;
-                    return DTB_Fault_Fault;
+                    return DtbPageFault;
                 }
                 if (pte->fonw) {
                     fault(req, MM_STAT_WR_MASK |
                           MM_STAT_FONW_MASK);
                     write_acv++;
-                    return DTB_Fault_Fault;
+                    return DtbPageFault;
                 }
             } else {
                 if (!(pte->xre & MODE2MASK(mode))) {
                     fault(req, MM_STAT_ACV_MASK |
                           (pte->fonr ? MM_STAT_FONR_MASK : 0));
                     read_acv++;
-                    return DTB_Acv_Fault;
+                    return DtbAcvFault;
                 }
                 if (pte->fonr) {
                     fault(req, MM_STAT_FONR_MASK);
                     read_acv++;
-                    return DTB_Fault_Fault;
+                    return DtbPageFault;
                 }
             }
         }
@@ -609,11 +619,11 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const
 
     // check that the physical address is ok (catch bad physical addresses)
     if (req->paddr & ~PAddrImplMask)
-        return Machine_Check_Fault;
+        return MachineCheckFault;
 
     checkCacheability(req);
 
-    return No_Fault;
+    return NoFault;
 }
 
 AlphaISA::PTE &