ARM: Make sure that software prefetch instructions can't change the state of the TLB
authorGene Wu <Gene.Wu@arm.com>
Mon, 23 Aug 2010 16:18:41 +0000 (11:18 -0500)
committerGene Wu <Gene.Wu@arm.com>
Mon, 23 Aug 2010 16:18:41 +0000 (11:18 -0500)
src/arch/arm/faults.hh
src/arch/arm/table_walker.cc
src/arch/arm/tlb.cc
src/mem/cache/cache_impl.hh

index d8684792c92ea587482c2a2dc8fda90ebbce6d63..f9d25abdf34618b684740ce7560a77eb8fbc9288 100644 (file)
@@ -87,6 +87,12 @@ class ArmFault : public FaultBase
         MemoryAccessSynchronousParityError = 0x19,
         TranslationTableWalkPrtyErr0 = 0x1c,
         TranslationTableWalkPrtyErr1 = 0x1e,
+
+        // not a real fault. This is a status code
+        // to allow the translation function to inform
+        // the memory access function not to proceed
+        // for a Prefetch that misses in the TLB.
+        PrefetchTLBMiss
     };
 
     struct FaultVals
index 6dcb387a3656a55f611e4c102dbbb74a06b8711d..1d363c66ff3d405655556c373173f6974dca2777 100644 (file)
@@ -439,11 +439,10 @@ TableWalker::doL1Descriptor()
               * AccessFlag0
               */
 
-            currState->fault =
-                new DataAbort(currState->vaddr, NULL, currState->isWrite,
+            currState->fault = new DataAbort(currState->vaddr,
+                                    currState->l1Desc.domain(), currState->isWrite,
                                     ArmFault::AccessFlag0);
         }
-
         if (currState->l1Desc.supersection()) {
             panic("Haven't implemented supersections\n");
         }
index da2a34084e8badc00acc36d1ba8889598f1e1df9..a70a20518ce5b4b8826a7b57b75ca4824afadee9 100644 (file)
@@ -409,6 +409,11 @@ TLB::translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
 
     TlbEntry *te = lookup(vaddr, context_id);
     if (te == NULL) {
+        if (req->isPrefetch()){
+           //if the request is a prefetch don't attempt to fill the TLB
+           //or go any further with the memory access
+           return new PrefetchAbort(vaddr, ArmFault::PrefetchTLBMiss);
+        }
         // start translation table walk, pass variables rather than
         // re-retreaving in table walker for speed
         DPRINTF(TLB, "TLB Miss: Starting hardware table walker for %#x(%d)\n",
index bf2901d3691477ce2cdf35d0ed5812d1dbe0c07c..e472b2601245ec4ce126674fa8aa0fde47a0a26f 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2010 ARM Limited
+ * All rights reserved.
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2002-2005 The Regents of The University of Michigan
  * Copyright (c) 2010 Advanced Micro Devices, Inc.
  * All rights reserved.
@@ -261,14 +273,19 @@ bool
 Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk,
                         int &lat, PacketList &writebacks)
 {
+    int id = pkt->req->hasContextId() ? pkt->req->contextId() : -1;
+    blk = tags->accessBlock(pkt->getAddr(), lat, id);
+
     if (pkt->req->isUncacheable())  {
+        if (blk != NULL) {
+            tags->invalidateBlk(blk);
+        }
+
         blk = NULL;
         lat = hitLatency;
         return false;
     }
 
-    int id = pkt->req->hasContextId() ? pkt->req->contextId() : -1;
-    blk = tags->accessBlock(pkt->getAddr(), lat, id);
 
     DPRINTF(Cache, "%s%s %x %s\n", pkt->cmdString(),
             pkt->req->isInstFetch() ? " (ifetch)" : "",
@@ -393,6 +410,13 @@ Cache<TagStore>::timingAccess(PacketPtr pkt)
     }
 
     if (pkt->req->isUncacheable()) {
+        int lat = hitLatency;
+        int id = pkt->req->hasContextId() ? pkt->req->contextId() : -1;
+        BlkType *blk = tags->accessBlock(pkt->getAddr(), lat, id);
+        if (blk != NULL) {
+            tags->invalidateBlk(blk);
+        }
+
         // writes go in write buffer, reads use MSHR
         if (pkt->isWrite() && !pkt->isRead()) {
             allocateWriteBuffer(pkt, time, true);
@@ -532,7 +556,7 @@ Cache<TagStore>::getBusPacket(PacketPtr cpu_pkt, BlkType *blk,
     bool blkValid = blk && blk->isValid();
 
     if (cpu_pkt->req->isUncacheable()) {
-        assert(blk == NULL);
+        //assert(blk == NULL);
         return NULL;
     }