diff options
Diffstat (limited to 'src/cpu/o3/cpu.cc')
-rw-r--r-- | src/cpu/o3/cpu.cc | 61 |
1 files changed, 52 insertions, 9 deletions
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 3a52fe4c2..f345fe82d 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -708,6 +708,47 @@ FullO3CPU<Impl>::haltContext(int tid) } template <class Impl> +void +FullO3CPU<Impl>::serialize(std::ostream &os) +{ + SERIALIZE_ENUM(_status); + BaseCPU::serialize(os); + nameOut(os, csprintf("%s.tickEvent", name())); + tickEvent.serialize(os); + + // Use SimpleThread's ability to checkpoint to make it easier to + // write out the registers. Also make this static so it doesn't + // get instantiated multiple times (causes a panic in statistics). + static SimpleThread temp; + + for (int i = 0; i < thread.size(); i++) { + nameOut(os, csprintf("%s.xc.%i", name(), i)); + temp.copyTC(thread[i]->getTC()); + temp.serialize(os); + } +} + +template <class Impl> +void +FullO3CPU<Impl>::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_ENUM(_status); + BaseCPU::unserialize(cp, section); + tickEvent.unserialize(cp, csprintf("%s.tickEvent", section)); + + // Use SimpleThread's ability to checkpoint to make it easier to + // read in the registers. Also make this static so it doesn't + // get instantiated multiple times (causes a panic in statistics). + static SimpleThread temp; + + for (int i = 0; i < thread.size(); i++) { + temp.copyTC(thread[i]->getTC()); + temp.unserialize(cp, csprintf("%s.xc.%i", section, i)); + thread[i]->getTC()->copyArchRegs(temp.getTC()); + } +} + +template <class Impl> bool FullO3CPU<Impl>::drain(Event *drain_event) { @@ -717,15 +758,16 @@ FullO3CPU<Impl>::drain(Event *drain_event) rename.drain(); iew.drain(); commit.drain(); - // A bit of a hack...set the drainEvent 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; // Wake the CPU and record activity so everything can drain out if // the CPU was not able to immediately drain. - if (_status != Drained) { + if (getState() != SimObject::DrainedTiming) { + // A bit of a hack...set the drainEvent 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; + wakeCPU(); activityRec.activity(); @@ -739,14 +781,15 @@ template <class Impl> void FullO3CPU<Impl>::resume() { - if (_status == SwitchedOut) - return; fetch.resume(); decode.resume(); rename.resume(); iew.resume(); commit.resume(); + if (_status == SwitchedOut || _status == Idle) + return; + if (!tickEvent.scheduled()) tickEvent.schedule(curTick); _status = Running; @@ -760,7 +803,7 @@ FullO3CPU<Impl>::signalDrained() if (tickEvent.scheduled()) tickEvent.squash(); - _status = Drained; + changeState(SimObject::DrainedTiming); if (drainEvent) { drainEvent->process(); |