ARM: Squash outstanding walks when instructions are squashed.
authorAli Saidi <Ali.Saidi@ARM.com>
Tue, 25 Sep 2012 16:49:40 +0000 (11:49 -0500)
committerAli Saidi <Ali.Saidi@ARM.com>
Tue, 25 Sep 2012 16:49:40 +0000 (11:49 -0500)
src/arch/arm/ArmTLB.py
src/arch/arm/table_walker.cc
src/arch/arm/table_walker.hh
src/cpu/simple/timing.hh
src/cpu/translation.hh
src/sim/tlb.hh

index 9572d20915f108d4b12f12ad3f4685ba4bfc0557..0a931b7e548a474fcf0dde5e8d257d2c237f81b3 100644 (file)
@@ -47,6 +47,8 @@ class ArmTableWalker(MemObject):
     cxx_class = 'ArmISA::TableWalker'
     port = MasterPort("Port for TableWalker to do walk the translation with")
     sys = Param.System(Parent.any, "system object parameter")
+    num_squash_per_cycle = Param.Unsigned(2,
+            "Number of outstanding walks that can be squashed per cycle")
 
 class ArmTLB(SimObject):
     type = 'ArmTLB'
index 77cc662b30292c89ca9aca96ab52a72bf041ccc8..dbd4211d5bbc7ac0589c89f9c39aab28d423c815 100644 (file)
@@ -54,6 +54,7 @@ TableWalker::TableWalker(const Params *p)
     : MemObject(p), port(this, params()->sys), drainEvent(NULL),
       tlb(NULL), currState(NULL), pending(false),
       masterId(p->sys->getMasterId(name())),
+      numSquashable(p->num_squash_per_cycle),
       doL1DescEvent(this), doL2DescEvent(this), doProcessEvent(this)
 {
     sctlr = 0;
@@ -184,9 +185,46 @@ TableWalker::processWalkWrapper()
     assert(!currState);
     assert(pendingQueue.size());
     currState = pendingQueue.front();
-    pendingQueue.pop_front();
-    pending = true;
-    processWalk();
+
+
+    if (!currState->transState->squashed()) {
+        // We've got a valid request, lets process it
+        pending = true;
+        pendingQueue.pop_front();
+        processWalk();
+        return;
+    }
+
+
+    // If the instruction that we were translating for has been
+    // squashed we shouldn't bother.
+    unsigned num_squashed = 0;
+    ThreadContext *tc = currState->tc;
+    assert(currState->transState->squashed());
+    while ((num_squashed < numSquashable) && currState &&
+            currState->transState->squashed()) {
+        pendingQueue.pop_front();
+        num_squashed++;
+
+        DPRINTF(TLB, "Squashing table walk for address %#x\n", currState->vaddr);
+
+        // finish the translation which will delete the translation object
+        currState->transState->finish(new UnimpFault("Squashed Inst"),
+                currState->req, currState->tc, currState->mode);
+
+        // delete the current request
+        delete currState;
+
+        // peak at the next one
+        if (pendingQueue.size())
+            currState = pendingQueue.front();
+        else
+            currState = NULL;
+    }
+
+    // if we've still got pending translations schedule more work
+    nextWalk(tc);
+    currState = NULL;
 }
 
 Fault
index b6fee66ffca0381994b1eadad0b25fc610fd223e..509b243395dd96cec69bfd38115cbf0b62377b79 100644 (file)
@@ -380,6 +380,10 @@ class TableWalker : public MemObject
     /** Request id for requests generated by this walker */
     MasterID masterId;
 
+    /** The number of walks belonging to squashed instructions that can be
+     * removed from the pendingQueue per cycle. */
+    unsigned numSquashable;
+
   public:
     typedef ArmTableWalkerParams Params;
     TableWalker(const Params *p);
index 19a4f818e35f00601f7f948dab44df8d8e68654a..a2570abe696df6b7d28d7ce51ee15076744ce008 100644 (file)
@@ -269,6 +269,14 @@ class TimingSimpleCPU : public BaseSimpleCPU
     void completeDataAccess(PacketPtr pkt);
     void advanceInst(Fault fault);
 
+    /** This function is used by the page table walker to determine if it could
+     * translate the a pending request or if the underlying request has been
+     * squashed. This always returns false for the simple timing CPU as it never
+     * executes any instructions speculatively.
+     * @ return Is the current instruction squashed?
+     */
+    bool isSquashed() const { return false; }
+
     /**
      * Print state of address in memory system via PrintReq (for
      * debugging).
index b6bc2182cc4c42ce25cc966cfb4523aaac3217e7..90fffa03d56525116dce21ad5cc8251e31cd6079 100644 (file)
@@ -259,6 +259,12 @@ class DataTranslation : public BaseTLB::Translation
         }
         delete this;
     }
+
+    bool
+    squashed() const
+    {
+        return xc->isSquashed();
+    }
 };
 
 #endif // __CPU_TRANSLATION_HH__
index 379cdd3436bddf293c1b864fc5c669498f882792..0b89c9bd0d5695371601fa7799f0d292c9be468b 100644 (file)
@@ -94,6 +94,13 @@ class BaseTLB : public SimObject
          */
         virtual void finish(Fault fault, RequestPtr req, ThreadContext *tc,
                             Mode mode) = 0;
+
+        /** This function is used by the page table walker to determine if it
+         * should translate the a pending request or if the underlying request
+         * has been squashed.
+         * @ return Is the instruction that requested this translation squashed?
+         */
+        virtual bool squashed() const { return false; }
     };
 };