diff options
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/o3/cpu.cc | 26 | ||||
-rw-r--r-- | src/cpu/o3/cpu.hh | 8 | ||||
-rw-r--r-- | src/cpu/simple/atomic.cc | 28 | ||||
-rw-r--r-- | src/cpu/simple/atomic.hh | 4 | ||||
-rw-r--r-- | src/cpu/simple/timing.cc | 59 | ||||
-rw-r--r-- | src/cpu/simple/timing.hh | 8 | ||||
-rw-r--r-- | src/cpu/testers/traffic_gen/traffic_gen.cc | 4 | ||||
-rw-r--r-- | src/cpu/testers/traffic_gen/traffic_gen.hh | 2 |
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 §ion) { - 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 §ion) 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 §ion) { - 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 §ion); - 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 §ion) { - 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 §ion); - 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); |