Get software prefetching to work in full-system mode.
authorSteve Reinhardt <stever@eecs.umich.edu>
Tue, 15 Jun 2004 17:48:08 +0000 (10:48 -0700)
committerSteve Reinhardt <stever@eecs.umich.edu>
Tue, 15 Jun 2004 17:48:08 +0000 (10:48 -0700)
Mostly a matter of keeping prefetches to invalid addrs
from messing up VM IPRs.  Also discovered that wh64s were
not being treated as prefetches, when they really should be
(for the most part, anyway).

arch/alpha/alpha_memory.cc:
arch/alpha/alpha_memory.hh:
    - Get rid of intrlock flag for locking VM fault regs (a la EV5);
    instead, just don't update regs on VPTE loads (a la EV6).
    - Add NO_FAULT MemReq flag to indicate references that should not
    cause page faults (i.e., prefetches).
arch/alpha/ev5.cc:
    - Get rid of intrlock flag for locking VM fault regs (a la EV5);
    instead, just don't update regs on VPTE loads (a la EV6).
    - Add Fault trace flag.
arch/alpha/isa_desc:
    - Add NO_FAULT MemReq flag to indicate references that should not
    cause page faults (i.e., prefetches).
    - Mark wh64 as a "data prefetch" instruction so it gets controlled
    properly by the FullCPU data prefetch control switch.
    - Align wh64 EA in decoder so issue stage doesn't need to worry about it.
arch/alpha/isa_traits.hh:
    - Get rid of intrlock flag for locking VM fault regs (a la EV5);
    instead, just don't update regs on VPTE loads (a la EV6).
base/traceflags.py:
    - Add Fault trace flag.
cpu/simple_cpu/simple_cpu.hh:
    - Pass MemReq flags to writeHint() operation.
cpu/static_inst.hh:
    Update comment re: prefetches.

--HG--
extra : convert_revision : 62e466b0f4c0ff9961796270fa2e371ec24bcbb6

arch/alpha/alpha_memory.cc
arch/alpha/alpha_memory.hh
arch/alpha/ev5.cc
arch/alpha/isa_desc
arch/alpha/isa_traits.hh
base/traceflags.py
cpu/simple_cpu/simple_cpu.hh
cpu/static_inst.hh

index 23815bf01b722ae4cd59821ba2f21ff4c343d1ad..58aa13b8fc93f7e8bad5d26e7f47e627a9450be7 100644 (file)
@@ -415,12 +415,19 @@ AlphaDTB::regStats()
 }
 
 void
-AlphaDTB::fault(Addr vaddr, uint64_t flags, ExecContext *xc) const
+AlphaDTB::fault(MemReqPtr &req, uint64_t flags) const
 {
+    ExecContext *xc = req->xc;
+    Addr vaddr = req->vaddr;
     uint64_t *ipr = xc->regs.ipr;
 
-    // set fault address and flags
-    if (!xc->misspeculating() && !xc->regs.intrlock) {
+    // 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 (!xc->misspeculating()
+        && !(req->flags & VPTE) && !(req->flags & NO_FAULT)) {
         // set VA register with faulting address
         ipr[AlphaISA::IPR_VA] = vaddr;
 
@@ -432,9 +439,6 @@ AlphaDTB::fault(Addr vaddr, uint64_t flags, ExecContext *xc) const
         // set VA_FORM register with faulting formatted address
         ipr[AlphaISA::IPR_VA_FORM] =
             ipr[AlphaISA::IPR_MVPTBR] | (VA_VPN(vaddr) << 3);
-
-        // lock these registers until the VA register is read
-        xc->regs.intrlock = true;
     }
 }
 
@@ -459,10 +463,8 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const
     } else {
         // verify that this is a good virtual address
         if (!validVirtualAddress(req->vaddr)) {
-            fault(req->vaddr,
-                  ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK |
-                   MM_STAT_ACV_MASK),
-                  req->xc);
+            fault(req, ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK |
+                        MM_STAT_ACV_MASK));
 
             if (write) { write_acv++; } else { read_acv++; }
             return DTB_Fault_Fault;
@@ -476,9 +478,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const
             // only valid in kernel mode
             if (DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]) !=
                 AlphaISA::mode_kernel) {
-                fault(req->vaddr,
-                      ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK),
-                      req->xc);
+                fault(req, ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK));
                 if (write) { write_acv++; } else { read_acv++; }
                 return DTB_Acv_Fault;
             }
@@ -496,9 +496,8 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const
 
             if (!pte) {
                 // page fault
-                fault(req->vaddr,
-                      ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK),
-                      req->xc);
+                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;
             }
