summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/o3/cpu.cc26
-rw-r--r--src/cpu/o3/cpu.hh8
-rw-r--r--src/cpu/simple/atomic.cc28
-rw-r--r--src/cpu/simple/atomic.hh4
-rw-r--r--src/cpu/simple/timing.cc59
-rw-r--r--src/cpu/simple/timing.hh8
-rw-r--r--src/cpu/testers/traffic_gen/traffic_gen.cc4
-rw-r--r--src/cpu/testers/traffic_gen/traffic_gen.hh2
8 files changed, 76 insertions, 63 deletions
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index fdd45fdda..bc5f096e6 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -619,7 +619,7 @@ FullO3CPU<Impl>::tick()
if (!tickEvent.scheduled()) {
if (_status == SwitchedOut ||
- getState() == SimObject::Drained) {
+ getDrainState() == Drainable::Drained) {
DPRINTF(O3CPU, "Switched out!\n");
// increment stat
lastRunningCycle = curCycle();
@@ -1077,7 +1077,7 @@ template <class Impl>
void
FullO3CPU<Impl>::serialize(std::ostream &os)
{
- SimObject::State so_state = SimObject::getState();
+ Drainable::State so_state(getDrainState());
SERIALIZE_ENUM(so_state);
BaseCPU::serialize(os);
nameOut(os, csprintf("%s.tickEvent", name()));
@@ -1100,7 +1100,7 @@ template <class Impl>
void
FullO3CPU<Impl>::unserialize(Checkpoint *cp, const std::string &section)
{
- SimObject::State so_state;
+ Drainable::State so_state;
UNSERIALIZE_ENUM(so_state);
BaseCPU::unserialize(cp, section);
tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
@@ -1120,7 +1120,7 @@ FullO3CPU<Impl>::unserialize(Checkpoint *cp, const std::string &section)
template <class Impl>
unsigned int
-FullO3CPU<Impl>::drain(Event *drain_event)
+FullO3CPU<Impl>::drain(DrainManager *drain_manager)
{
DPRINTF(O3CPU, "Switching out\n");
@@ -1137,12 +1137,12 @@ FullO3CPU<Impl>::drain(Event *drain_event)
// Wake the CPU and record activity so everything can drain out if
// the CPU was not able to immediately drain.
- if (getState() != SimObject::Drained) {
- // A bit of a hack...set the drainEvent after all the drain()
+ if (getDrainState() != Drainable::Drained) {
+ // A bit of a hack...set the drainManager after all the drain()
// calls have been made, that way if all of the stages drain
// immediately, the signalDrained() function knows not to call
// process on the drain event.
- drainEvent = drain_event;
+ drainManager = drain_manager;
wakeCPU();
activityRec.activity();
@@ -1157,7 +1157,7 @@ FullO3CPU<Impl>::drain(Event *drain_event)
template <class Impl>
void
-FullO3CPU<Impl>::resume()
+FullO3CPU<Impl>::drainResume()
{
fetch.resume();
decode.resume();
@@ -1165,7 +1165,7 @@ FullO3CPU<Impl>::resume()
iew.resume();
commit.resume();
- changeState(SimObject::Running);
+ setDrainState(Drainable::Running);
if (_status == SwitchedOut)
return;
@@ -1185,14 +1185,14 @@ FullO3CPU<Impl>::signalDrained()
if (tickEvent.scheduled())
tickEvent.squash();
- changeState(SimObject::Drained);
+ setDrainState(Drainable::Drained);
BaseCPU::switchOut();
- if (drainEvent) {
+ if (drainManager) {
DPRINTF(Drain, "CPU done draining, processing drain event\n");
- drainEvent->process();
- drainEvent = NULL;
+ drainManager->signalDrainDone();
+ drainManager = NULL;
}
}
assert(drainCount <= 5);
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index 076cce0fb..1f9a8da6c 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -431,10 +431,10 @@ class FullO3CPU : public BaseO3CPU
/** Starts draining the CPU's pipeline of all instructions in
* order to stop all memory accesses. */
- virtual unsigned int drain(Event *drain_event);
+ unsigned int drain(DrainManager *drain_manager);
/** Resumes execution after a drain. */
- virtual void resume();
+ void drainResume();
/** Signals to this CPU that a stage has completed switching out. */
void signalDrained();
@@ -730,8 +730,8 @@ class FullO3CPU : public BaseO3CPU
/** Pointer to the system. */
System *system;
- /** Event to call process() on once draining has completed. */
- Event *drainEvent;
+ /** DrainManager to notify when draining has completed. */
+ DrainManager *drainManager;
/** Counter of how many stages have completed draining. */
int drainCount;
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index 2d7afd221..e63d998a7 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -123,7 +123,7 @@ AtomicSimpleCPU::~AtomicSimpleCPU()
void
AtomicSimpleCPU::serialize(ostream &os)
{
- SimObject::State so_state = SimObject::getState();
+ Drainable::State so_state(getDrainState());
SERIALIZE_ENUM(so_state);
SERIALIZE_SCALAR(locked);
BaseSimpleCPU::serialize(os);
@@ -134,15 +134,22 @@ AtomicSimpleCPU::serialize(ostream &os)
void
AtomicSimpleCPU::unserialize(Checkpoint *cp, const string &section)
{
- SimObject::State so_state;
+ Drainable::State so_state;
UNSERIALIZE_ENUM(so_state);
UNSERIALIZE_SCALAR(locked);
BaseSimpleCPU::unserialize(cp, section);
tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
}
+unsigned int
+AtomicSimpleCPU::drain(DrainManager *drain_manager)
+{
+ setDrainState(Drainable::Drained);
+ return 0;
+}
+
void
-AtomicSimpleCPU::resume()
+AtomicSimpleCPU::drainResume()
{
if (_status == Idle || _status == SwitchedOut)
return;
@@ -150,7 +157,7 @@ AtomicSimpleCPU::resume()
DPRINTF(SimpleCPU, "Resume\n");
assert(system->getMemoryMode() == Enums::atomic);
- changeState(SimObject::Running);
+ setDrainState(Drainable::Running);
if (thread->status() == ThreadContext::Active) {
if (!tickEvent.scheduled())
schedule(tickEvent, nextCycle());
@@ -161,7 +168,7 @@ AtomicSimpleCPU::resume()
void
AtomicSimpleCPU::switchOut()
{
- assert(_status == Running || _status == Idle);
+ assert(_status == BaseSimpleCPU::Running || _status == Idle);
_status = SwitchedOut;
tickEvent.squash();
@@ -180,13 +187,14 @@ AtomicSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
ThreadID size = threadContexts.size();
for (ThreadID i = 0; i < size; ++i) {
ThreadContext *tc = threadContexts[i];
- if (tc->status() == ThreadContext::Active && _status != Running) {
- _status = Running;
+ if (tc->status() == ThreadContext::Active &&
+ _status != BaseSimpleCPU::Running) {
+ _status = BaseSimpleCPU::Running;
schedule(tickEvent, nextCycle());
break;
}
}
- if (_status != Running) {
+ if (_status != BaseSimpleCPU::Running) {
_status = Idle;
}
assert(threadContexts.size() == 1);
@@ -212,7 +220,7 @@ AtomicSimpleCPU::activateContext(ThreadID thread_num, Cycles delay)
//Make sure ticks are still on multiples of cycles
schedule(tickEvent, clockEdge(delay));
- _status = Running;
+ _status = BaseSimpleCPU::Running;
}
@@ -227,7 +235,7 @@ AtomicSimpleCPU::suspendContext(ThreadID thread_num)
if (_status == Idle)
return;
- assert(_status == Running);
+ assert(_status == BaseSimpleCPU::Running);
// tick event may not be scheduled if this gets called from inside
// an instruction's execution, e.g. "quiesce"
diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh
index d67ab67a5..94d2de081 100644
--- a/src/cpu/simple/atomic.hh
+++ b/src/cpu/simple/atomic.hh
@@ -122,7 +122,9 @@ class AtomicSimpleCPU : public BaseSimpleCPU
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
- virtual void resume();
+
+ unsigned int drain(DrainManager *drain_manager);
+ void drainResume();
void switchOut();
void takeOverFrom(BaseCPU *oldCPU);
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index 15b277d53..41764302d 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -92,7 +92,7 @@ TimingSimpleCPU::TimingSimpleCPU(TimingSimpleCPUParams *p)
{
_status = Idle;
- changeState(SimObject::Running);
+ setDrainState(Drainable::Running);
system->totalNumInsts = 0;
}
@@ -104,7 +104,7 @@ TimingSimpleCPU::~TimingSimpleCPU()
void
TimingSimpleCPU::serialize(ostream &os)
{
- SimObject::State so_state = SimObject::getState();
+ Drainable::State so_state(getDrainState());
SERIALIZE_ENUM(so_state);
BaseSimpleCPU::serialize(os);
}
@@ -112,29 +112,31 @@ TimingSimpleCPU::serialize(ostream &os)
void
TimingSimpleCPU::unserialize(Checkpoint *cp, const string &section)
{
- SimObject::State so_state;
+ Drainable::State so_state;
UNSERIALIZE_ENUM(so_state);
BaseSimpleCPU::unserialize(cp, section);
}
unsigned int
-TimingSimpleCPU::drain(Event *drain_event)
+TimingSimpleCPU::drain(DrainManager *drain_manager)
{
// TimingSimpleCPU is ready to drain if it's not waiting for
// an access to complete.
- if (_status == Idle || _status == Running || _status == SwitchedOut) {
- changeState(SimObject::Drained);
+ if (_status == Idle ||
+ _status == BaseSimpleCPU::Running ||
+ _status == SwitchedOut) {
+ setDrainState(Drainable::Drained);
return 0;
} else {
- changeState(SimObject::Draining);
- drainEvent = drain_event;
+ setDrainState(Drainable::Draining);
+ drainManager = drain_manager;
DPRINTF(Drain, "CPU not drained\n");
return 1;
}
}
void
-TimingSimpleCPU::resume()
+TimingSimpleCPU::drainResume()
{
DPRINTF(SimpleCPU, "Resume\n");
if (_status != SwitchedOut && _status != Idle) {
@@ -146,13 +148,13 @@ TimingSimpleCPU::resume()
schedule(fetchEvent, nextCycle());
}
- changeState(SimObject::Running);
+ setDrainState(Drainable::Running);
}
void
TimingSimpleCPU::switchOut()
{
- assert(_status == Running || _status == Idle);
+ assert(_status == BaseSimpleCPU::Running || _status == Idle);
_status = SwitchedOut;
numCycles += curCycle() - previousCycle;
@@ -172,13 +174,14 @@ TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
// running and schedule its tick event.
for (int i = 0; i < threadContexts.size(); ++i) {
ThreadContext *tc = threadContexts[i];
- if (tc->status() == ThreadContext::Active && _status != Running) {
- _status = Running;
+ if (tc->status() == ThreadContext::Active &&
+ _status != BaseSimpleCPU::Running) {
+ _status = BaseSimpleCPU::Running;
break;
}
}
- if (_status != Running) {
+ if (_status != BaseSimpleCPU::Running) {
_status = Idle;
}
assert(threadContexts.size() == 1);
@@ -197,7 +200,7 @@ TimingSimpleCPU::activateContext(ThreadID thread_num, Cycles delay)
assert(_status == Idle);
notIdleFraction++;
- _status = Running;
+ _status = BaseSimpleCPU::Running;
// kick things off by initiating the fetch of the next instruction
schedule(fetchEvent, clockEdge(delay));
@@ -215,7 +218,7 @@ TimingSimpleCPU::suspendContext(ThreadID thread_num)
if (_status == Idle)
return;
- assert(_status == Running);
+ assert(_status == BaseSimpleCPU::Running);
// just change status to Idle... if status != Running,
// completeInst() will not initiate fetch of next instruction.
@@ -330,7 +333,7 @@ TimingSimpleCPU::translationFault(Fault fault)
postExecute();
- if (getState() == SimObject::Draining) {
+ if (getDrainState() == Drainable::Draining) {
advancePC(fault);
completeDrain();
} else {
@@ -511,7 +514,7 @@ TimingSimpleCPU::writeMem(uint8_t *data, unsigned size,
void
TimingSimpleCPU::finishTranslation(WholeTranslationState *state)
{
- _status = Running;
+ _status = BaseSimpleCPU::Running;
if (state->getFault() != NoFault) {
if (state->isPrefetch()) {
@@ -552,7 +555,7 @@ TimingSimpleCPU::fetch()
bool needToFetch = !isRomMicroPC(pcState.microPC()) && !curMacroStaticInst;
if (needToFetch) {
- _status = Running;
+ _status = BaseSimpleCPU::Running;
Request *ifetch_req = new Request();
ifetch_req->setThreadContext(_cpuId, /* thread ID */ 0);
setupFetchRequest(ifetch_req);
@@ -592,7 +595,7 @@ TimingSimpleCPU::sendFetch(Fault fault, RequestPtr req, ThreadContext *tc)
DPRINTF(SimpleCPU, "Translation of addr %#x faulted\n", req->getVaddr());
delete req;
// fetch fault: advance directly to next instruction (fault handler)
- _status = Running;
+ _status = BaseSimpleCPU::Running;
advanceInst(fault);
}
@@ -620,7 +623,7 @@ TimingSimpleCPU::advanceInst(Fault fault)
if (!stayAtPC)
advancePC(fault);
- if (_status == Running) {
+ if (_status == BaseSimpleCPU::Running) {
// kick off fetch of next instruction... callback from icache
// response will cause that instruction to be executed,
// keeping the CPU running.
@@ -641,12 +644,12 @@ TimingSimpleCPU::completeIfetch(PacketPtr pkt)
assert(!pkt || !pkt->isError());
assert(_status == IcacheWaitResponse);
- _status = Running;
+ _status = BaseSimpleCPU::Running;
numCycles += curCycle() - previousCycle;
previousCycle = curCycle();
- if (getState() == SimObject::Draining) {
+ if (getDrainState() == Drainable::Draining) {
if (pkt) {
delete pkt->req;
delete pkt;
@@ -664,7 +667,7 @@ TimingSimpleCPU::completeIfetch(PacketPtr pkt)
// If we're not running now the instruction will complete in a dcache
// response callback or the instruction faulted and has started an
// ifetch
- if (_status == Running) {
+ if (_status == BaseSimpleCPU::Running) {
if (fault != NoFault && traceData) {
// If there was a fault, we shouldn't trace this instruction.
delete traceData;
@@ -778,7 +781,7 @@ TimingSimpleCPU::completeDataAccess(PacketPtr pkt)
}
}
- _status = Running;
+ _status = BaseSimpleCPU::Running;
Fault fault = curStaticInst->completeAcc(pkt, this, traceData);
@@ -802,7 +805,7 @@ TimingSimpleCPU::completeDataAccess(PacketPtr pkt)
postExecute();
- if (getState() == SimObject::Draining) {
+ if (getDrainState() == Drainable::Draining) {
advancePC(fault);
completeDrain();
@@ -817,8 +820,8 @@ void
TimingSimpleCPU::completeDrain()
{
DPRINTF(Drain, "CPU done draining, processing drain event\n");
- changeState(SimObject::Drained);
- drainEvent->process();
+ setDrainState(Drainable::Drained);
+ drainManager->signalDrainDone();
}
bool
diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh
index a2570abe6..e7f5122d0 100644
--- a/src/cpu/simple/timing.hh
+++ b/src/cpu/simple/timing.hh
@@ -45,7 +45,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
virtual void init();
public:
- Event *drainEvent;
+ DrainManager *drainManager;
private:
@@ -109,7 +109,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
void
markDelayed()
{
- assert(cpu->_status == Running);
+ assert(cpu->_status == BaseSimpleCPU::Running);
cpu->_status = ITBWaitResponse;
}
@@ -249,8 +249,8 @@ class TimingSimpleCPU : public BaseSimpleCPU
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
- virtual unsigned int drain(Event *drain_event);
- virtual void resume();
+ unsigned int drain(DrainManager *drain_manager);
+ void drainResume();
void switchOut();
void takeOverFrom(BaseCPU *oldCPU);
diff --git a/src/cpu/testers/traffic_gen/traffic_gen.cc b/src/cpu/testers/traffic_gen/traffic_gen.cc
index af7ff89f4..e0657822c 100644
--- a/src/cpu/testers/traffic_gen/traffic_gen.cc
+++ b/src/cpu/testers/traffic_gen/traffic_gen.cc
@@ -110,11 +110,11 @@ TrafficGen::initState()
}
unsigned int
-TrafficGen::drain(Event* drain_event)
+TrafficGen::drain(DrainManager *dm)
{
// @todo we should also stop putting new requests in the queue and
// either interrupt the current state or wait for a transition
- return port.drain(drain_event);
+ return port.drain(dm);
}
void
diff --git a/src/cpu/testers/traffic_gen/traffic_gen.hh b/src/cpu/testers/traffic_gen/traffic_gen.hh
index 5f59be82c..4e94df548 100644
--- a/src/cpu/testers/traffic_gen/traffic_gen.hh
+++ b/src/cpu/testers/traffic_gen/traffic_gen.hh
@@ -604,7 +604,7 @@ class TrafficGen : public MemObject
void initState();
- unsigned int drain(Event *drain_event);
+ unsigned int drain(DrainManager *dm);
void serialize(std::ostream &os);