summaryrefslogtreecommitdiff
path: root/src/cpu/simple
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/simple')
-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
4 files changed, 56 insertions, 43 deletions
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);