ARM: Fix bug that let two table walks occur in parallel.
authorAli Saidi <Ali.Saidi@ARM.com>
Wed, 23 Feb 2011 21:10:49 +0000 (15:10 -0600)
committerAli Saidi <Ali.Saidi@ARM.com>
Wed, 23 Feb 2011 21:10:49 +0000 (15:10 -0600)
src/arch/arm/table_walker.cc
src/arch/arm/tlb.cc
src/cpu/o3/commit_impl.hh

index e6dd728dda3d27579a76745af7b2a641469669c9..e2207e26ba9180b05e1519b2a9348b67cec05245 100644 (file)
@@ -141,12 +141,12 @@ TableWalker::walk(RequestPtr _req, ThreadContext *_tc, uint8_t _cid, TLB::Mode _
     if (!currState->timing)
         return processWalk();
 
-    if (pending) {
+    if (pending || pendingQueue.size()) {
         pendingQueue.push_back(currState);
         currState = NULL;
     } else {
         pending = true;
-        processWalk();
+        return processWalk();
     }
 
     return NoFault;
@@ -194,10 +194,8 @@ TableWalker::processWalk()
     f = tlb->walkTrickBoxCheck(l1desc_addr, currState->vaddr, sizeof(uint32_t),
             currState->isFetch, currState->isWrite, 0, true);
     if (f) {
+        DPRINTF(TLB, "Trickbox check caused fault on %#x\n", currState->vaddr);
         if (currState->timing) {
-            currState->transState->finish(f, currState->req,
-                                          currState->tc, currState->mode);
-
             pending = false;
             nextWalk(currState->tc);
             currState = NULL;
index 230c562001377b066e9a086d3fa959d8244b1dfb..f1c8ae41a56622d476702820c268b73a5991744b 100644 (file)
@@ -529,7 +529,7 @@ TLB::translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
                 vaddr, contextId);
         fault = tableWalker->walk(req, tc, contextId, mode, translation,
                 timing);
-        if (timing) {
+        if (timing && fault == NoFault) {
             delay = true;
             // for timing mode, return and wait for table walk
             return fault;
@@ -694,6 +694,8 @@ TLB::translateTiming(RequestPtr req, ThreadContext *tc,
 #else
     fault = translateSe(req, tc, mode, translation, delay, true);
 #endif
+    DPRINTF(TLB, "Translation returning delay=%d fault=%d\n", delay, fault !=
+            NoFault);
     if (!delay)
         translation->finish(fault, req, tc, mode);
     else
index 50c08e1622dc37fd427f1a7ff57d2fc4feffe650..01e235722e7c2dbce072f0394dc049a3b0b189d0 100644 (file)
@@ -1142,6 +1142,8 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
 
         commitStatus[tid] = TrapPending;
 
+        DPRINTF(Commit, "Committing instruction with fault [sn:%lli]\n",
+            head_inst->seqNum);
         if (head_inst->traceData) {
             if (DTRACE(ExecFaulting)) {
                 head_inst->traceData->setFetchSeq(head_inst->seqNum);