summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
authorKevin Lim <ktlim@umich.edu>2006-07-06 23:13:38 -0400
committerKevin Lim <ktlim@umich.edu>2006-07-06 23:13:38 -0400
commitfff75316771331ec3247cbd6e424a93b252a1e29 (patch)
tree0e2e96841ebd160ef0160dd3dc56aa0a56696b86 /src/cpu
parentfbe3e22474184e537fe74f4e86277056026f0514 (diff)
downloadgem5-fff75316771331ec3247cbd6e424a93b252a1e29.tar.xz
Support serializing and unserializing in the O3 CPU. Also a few small fixes for draining/switching CPUs.
src/cpu/o3/commit_impl.hh: Fix to clear drainPending variable on call to resume. src/cpu/o3/cpu.cc: src/cpu/o3/cpu.hh: Support serializing and unserializing in the O3 CPU. src/cpu/o3/lsq_impl.hh: Be sure to say we have no stores to write back if the active thread list is empty. src/cpu/simple_thread.cc: src/cpu/simple_thread.hh: Slightly change how SimpleThread is used to copy from other ThreadContexts. --HG-- extra : convert_revision : 92a5109b3783a989d5b451036061ef82c56d3121
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/o3/commit_impl.hh1
-rw-r--r--src/cpu/o3/cpu.cc61
-rw-r--r--src/cpu/o3/cpu.hh8
-rw-r--r--src/cpu/o3/lsq_impl.hh3
-rw-r--r--src/cpu/simple_thread.cc32
-rw-r--r--src/cpu/simple_thread.hh4
6 files changed, 84 insertions, 25 deletions
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh
index b50c9a898..39e1cf3fe 100644
--- a/src/cpu/o3/commit_impl.hh
+++ b/src/cpu/o3/commit_impl.hh
@@ -377,6 +377,7 @@ template <class Impl>
void
DefaultCommit<Impl>::resume()
{
+ drainPending = false;
}
template <class Impl>
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();
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index cf3747601..5b881e558 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -111,7 +111,6 @@ class FullO3CPU : public BaseO3CPU
Idle,
Halted,
Blocked,
- Drained,
SwitchedOut
};
@@ -266,6 +265,13 @@ class FullO3CPU : public BaseO3CPU
/** Update The Order In Which We Process Threads. */
void updateThreadPriority();
+ /** Serialize state. */
+ virtual void serialize(std::ostream &os);
+
+ /** Unserialize from a checkpoint. */
+ virtual void unserialize(Checkpoint *cp, const std::string &section);
+
+ public:
/** Executes a syscall on this cycle.
* ---------------------------------------
* Note: this is a virtual function. CPU-Specific
diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh
index 5173f8be1..89fd1a71d 100644
--- a/src/cpu/o3/lsq_impl.hh
+++ b/src/cpu/o3/lsq_impl.hh
@@ -502,6 +502,9 @@ LSQ<Impl>::hasStoresToWB()
{
list<unsigned>::iterator active_threads = (*activeThreads).begin();
+ if ((*activeThreads).empty())
+ return false;
+
while (active_threads != (*activeThreads).end()) {
unsigned tid = *active_threads++;
if (!hasStoresToWB(tid))
diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc
index 6255b3357..af1db2ff2 100644
--- a/src/cpu/simple_thread.cc
+++ b/src/cpu/simple_thread.cc
@@ -125,7 +125,7 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num,
#endif
-SimpleThread::SimpleThread(ThreadContext *oldContext)
+SimpleThread::SimpleThread()
#if FULL_SYSTEM
: ThreadState(-1, -1)
#else
@@ -134,19 +134,6 @@ SimpleThread::SimpleThread(ThreadContext *oldContext)
{
tc = new ProxyThreadContext<SimpleThread>(this);
regs.clear();
-
- copyState(oldContext);
-
-#if FULL_SYSTEM
- EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent();
- if (quiesce) {
- quiesceEvent = quiesce;
- }
- Kernel::Statistics *stats = oldContext->getKernelStats();
- if (stats) {
- kernelStats = stats;
- }
-#endif
}
SimpleThread::~SimpleThread()
@@ -183,6 +170,23 @@ SimpleThread::takeOverFrom(ThreadContext *oldContext)
}
void
+SimpleThread::copyTC(ThreadContext *context)
+{
+ copyState(context);
+
+#if FULL_SYSTEM
+ EndQuiesceEvent *quiesce = context->getQuiesceEvent();
+ if (quiesce) {
+ quiesceEvent = quiesce;
+ }
+ Kernel::Statistics *stats = context->getKernelStats();
+ if (stats) {
+ kernelStats = stats;
+ }
+#endif
+}
+
+void
SimpleThread::copyState(ThreadContext *oldContext)
{
// copy over functional state
diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh
index ff2639e10..d36853db4 100644
--- a/src/cpu/simple_thread.hh
+++ b/src/cpu/simple_thread.hh
@@ -121,7 +121,7 @@ class SimpleThread : public ThreadState
MemObject *memobj);
#endif
- SimpleThread(ThreadContext *oldContext);
+ SimpleThread();
virtual ~SimpleThread();
@@ -129,6 +129,8 @@ class SimpleThread : public ThreadState
void regStats(const std::string &name);
+ void copyTC(ThreadContext *context);
+
void copyState(ThreadContext *oldContext);
void serialize(std::ostream &os);