diff options
author | Christopher Torng <clt67@cornell.edu> | 2014-03-01 23:35:23 -0600 |
---|---|---|
committer | Christopher Torng <clt67@cornell.edu> | 2014-03-01 23:35:23 -0600 |
commit | 919baa603d0b835c3202f9968a617a31f9116549 (patch) | |
tree | e5e075957313bbe9a9630b84e64c86545351e264 /src/cpu/inorder | |
parent | a533f3f9831081625626f96f9434a00f3079e98e (diff) | |
download | gem5-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.py | 4 | ||||
-rw-r--r-- | src/cpu/inorder/cpu.cc | 62 | ||||
-rw-r--r-- | src/cpu/inorder/cpu.hh | 9 | ||||
-rw-r--r-- | src/cpu/inorder/first_stage.cc | 10 | ||||
-rw-r--r-- | src/cpu/inorder/first_stage.hh | 3 | ||||
-rw-r--r-- | src/cpu/inorder/pipeline_stage.hh | 2 |
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. |