diff -r d222a22f78e9 src/arch/mips/utility.cc --- a/src/arch/mips/utility.cc Tue Jan 28 18:00:51 2014 -0600 +++ b/src/arch/mips/utility.cc Thu Feb 27 00:32:41 2014 -0500 @@ -241,7 +241,23 @@ void copyRegs(ThreadContext *src, ThreadContext *dest) { - panic("Copy Regs Not Implemented Yet\n"); + // First loop through the integer registers. + for (int i = 0; i < NumIntRegs; i++) + dest->setIntRegFlat(i, src->readIntRegFlat(i)); + + // Then loop through the floating point registers. + for (int i = 0; i < NumFloatRegs; i++) + dest->setFloatRegFlat(i, src->readFloatRegFlat(i)); + + // Would need to add condition-code regs if implemented + assert(NumCCRegs == 0); + + // Copy misc. registers + for (int i = 0; i < NumMiscRegs; i++) + dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i)); + + // Copy over the PC State + dest->pcState(src->pcState()); } void diff -r d222a22f78e9 src/cpu/inorder/InOrderCPU.py --- a/src/cpu/inorder/InOrderCPU.py Tue Jan 28 18:00:51 2014 -0600 +++ b/src/cpu/inorder/InOrderCPU.py Thu Feb 27 00:32:41 2014 -0500 @@ -47,6 +47,10 @@ 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 -r d222a22f78e9 src/cpu/inorder/cpu.hh --- a/src/cpu/inorder/cpu.hh Tue Jan 28 18:00:51 2014 -0600 +++ b/src/cpu/inorder/cpu.hh Thu Feb 27 00:32:41 2014 -0500 @@ -866,6 +866,15 @@ 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 -r d222a22f78e9 src/cpu/inorder/cpu.cc --- a/src/cpu/inorder/cpu.cc Tue Jan 28 18:00:51 2014 -0600 +++ b/src/cpu/inorder/cpu.cc Thu Feb 27 00:32:41 2014 -0500 @@ -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 @@ 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(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 -r d222a22f78e9 src/cpu/inorder/first_stage.hh --- a/src/cpu/inorder/first_stage.hh Tue Jan 28 18:00:51 2014 -0600 +++ b/src/cpu/inorder/first_stage.hh Thu Feb 27 00:32:41 2014 -0500 @@ -88,6 +88,9 @@ /** 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 -r d222a22f78e9 src/cpu/inorder/first_stage.cc --- a/src/cpu/inorder/first_stage.cc Tue Jan 28 18:00:51 2014 -0600 +++ b/src/cpu/inorder/first_stage.cc Thu Feb 27 00:32:41 2014 -0500 @@ -277,3 +277,13 @@ return InvalidThreadID; } + +void +FirstStage::takeOverFrom() +{ + PipelineStage::takeOverFrom(); + + for(ThreadID tid = 0; tid < this->numThreads; tid++) { + stageStatus[tid] = Running; + } +} diff -r d222a22f78e9 src/cpu/inorder/pipeline_stage.hh --- a/src/cpu/inorder/pipeline_stage.hh Tue Jan 28 18:00:51 2014 -0600 +++ b/src/cpu/inorder/pipeline_stage.hh Thu Feb 27 00:32:41 2014 -0500 @@ -135,7 +135,7 @@ 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.