changeset cf9db1c47a77 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=cf9db1c47a77
description:
        ARM: Don't return the result of a table walk the same cycle it's 
completed.

        The L1 cache may have been accessed to provide this data, which confuses
        it, if it ends up being accesses twice in one cycle. Instead wait 1 tick
        which will force the timing simple CPU to forward to its next clock 
cycle
        when the translation completes.

        Also prevent multiple outstanding table walks from occuring at once.

diffstat:

 src/arch/arm/table_walker.cc |  71 +++++++++++++++++++++++++++++++++++++++----
 src/arch/arm/table_walker.hh |  12 +++++++
 2 files changed, 75 insertions(+), 8 deletions(-)

diffs (192 lines):

diff -r e40fbbe1ed4f -r cf9db1c47a77 src/arch/arm/table_walker.cc
--- a/src/arch/arm/table_walker.cc      Mon Nov 08 13:58:24 2010 -0600
+++ b/src/arch/arm/table_walker.cc      Mon Nov 08 13:58:24 2010 -0600
@@ -41,13 +41,14 @@
 #include "arch/arm/table_walker.hh"
 #include "arch/arm/tlb.hh"
 #include "dev/io_device.hh"
+#include "cpu/base.hh"
 #include "cpu/thread_context.hh"
 
 using namespace ArmISA;
 
 TableWalker::TableWalker(const Params *p)
-    : MemObject(p), port(NULL), tlb(NULL),
-      currState(NULL), doL1DescEvent(this), doL2DescEvent(this)
+    : MemObject(p), port(NULL), tlb(NULL), currState(NULL), pending(false),
+      doL1DescEvent(this), doL2DescEvent(this), doProcessEvent(this)
 {
     sctlr = 0;
 }
@@ -115,6 +116,35 @@
     currState->isFetch = (currState->mode == TLB::Execute);
     currState->isWrite = (currState->mode == TLB::Write);
 
+
+    if (!currState->timing)
+        return processWalk();
+
+    if (pending) {
+        pendingQueue.push_back(currState);
+        currState = NULL;
+    } else {
+        pending = true;
+        processWalk();
+    }
+
+    return NoFault;
+}
+
+void
+TableWalker::processWalkWrapper()
+{
+    assert(!currState);
+    assert(pendingQueue.size());
+    currState = pendingQueue.front();
+    pendingQueue.pop_front();
+    pending = true;
+    processWalk();
+}
+
+Fault
+TableWalker::processWalk()
+{
     Addr ttbr = 0;
 
     // If translation isn't enabled, we shouldn't be here
@@ -146,6 +176,9 @@
         if (currState->timing) {
             currState->transState->finish(f, currState->req,
                                           currState->tc, currState->mode);
+
+            pending = false;
+            nextWalk(currState->tc);
             currState = NULL;
         } else {
             currState->tc = NULL;
@@ -156,7 +189,8 @@
 
     if (currState->timing) {
         port->dmaAction(MemCmd::ReadReq, l1desc_addr, sizeof(uint32_t),
-                &doL1DescEvent, (uint8_t*)&currState->l1Desc.data, (Tick)0);
+                &doL1DescEvent, (uint8_t*)&currState->l1Desc.data,
+                currState->tc->getCpuPtr()->ticks(1));
         DPRINTF(TLBVerbose, "Adding to walker fifo: queue size before adding: 
%d\n",
                 stateQueueL1.size());
         stateQueueL1.push_back(currState);
@@ -167,7 +201,8 @@
            flag = Request::UNCACHEABLE;
         }
         port->dmaAction(MemCmd::ReadReq, l1desc_addr, sizeof(uint32_t),
-                NULL, (uint8_t*)&currState->l1Desc.data, (Tick)0, flag);
+                NULL, (uint8_t*)&currState->l1Desc.data,
+                currState->tc->getCpuPtr()->ticks(1), flag);
         doL1Descriptor();
         f = currState->fault;
     }
@@ -498,10 +533,12 @@
         if (currState->timing) {
             currState->delayed = true;
             port->dmaAction(MemCmd::ReadReq, l2desc_addr, sizeof(uint32_t),
-                    &doL2DescEvent, (uint8_t*)&currState->l2Desc.data, 0);
+                    &doL2DescEvent, (uint8_t*)&currState->l2Desc.data,
+                    currState->tc->getCpuPtr()->ticks(1));
         } else {
             port->dmaAction(MemCmd::ReadReq, l2desc_addr, sizeof(uint32_t),
-                    NULL, (uint8_t*)&currState->l2Desc.data, 0);
+                    NULL, (uint8_t*)&currState->l2Desc.data,
+                    currState->tc->getCpuPtr()->ticks(1));
             doL2Descriptor();
         }
         return;
@@ -589,6 +626,9 @@
         currState->transState->finish(currState->fault, currState->req,
                                       currState->tc, currState->mode);
 
+        pending = false;
+        nextWalk(currState->tc);
+
         currState->req = NULL;
         currState->tc = NULL;
         currState->delayed = false;
@@ -600,10 +640,12 @@
         currState->fault = tlb->translateTiming(currState->req, currState->tc,
                                        currState->transState, currState->mode);
 
+        pending = false;
+        nextWalk(currState->tc);
+
         currState->req = NULL;
         currState->tc = NULL;
         currState->delayed = false;
-
         delete currState;
     } else {
         // need to do L2 descriptor
@@ -633,15 +675,28 @@
                                       currState->transState, currState->mode);
     }
 
+
+    stateQueueL2.pop_front();
+    pending = false;
+    nextWalk(currState->tc);
+
     currState->req = NULL;
     currState->tc = NULL;
     currState->delayed = false;
 
-    stateQueueL2.pop_front();
     delete currState;
     currState = NULL;
 }
 
+void
+TableWalker::nextWalk(ThreadContext *tc)
+{
+    if (pendingQueue.size())
+        schedule(doProcessEvent, tc->getCpuPtr()->nextCycle(curTick+1));
+}
+
+
+
 ArmISA::TableWalker *
 ArmTableWalkerParams::create()
 {
diff -r e40fbbe1ed4f -r cf9db1c47a77 src/arch/arm/table_walker.hh
--- a/src/arch/arm/table_walker.hh      Mon Nov 08 13:58:24 2010 -0600
+++ b/src/arch/arm/table_walker.hh      Mon Nov 08 13:58:24 2010 -0600
@@ -320,6 +320,11 @@
      * require an additional level. */
     std::list<WalkerState *> stateQueueL2;
 
+    /** Queue of requests that have passed are waiting because the walker is
+     * currently busy. */
+    std::list<WalkerState *> pendingQueue;;
+
+
     /** Port to issue translation requests from */
     DmaPort *port;
 
@@ -331,6 +336,9 @@
 
     WalkerState *currState;
 
+    /** If a timing translation is currently in progress */
+    bool pending;
+
   public:
     typedef ArmTableWalkerParams Params;
     TableWalker(const Params *p);
@@ -362,7 +370,11 @@
     void doL2DescriptorWrapper();
     EventWrapper<TableWalker, &TableWalker::doL2DescriptorWrapper> 
doL2DescEvent;
 
+    Fault processWalk();
+    void processWalkWrapper();
+    EventWrapper<TableWalker, &TableWalker::processWalkWrapper> doProcessEvent;
 
+    void nextWalk(ThreadContext *tc);
 };
 
 
_______________________________________________
m5-dev mailing list
m5-dev@m5sim.org
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to