diff options
author | Ali Saidi <Ali.Saidi@ARM.com> | 2011-05-04 20:38:27 -0500 |
---|---|---|
committer | Ali Saidi <Ali.Saidi@ARM.com> | 2011-05-04 20:38:27 -0500 |
commit | 6e634beb8acda76085aaef6dbf38aa69b6a6dd4f (patch) | |
tree | f27f32f705235ee80309dd188bcc3f24194ac366 /src | |
parent | 89e7bcca822a4690f630393cd400cf3468298fb1 (diff) | |
download | gem5-6e634beb8acda76085aaef6dbf38aa69b6a6dd4f.tar.xz |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/cpu/simple/base.hh | 1 | ||||
-rw-r--r-- | 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)) { |