summaryrefslogtreecommitdiff
path: root/src/cpu/inorder
diff options
context:
space:
mode:
authorChristopher Torng <clt67@cornell.edu>2014-03-01 23:35:23 -0600
committerChristopher Torng <clt67@cornell.edu>2014-03-01 23:35:23 -0600
commit919baa603d0b835c3202f9968a617a31f9116549 (patch)
treee5e075957313bbe9a9630b84e64c86545351e264 /src/cpu/inorder
parenta533f3f9831081625626f96f9434a00f3079e98e (diff)
downloadgem5-919baa603d0b835c3202f9968a617a31f9116549.tar.xz
cpu: Enable fast-forwarding for MIPS InOrderCPU and O3CPU
A copyRegs() function is added to MIPS utilities to copy architectural state from the old CPU to the new CPU during fast-forwarding. This addition alone enables fast-forwarding for the o3 cpu model running MIPS. The patch also adds takeOverFrom() and drainResume() functions to the InOrderCPU to enable it to take over from another CPU. This change enables fast-forwarding for the inorder cpu model running MIPS, but not for Alpha. Committed by: Nilay Vaish <nilay@cs.wisc.edu>
Diffstat (limited to 'src/cpu/inorder')
-rw-r--r--src/cpu/inorder/InOrderCPU.py4
-rw-r--r--src/cpu/inorder/cpu.cc62
-rw-r--r--src/cpu/inorder/cpu.hh9
-rw-r--r--src/cpu/inorder/first_stage.cc10
-rw-r--r--src/cpu/inorder/first_stage.hh3
-rw-r--r--src/cpu/inorder/pipeline_stage.hh2
6 files changed, 89 insertions, 1 deletions
diff --git a/src/cpu/inorder/InOrderCPU.py b/src/cpu/inorder/InOrderCPU.py
index 4caf254c4..920b9cdc1 100644
--- a/src/cpu/inorder/InOrderCPU.py
+++ b/src/cpu/inorder/InOrderCPU.py
@@ -47,6 +47,10 @@ class InOrderCPU(BaseCPU):
def require_caches(cls):
return True
+ @classmethod
+ def support_take_over(cls):
+ return True
+
threadModel = Param.ThreadModel('SMT', "Multithreading model (SE-MODE only)")
cachePorts = Param.Unsigned(2, "Cache Ports")
diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc
index 5a02f94d9..eecbd033e 100644
--- a/src/cpu/inorder/cpu.cc
+++ b/src/cpu/inorder/cpu.cc
@@ -64,6 +64,7 @@
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
#include "debug/Activity.hh"
+#include "debug/Drain.hh"
#include "debug/InOrderCPU.hh"
#include "debug/InOrderCachePort.hh"
#include "debug/Interrupt.hh"
@@ -1490,6 +1491,67 @@ InOrderCPU::updateContextSwitchStats()
instsPerSwitch = 0;
}
+
+void
+InOrderCPU::drainResume()
+{
+ setDrainState(Drainable::Running);
+ if (switchedOut())
+ return;
+
+ DPRINTF(Drain, "Resuming...\n");
+ verifyMemoryMode();
+
+ assert(!tickEvent.scheduled());
+
+ // Activate threads and also signal the resource pool to activate
+ // the thread on all resources.
+ _status = Idle;
+ for (ThreadID i = 0; i < thread.size(); i++) {
+ if (thread[i]->status() == ThreadContext::Active) {
+ DPRINTF(Drain, "Activating thread: %i\n", i);
+ activateThread(i);
+ resPool->activateThread(i);
+ _status = Running;
+ }
+ }
+}
+
+void
+InOrderCPU::switchOut()
+{
+ DPRINTF(InOrderCPU, "Switching out\n");
+ BaseCPU::switchOut();
+
+ activityRec.reset();
+
+ _status = SwitchedOut;
+}
+
+void
+InOrderCPU::takeOverFrom(BaseCPU *oldCPU)
+{
+ BaseCPU::takeOverFrom(oldCPU);
+
+ // Call takeOverFrom() on each pipeline stage
+ for (int stNum=0; stNum < NumStages; stNum++) {
+ pipelineStage[stNum]->takeOverFrom();
+ }
+
+ assert(!tickEvent.scheduled());
+
+ // Copy over the current instruction sequence numbers if we are
+ // taking over from another InOrderCPU.
+ InOrderCPU *oldIOCPU = dynamic_cast<InOrderCPU*>(oldCPU);
+ if (oldIOCPU) {
+ for (ThreadID tid = 0; tid < numThreads; tid++)
+ globalSeqNum[tid] = oldIOCPU->globalSeqNum[tid];
+ }
+
+ lastRunningCycle = curCycle();
+ _status = Idle;
+}
+
void
InOrderCPU::instDone(DynInstPtr inst, ThreadID tid)
diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh
index 1183f6fc9..0104cb95f 100644
--- a/src/cpu/inorder/cpu.hh
+++ b/src/cpu/inorder/cpu.hh
@@ -866,6 +866,15 @@ class InOrderCPU : public BaseCPU
Stats::Average instsPerCtxtSwitch;
Stats::Scalar numCtxtSwitches;
+ /** Resumes execution after a drain. */
+ void drainResume();
+
+ /** Switches out this CPU. */
+ virtual void switchOut();
+
+ /** Takes over from another CPU. */
+ virtual void takeOverFrom(BaseCPU *oldCPU);
+
/** Update Thread , used for statistic purposes*/
inline void tickThreadStats();
diff --git a/src/cpu/inorder/first_stage.cc b/src/cpu/inorder/first_stage.cc
index 20fd9169f..f59e89410 100644
--- a/src/cpu/inorder/first_stage.cc
+++ b/src/cpu/inorder/first_stage.cc
@@ -277,3 +277,13 @@ FirstStage::roundRobin()
return InvalidThreadID;
}
+
+void
+FirstStage::takeOverFrom()
+{
+ PipelineStage::takeOverFrom();
+
+ for(ThreadID tid = 0; tid < this->numThreads; tid++) {
+ stageStatus[tid] = Running;
+ }
+}
diff --git a/src/cpu/inorder/first_stage.hh b/src/cpu/inorder/first_stage.hh
index 44ffb9599..ae8b12102 100644
--- a/src/cpu/inorder/first_stage.hh
+++ b/src/cpu/inorder/first_stage.hh
@@ -88,6 +88,9 @@ class FirstStage : public PipelineStage {
/** Return next thread given Round Robin Policy for Thread Fetching */
ThreadID roundRobin();
+
+ /** Takes over from another CPU's thread. */
+ void takeOverFrom();
};
#endif // __CPU_INORDER_FIRST_STAGE_HH__
diff --git a/src/cpu/inorder/pipeline_stage.hh b/src/cpu/inorder/pipeline_stage.hh
index 963d96afb..478561a8e 100644
--- a/src/cpu/inorder/pipeline_stage.hh
+++ b/src/cpu/inorder/pipeline_stage.hh
@@ -135,7 +135,7 @@ class PipelineStage
void switchOut();
/** Takes over from another CPU's thread. */
- void takeOverFrom();
+ virtual void takeOverFrom();
/** Ticks stage, processing all input signals and executing as many
* instructions as possible.