CPU: Fix a case where timing simple cpu faults can nest.
authorAli Saidi <Ali.Saidi@ARM.com>
Thu, 5 May 2011 01:38:27 +0000 (20:38 -0500)
committerAli Saidi <Ali.Saidi@ARM.com>
Thu, 5 May 2011 01:38:27 +0000 (20:38 -0500)
If we fault, change the state to faulting so that we don't fault again in the same cycle.

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

index 2696cc395e2e57dda53e3bc1f77f049086132ea8..0cc90645f060efcb8ab5bbba3c20c102457e8c23 100644 (file)
@@ -124,6 +124,7 @@ class BaseSimpleCPU : public BaseCPU
     enum Status {
         Idle,
         Running,
+        Faulting,
         ITBWaitResponse,
         IcacheRetry,
         IcacheWaitResponse,
index c992cb0b58f6b1489958d0d46311acb0af72da79..59bf949b01eae59e582dfc7f5ef99bb38c86a900 100644 (file)
@@ -725,6 +725,7 @@ TimingSimpleCPU::fetch()
     bool needToFetch = !isRomMicroPC(pcState.microPC()) && !curMacroStaticInst;
 
     if (needToFetch) {
+        _status = Running;
         Request *ifetch_req = new Request();
         ifetch_req->setThreadContext(_cpuId, /* thread ID */ 0);
         setupFetchRequest(ifetch_req);
@@ -771,7 +772,20 @@ TimingSimpleCPU::sendFetch(Fault fault, RequestPtr req, ThreadContext *tc)
 void
 TimingSimpleCPU::advanceInst(Fault fault)
 {
-    if (fault != NoFault || !stayAtPC)
+
+    if (_status == Faulting)
+        return;
+
+    if (fault != NoFault) {
+        advancePC(fault);
+        DPRINTF(SimpleCPU, "Fault occured, scheduling fetch event\n");
+        reschedule(fetchEvent, nextCycle(), true);
+        _status = Faulting;
+        return;
+    }
+
+
+    if (!stayAtPC)
         advancePC(fault);
 
     if (_status == Running) {
@@ -786,8 +800,6 @@ TimingSimpleCPU::advanceInst(Fault fault)
 void
 TimingSimpleCPU::completeIfetch(PacketPtr pkt)
 {
-    DPRINTF(SimpleCPU, "Complete ICache Fetch\n");
-
     // received a response from the icache: execute the received
     // instruction
 
@@ -878,8 +890,7 @@ TimingSimpleCPU::IcachePort::recvTiming(PacketPtr pkt)
             tickEvent.schedule(pkt, next_tick);
 
         return true;
-    }
-    else if (pkt->wasNacked()) {
+    } else if (pkt->wasNacked()) {
         assert(cpu->_status == IcacheWaitResponse);
         pkt->reinitNacked();
         if (!sendTiming(pkt)) {