summaryrefslogtreecommitdiff
path: root/src/cpu/o3/cpu.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/o3/cpu.cc')
-rw-r--r--src/cpu/o3/cpu.cc61
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 &section)
+{
+ 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();