void
AtomicSimpleCPU::serialize(ostream &os)
{
- BaseSimpleCPU::serialize(os);
SERIALIZE_ENUM(_status);
+ BaseSimpleCPU::serialize(os);
nameOut(os, csprintf("%s.tickEvent", name()));
tickEvent.serialize(os);
}
void
AtomicSimpleCPU::unserialize(Checkpoint *cp, const string §ion)
{
- BaseSimpleCPU::unserialize(cp, section);
UNSERIALIZE_ENUM(_status);
+ BaseSimpleCPU::unserialize(cp, section);
tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
}
void
-AtomicSimpleCPU::switchOut(Sampler *s)
+AtomicSimpleCPU::switchOut()
{
- sampler = s;
- if (status() == Running) {
- _status = SwitchedOut;
+ assert(status() == Running || status() == Idle);
+ _status = SwitchedOut;
- tickEvent.squash();
- }
- sampler->signalSwitched();
+ tickEvent.squash();
}
{
_status = Idle;
ifetch_pkt = dcache_pkt = NULL;
+ quiesceEvent = NULL;
+ state = SimObject::Timing;
}
void
TimingSimpleCPU::serialize(ostream &os)
{
- BaseSimpleCPU::serialize(os);
SERIALIZE_ENUM(_status);
+ BaseSimpleCPU::serialize(os);
}
void
TimingSimpleCPU::unserialize(Checkpoint *cp, const string §ion)
{
- BaseSimpleCPU::unserialize(cp, section);
UNSERIALIZE_ENUM(_status);
+ BaseSimpleCPU::unserialize(cp, section);
+}
+
+bool
+TimingSimpleCPU::quiesce(Event *quiesce_event)
+{
+ // TimingSimpleCPU is ready to quiesce if it's not waiting for
+ // an access to complete.
+ if (status() == Idle || status() == Running || status() == SwitchedOut) {
+ DPRINTF(Config, "Ready to quiesce\n");
+ return false;
+ } else {
+ DPRINTF(Config, "Waiting to quiesce\n");
+ changeState(SimObject::Quiescing);
+ quiesceEvent = quiesce_event;
+ return true;
+ }
}
void
-TimingSimpleCPU::switchOut(Sampler *s)
+TimingSimpleCPU::resume()
{
- sampler = s;
- if (status() == Running) {
- _status = SwitchedOut;
+ if (_status != SwitchedOut && _status != Idle) {
+ Event *e =
+ new EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch>(this, true);
+ e->schedule(curTick);
}
- sampler->signalSwitched();
+}
+
+void
+TimingSimpleCPU::setMemoryMode(State new_mode)
+{
+ assert(new_mode == SimObject::Timing);
+}
+
+void
+TimingSimpleCPU::switchOut()
+{
+ assert(status() == Running || status() == Idle);
+ _status = SwitchedOut;
}
// instruction
assert(pkt->result == Packet::Success);
assert(_status == IcacheWaitResponse);
+
_status = Running;
delete pkt->req;
delete pkt;
+ if (getState() == SimObject::Quiescing) {
+ completeQuiesce();
+ return;
+ }
+
preExecute();
if (curStaticInst->isMemRef() && !curStaticInst->isDataPrefetch()) {
// load or store: just send to dcache
assert(_status == DcacheWaitResponse);
_status = Running;
+ if (getState() == SimObject::Quiescing) {
+ completeQuiesce();
+
+ delete pkt->req;
+ delete pkt;
+
+ return;
+ }
+
Fault fault = curStaticInst->completeAcc(pkt, this, traceData);
delete pkt->req;
}
+void
+TimingSimpleCPU::completeQuiesce()
+{
+ DPRINTF(Config, "Done quiescing\n");
+ changeState(SimObject::QuiescedTiming);
+ quiesceEvent->process();
+}
bool
TimingSimpleCPU::DcachePort::recvTiming(Packet *pkt)
Status status() const { return _status; }
+ Event *quiesceEvent;
+
private:
class CpuPort : public Port
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string §ion);
- void switchOut(Sampler *s);
+ virtual bool quiesce(Event *quiesce_event);
+ virtual void resume();
+ virtual void setMemoryMode(State new_mode);
+
+ void switchOut();
void takeOverFrom(BaseCPU *oldCPU);
virtual void activateContext(int thread_num, int delay);
void completeIfetch(Packet *);
void completeDataAccess(Packet *);
void advanceInst(Fault fault);
+ private:
+ void completeQuiesce();
};
#endif // __CPU_SIMPLE_TIMING_HH__