summaryrefslogtreecommitdiff
path: root/src/cpu/simple
diff options
context:
space:
mode:
authorAli Saidi <Ali.Saidi@ARM.com>2011-05-04 20:38:27 -0500
committerAli Saidi <Ali.Saidi@ARM.com>2011-05-04 20:38:27 -0500
commit6e634beb8acda76085aaef6dbf38aa69b6a6dd4f (patch)
treef27f32f705235ee80309dd188bcc3f24194ac366 /src/cpu/simple
parent89e7bcca822a4690f630393cd400cf3468298fb1 (diff)
downloadgem5-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/cpu/simple')
-rw-r--r--src/cpu/simple/base.hh1
-rw-r--r--src/cpu/simple/timing.cc21
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)) {