summaryrefslogtreecommitdiff
path: root/src/cpu/inorder/cpu.cc
diff options
context:
space:
mode:
authorKorey Sewell <ksewell@umich.edu>2011-06-19 21:43:40 -0400
committerKorey Sewell <ksewell@umich.edu>2011-06-19 21:43:40 -0400
commitf1c3691356355d2ca865e48e91814c56293f6326 (patch)
tree6608284d5bcdab42d69042034d49198c647b1a2c /src/cpu/inorder/cpu.cc
parent0bfdf342da40842a05351d53a384db4a8ff88bf5 (diff)
downloadgem5-f1c3691356355d2ca865e48e91814c56293f6326.tar.xz
inorder: check for interrupts each tick
use a dummy instruction to facilitate the squash after the interrupts trap
Diffstat (limited to 'src/cpu/inorder/cpu.cc')
-rw-r--r--src/cpu/inorder/cpu.cc49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc
index 232bf8279..2623c6c1d 100644
--- a/src/cpu/inorder/cpu.cc
+++ b/src/cpu/inorder/cpu.cc
@@ -350,6 +350,16 @@ InOrderCPU::InOrderCPU(Params *params)
asid[tid]);
dummyReq[tid] = new ResourceRequest(resPool->getResource(0));
+
+#if FULL_SYSTEM
+ // Use this dummy inst to force squashing behind every instruction
+ // in pipeline
+ dummyTrapInst[tid] = new InOrderDynInst(this, NULL, 0, 0, 0);
+ dummyTrapInst[tid]->seqNum = 0;
+ dummyTrapInst[tid]->squashSeqNum = 0;
+ dummyTrapInst[tid]->setTid(tid);
+#endif
+
}
dummyReqInst = new InOrderDynInst(this, NULL, 0, 0, 0);
@@ -687,6 +697,8 @@ InOrderCPU::tick()
pipes_idle = pipes_idle && pipelineStage[stNum]->idle;
}
+ checkForInterrupts();
+
if (pipes_idle)
idleCycles++;
else
@@ -800,6 +812,43 @@ InOrderCPU::simPalCheck(int palFunc, ThreadID tid)
return true;
}
+void
+InOrderCPU::checkForInterrupts()
+{
+ for (int i = 0; i < threadContexts.size(); i++) {
+ ThreadContext *tc = threadContexts[i];
+
+ if (interrupts->checkInterrupts(tc)) {
+ Fault interrupt = interrupts->getInterrupt(tc);
+
+ if (interrupt != NoFault) {
+ DPRINTF(Interrupt, "Processing Intterupt for [tid:%i].\n",
+ tc->threadId());
+
+ ThreadID tid = tc->threadId();
+ interrupts->updateIntrInfo(tc);
+
+ // Squash from Last Stage in Pipeline
+ unsigned last_stage = NumStages - 1;
+ dummyTrapInst[tid]->squashingStage = last_stage;
+ pipelineStage[last_stage]->setupSquash(dummyTrapInst[tid],
+ tid);
+
+ // By default, setupSquash will always squash from stage + 1
+ pipelineStage[BackEndStartStage - 1]->setupSquash(dummyTrapInst[tid],
+ tid);
+
+ // Schedule Squash Through-out Resource Pool
+ resPool->scheduleEvent(
+ (InOrderCPU::CPUEventType)ResourcePool::SquashAll,
+ dummyTrapInst[tid], 0);
+
+ // Finally, Setup Trap to happen at end of cycle
+ trapContext(interrupt, tid, dummyTrapInst[tid]);
+ }
+ }
+ }
+}
Fault
InOrderCPU::getInterrupts()