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>
This commit is contained in:
Christopher Torng 2014-03-01 23:35:23 -06:00
parent a533f3f983
commit 919baa603d
7 changed files with 106 additions and 2 deletions

View file

@ -241,7 +241,23 @@ initCPU(ThreadContext *tc, int cpuId)
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

View file

@ -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")

View file

@ -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)

View file

@ -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();

View file

@ -277,3 +277,13 @@ FirstStage::roundRobin()
return InvalidThreadID;
}
void
FirstStage::takeOverFrom()
{
PipelineStage::takeOverFrom();
for(ThreadID tid = 0; tid < this->numThreads; tid++) {
stageStatus[tid] = Running;
}
}

View file

@ -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__

View file

@ -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.