SimpleCPU: Fix a case where a DTLB fault redirects fetch and an I-side walk occurs.
authorAli Saidi <Ali.Saidi@ARM.com>
Sat, 12 Feb 2011 00:29:35 +0000 (18:29 -0600)
committerAli Saidi <Ali.Saidi@ARM.com>
Sat, 12 Feb 2011 00:29:35 +0000 (18:29 -0600)
This change fixes an issue where a DTLB fault occurs and redirects fetch to
handle the fault and the ITLB requires a walk which delays translation. In this
case the status of the cpu isn't updated appropriately, and an additional
instruction fetch occurs. Eventually this hits an assert as multiple instruction
fetches are occuring in the system and when the second one returns the
processor is in the wrong state.

Some asserts below are removed because it was always true (typo) and the state
after the initiateAcc() the processor could be in any valid state when a
d-side fault occurs.

src/cpu/simple/timing.cc
src/cpu/simple/timing.hh

index 453699f84178cbde228c26646e1b2a18e6981e74..ab1ff91e8b7d029de4ddd78ed560fb42830bd871 100644 (file)
@@ -752,6 +752,7 @@ TimingSimpleCPU::sendFetch(Fault fault, RequestPtr req, ThreadContext *tc)
     } else {
         delete req;
         // fetch fault: advance directly to next instruction (fault handler)
+        _status = Running;
         advanceInst(fault);
     }
 
@@ -805,12 +806,11 @@ TimingSimpleCPU::completeIfetch(PacketPtr pkt)
     if (curStaticInst && curStaticInst->isMemRef()) {
         // load or store: just send to dcache
         Fault fault = curStaticInst->initiateAcc(this, traceData);
-        if (_status != Running) {
-            // instruction will complete in dcache response callback
-            assert(_status == DcacheWaitResponse ||
-                    _status == DcacheRetry || DTBWaitResponse);
-            assert(fault == NoFault);
-        } else {
+
+        // If we're not running now the instruction will complete in a dcache
+        // response callback or the instruction faulted and has started an
+        // ifetch
+        if (_status == Running) {
             if (fault != NoFault && traceData) {
                 // If there was a fault, we shouldn't trace this instruction.
                 delete traceData;
index 098db5f5a0dfa5c22f3e9ae08761fbaf72540175..a7a3eb7c3c0c965d732f450ce6be2b91dc088f4b 100644 (file)
@@ -109,7 +109,10 @@ class TimingSimpleCPU : public BaseSimpleCPU
 
         void
         markDelayed()
-        {}
+        {
+            assert(cpu->_status == Running);
+            cpu->_status = ITBWaitResponse;
+        }
 
         void
         finish(Fault fault, RequestPtr req, ThreadContext *tc,