@@ -508,29 +507,25 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const
             if (write) {
                 if (!(pte->xwe & MODE2MASK(mode))) {
                     // declare the instruction access fault
-                    fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_ACV_MASK |
-                          (pte->fonw ? MM_STAT_FONW_MASK : 0),
-                          req->xc);
+                    fault(req, (MM_STAT_WR_MASK | MM_STAT_ACV_MASK |
+                                (pte->fonw ? MM_STAT_FONW_MASK : 0)));
                     write_acv++;
                     return DTB_Fault_Fault;
                 }
                 if (pte->fonw) {
-                    fault(req->vaddr, MM_STAT_WR_MASK | MM_STAT_FONW_MASK,
-                          req->xc);
+                    fault(req, MM_STAT_WR_MASK | MM_STAT_FONW_MASK);
                     write_acv++;
                     return DTB_Fault_Fault;
                 }
             } else {
                 if (!(pte->xre & MODE2MASK(mode))) {
-                    fault(req->vaddr,
-                          MM_STAT_ACV_MASK |
-                          (pte->fonr ? MM_STAT_FONR_MASK : 0),
-                          req->xc);
+                    fault(req, (MM_STAT_ACV_MASK |
+                                (pte->fonr ? MM_STAT_FONR_MASK : 0)));
                     read_acv++;
                     return DTB_Acv_Fault;
                 }
                 if (pte->fonr) {
-                    fault(req->vaddr, MM_STAT_FONR_MASK, req->xc);
+                    fault(req, MM_STAT_FONR_MASK);
                     read_acv++;
                     return DTB_Fault_Fault;
                 }
index b5fc18255239160fd65acefd62b39f9e4373fcd7..fbd6ecf155df0f58faf1ccdac30878412025e638 100644 (file)
@@ -112,7 +112,7 @@ class AlphaDTB : public AlphaTLB
     Stats::Formula accesses;
 
   protected:
-    void fault(Addr pc, uint64_t flags, ExecContext *xc) const;
+    void fault(MemReqPtr &req, uint64_t flags) const;
 
   public:
     AlphaDTB(const std::string &name, int size);
index ecf66f4f51ef890be76dd7280cb97c0ff93e0165..d2ca71b3a020da54db4a688c3d899855d3515d8f 100644 (file)
@@ -162,6 +162,7 @@ AlphaISA::zeroRegisters(XC *xc)
 void
 ExecContext::ev5_trap(Fault fault)
 {
+    DPRINTF(Fault, "Fault %s\n", FaultName(fault));
     Stats::recordEvent(csprintf("Fault %s", FaultName(fault)));
 
     assert(!misspeculating());
@@ -302,11 +303,7 @@ ExecContext::readIpr(int idx, Fault &fault)
         break;
 
       case AlphaISA::IPR_VA:
-        // SFX: unlocks interrupt status registers
         retval = ipr[idx];
-
-        if (!misspeculating())
-            regs.intrlock = false;
         break;
 
       case AlphaISA::IPR_VA_FORM:
index 9fee124850db346e94c35b67f25b8ff3844dab86..6c5912c528c81e4084051ffa01cc9b11c94456f2 100644 (file)
@@ -1023,7 +1023,7 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code = '',
     # and memory access flags (handled here).
 
     # Would be nice to autogenerate this list, but oh well.
-    valid_mem_flags = ['LOCKED', 'EVICT_NEXT', 'PF_EXCLUSIVE']
+    valid_mem_flags = ['LOCKED', 'NO_FAULT', 'EVICT_NEXT', 'PF_EXCLUSIVE']
     inst_flags = []
     mem_flags = []
     for f in flags:
@@ -1072,7 +1072,7 @@ def format LoadOrPrefetch(ea_code, memacc_code, *pf_flags) {{
     # Declare the prefetch instruction object.
 
     # convert flags from tuple to list to make them mutable
-    pf_flags = list(pf_flags) + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'MemReadOp']
+    pf_flags = list(pf_flags) + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'MemReadOp', 'NO_FAULT']
 
     (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
        LoadStoreBase(name, Name + 'Prefetch', ea_code, '',
@@ -2369,9 +2369,10 @@ decode OPCODE default Unknown::unknown() {
        }
 
        format MiscPrefetch {
-           0xf800: wh64({{ EA = Rb; }},
-                        {{ xc->writeHint(EA, 64); }},
-                        IsMemRef, IsStore, MemWriteOp);
+           0xf800: wh64({{ EA = Rb & ~ULL(63); }},
+                        {{ xc->writeHint(EA, 64, memAccessFlags); }},
+                        IsMemRef, IsDataPrefetch, IsStore, MemWriteOp,
+                        NO_FAULT);
        }
 
        format BasicOperate {
index 37ba77192be5685d0960f2b289160290a8269fb1..1a8ff663b54cde1c3f964d780a173a4b61717b88 100644 (file)
@@ -153,7 +153,6 @@ class AlphaISA
 #ifdef FULL_SYSTEM
         IntReg palregs[NumIntRegs];    // PAL shadow registers
         InternalProcReg ipr[NumInternalProcRegs]; // internal processor regs
-        int intrlock;                  // interrupt register lock flag
         int intrflag;                  // interrupt flag
         bool pal_shadow;               // using pal_shadow registers
 #endif // FULL_SYSTEM
index 69f4e7ab851ec075b46a4d42a3117bbda8340d7f..a01eae3eb32b59721fb81070da2fd1e199eb24d3 100644 (file)
@@ -66,6 +66,7 @@ baseFlags = [
     'AlphaConsole',
     'Flow',
     'Interrupt',
+    'Fault',
     'Cycle',
     'Loader',
     'MMU',
index 1c6b18d039ae0acbcf77d9e34a89d89e023128ed..545c753f0a0980a2daff2ae48b19153521c2d830 100644 (file)
@@ -253,7 +253,7 @@ class SimpleCPU : public BaseCPU
         // need to do this...
     }
 
-    void writeHint(Addr addr, int size)
+    void writeHint(Addr addr, int size, unsigned flags)
     {
         // need to do this...
     }
index 3eeefb6756684038aa5f803ae1297e98076b5112..68c30df2f63bcce5f287cb15fa6b626062e04e60 100644 (file)
@@ -72,8 +72,7 @@ class StaticInstBase : public RefCounted
     /// unconditional branches, memory barriers) or both (e.g., an
     /// FP/int conversion).
     /// - If IsMemRef is set, then exactly one of IsLoad or IsStore
-    /// will be set.  Prefetches are marked as IsLoad, even if they
-    /// prefetch exclusive copies.
+    /// will be set.
     /// - If IsControl is set, then exactly one of IsDirectControl or
     /// IsIndirect Control will be set, and exactly one of
     /// IsCondControl or IsUncondControl will be set.