O3: Fixes the way prefetches are handled inside the iew unit.
authorMatt Horsnell <Matt.Horsnell@arm.com>
Tue, 18 Jan 2011 22:30:02 +0000 (16:30 -0600)
committerMatt Horsnell <Matt.Horsnell@arm.com>
Tue, 18 Jan 2011 22:30:02 +0000 (16:30 -0600)
This patch prevents the prefetch being added to the instCommit queue twice.

src/arch/arm/faults.hh
src/arch/arm/tlb.cc
src/cpu/o3/iew_impl.hh

index 6c1b223abaf8c67d92be53062fba4b2395449cce..633e74eae83044de5d59d597958b79d6eb121992 100644 (file)
@@ -92,7 +92,8 @@ class ArmFault : public FaultBase
         // to allow the translation function to inform
         // the memory access function not to proceed
         // for a Prefetch that misses in the TLB.
-        PrefetchTLBMiss
+        PrefetchTLBMiss = 0x1f,
+        PrefetchUncacheable = 0x20
     };
 
     struct FaultVals
index f142e03f82911b66c6c20907932c943baee531b8..e5f5b36f630a9b33e9cd98ae91ecb0a19fbae045 100644 (file)
@@ -556,9 +556,15 @@ TLB::translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
             outerAttrs: %d\n",
             te->shareable, te->innerAttrs, te->outerAttrs);
     setAttr(te->attributes);
-    if (te->nonCacheable)
+    if (te->nonCacheable) {
         req->setFlags(Request::UNCACHEABLE);
 
+        // Prevent prefetching from I/O devices.
+        if (req->isPrefetch()) {
+            return new PrefetchAbort(vaddr, ArmFault::PrefetchUncacheable);
+        }
+    }
+
     switch ( (dacr >> (te->domain * 2)) & 0x3) {
       case 0:
         domainFaults++;
index e1af2085244a78c25ca0fc78e9a6d914a5dfdbd2..3f53b4197068a0d59d912a0cee0454258d9daf08 100644 (file)
@@ -1222,8 +1222,7 @@ DefaultIEW<Impl>::executeInsts()
         // Execute instruction.
         // Note that if the instruction faults, it will be handled
         // at the commit stage.
-        if (inst->isMemRef() &&
-            (!inst->isDataPrefetch() && !inst->isInstPrefetch())) {
+        if (inst->isMemRef()) {
             DPRINTF(IEW, "Execute: Calculating address for memory "
                     "reference.\n");
 
@@ -1232,6 +1231,9 @@ DefaultIEW<Impl>::executeInsts()
                 // Loads will mark themselves as executed, and their writeback
                 // event adds the instruction to the queue to commit
                 fault = ldstQueue.executeLoad(inst);
+                if (inst->isDataPrefetch() || inst->isInstPrefetch()) {
+                    fault = NoFault;
+                }
             } else if (inst->isStore()) {
                 fault = ldstQueue.executeStore(inst);