From 6e634beb8acda76085aaef6dbf38aa69b6a6dd4f Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 4 May 2011 20:38:27 -0500 Subject: [PATCH] CPU: Fix a case where timing simple cpu faults can nest. If we fault, change the state to faulting so that we don't fault again in the same cycle. --- src/cpu/simple/base.hh | 1 + src/cpu/simple/timing.cc | 21 ++++++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index 2696cc395..0cc90645f 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -124,6 +124,7 @@ class BaseSimpleCPU : public BaseCPU enum Status { Idle, Running, + Faulting, ITBWaitResponse, IcacheRetry, IcacheWaitResponse, diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index c992cb0b5..59bf949b0 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -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)) {