summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
authorKevin Lim <ktlim@umich.edu>2006-07-06 13:59:02 -0400
committerKevin Lim <ktlim@umich.edu>2006-07-06 13:59:02 -0400
commit30c516d51cad44f62a7269a59f067ae5a1be81df (patch)
tree7df8888a35f67954558db467a748b9c610efe7e4 /src/cpu
parent8c547d80b1a091f41f5516f58ad7368181fe4041 (diff)
downloadgem5-30c516d51cad44f62a7269a59f067ae5a1be81df.tar.xz
Support for draining, and the new method of switching out. Now switching out happens after the pipeline has been drained, deferring the three way handshake to the normal drain mechanism. The calls of switchOut() and takeOverFrom() both take action immediately.
src/cpu/o3/commit.hh: src/cpu/o3/commit_impl.hh: src/cpu/o3/cpu.cc: src/cpu/o3/cpu.hh: src/cpu/o3/decode.hh: src/cpu/o3/decode_impl.hh: src/cpu/o3/fetch.hh: src/cpu/o3/fetch_impl.hh: src/cpu/o3/iew.hh: src/cpu/o3/iew_impl.hh: src/cpu/o3/rename.hh: src/cpu/o3/rename_impl.hh: Support for draining, new method of switching out. --HG-- extra : convert_revision : 05bf8b271ec85b3e2c675c3bed6c42aeba21f465
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/o3/commit.hh13
-rw-r--r--src/cpu/o3/commit_impl.hh21
-rw-r--r--src/cpu/o3/cpu.cc77
-rw-r--r--src/cpu/o3/cpu.hh25
-rw-r--r--src/cpu/o3/decode.hh8
-rw-r--r--src/cpu/o3/decode_impl.hh6
-rw-r--r--src/cpu/o3/fetch.hh14
-rw-r--r--src/cpu/o3/fetch_impl.hh24
-rw-r--r--src/cpu/o3/iew.hh9
-rw-r--r--src/cpu/o3/iew_impl.hh14
-rw-r--r--src/cpu/o3/rename.hh9
-rw-r--r--src/cpu/o3/rename_impl.hh6
12 files changed, 155 insertions, 71 deletions
diff --git a/src/cpu/o3/commit.hh b/src/cpu/o3/commit.hh
index 60b555269..49ff5cdad 100644
--- a/src/cpu/o3/commit.hh
+++ b/src/cpu/o3/commit.hh
@@ -187,11 +187,14 @@ class DefaultCommit
/** Initializes stage by sending back the number of free entries. */
void initStage();
- /** Initializes the switching out of commit. */
- void switchOut();
+ /** Initializes the draining of commit. */
+ void drain();
+
+ /** Resumes execution after draining. */
+ void resume();
/** Completes the switch out of commit. */
- void doSwitchOut();
+ void switchOut();
/** Takes over from another CPU's thread. */
void takeOverFrom();
@@ -383,8 +386,8 @@ class DefaultCommit
/** Number of Active Threads */
unsigned numThreads;
- /** Is a switch out pending. */
- bool switchPending;
+ /** Is a drain pending. */
+ bool drainPending;
/** Is commit switched out. */
bool switchedOut;
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh
index 06b8e8a95..2eb05afac 100644
--- a/src/cpu/o3/commit_impl.hh
+++ b/src/cpu/o3/commit_impl.hh
@@ -80,7 +80,7 @@ DefaultCommit<Impl>::DefaultCommit(Params *params)
renameWidth(params->renameWidth),
commitWidth(params->commitWidth),
numThreads(params->numberOfThreads),
- switchPending(false),
+ drainPending(false),
switchedOut(false),
trapLatency(params->trapLatency),
fetchTrapLatency(params->fetchTrapLatency)
@@ -351,22 +351,28 @@ DefaultCommit<Impl>::initStage()
template <class Impl>
void
-DefaultCommit<Impl>::switchOut()
+DefaultCommit<Impl>::drain()
{
- switchPending = true;
+ drainPending = true;
}
template <class Impl>
void
-DefaultCommit<Impl>::doSwitchOut()
+DefaultCommit<Impl>::switchOut()
{
switchedOut = true;
- switchPending = false;
+ drainPending = false;
rob->switchOut();
}
template <class Impl>
void
+DefaultCommit<Impl>::resume()
+{
+}
+
+template <class Impl>
+void
DefaultCommit<Impl>::takeOverFrom()
{
switchedOut = false;
@@ -557,8 +563,9 @@ DefaultCommit<Impl>::tick()
wroteToTimeBuffer = false;
_nextStatus = Inactive;
- if (switchPending && rob->isEmpty() && !iewStage->hasStoresToWB()) {
- cpu->signalSwitched();
+ if (drainPending && rob->isEmpty() && !iewStage->hasStoresToWB()) {
+ cpu->signalDrained();
+ drainPending = false;
return;
}
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index fb7739db8..5bda57cf8 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -158,7 +158,7 @@ FullO3CPU<Impl>::FullO3CPU(Params *params)
physmem(system->physmem),
#endif // FULL_SYSTEM
mem(params->mem),
- switchCount(0),
+ drainCount(0),
deferRegistration(params->deferRegistration),
numThreads(number_of_threads)
{
@@ -713,45 +713,72 @@ FullO3CPU<Impl>::haltContext(int tid)
}
template <class Impl>
-void
-FullO3CPU<Impl>::switchOut()
+bool
+FullO3CPU<Impl>::drain(Event *drain_event)
{
- switchCount = 0;
- fetch.switchOut();
- decode.switchOut();
- rename.switchOut();
- iew.switchOut();
- commit.switchOut();
+ drainCount = 0;
+ drainEvent = drain_event;
+ fetch.drain();
+ decode.drain();
+ rename.drain();
+ iew.drain();
+ commit.drain();
// Wake the CPU and record activity so everything can drain out if
// the CPU is currently idle.
wakeCPU();
activityRec.activity();
+
+ return false;
}
template <class Impl>
void
-FullO3CPU<Impl>::signalSwitched()
-{
- if (++switchCount == NumStages) {
- fetch.doSwitchOut();
- rename.doSwitchOut();
- commit.doSwitchOut();
- instList.clear();
- while (!removeList.empty()) {
- removeList.pop();
- }
+FullO3CPU<Impl>::resume()
+{
+ if (_status == SwitchedOut)
+ return;
+ fetch.resume();
+ decode.resume();
+ rename.resume();
+ iew.resume();
+ commit.resume();
-#if USE_CHECKER
- if (checker)
- checker->switchOut();
-#endif
+ if (!tickEvent.scheduled())
+ tickEvent.schedule(curTick);
+ _status = Running;
+}
+template <class Impl>
+void
+FullO3CPU<Impl>::signalDrained()
+{
+ if (++drainCount == NumStages) {
if (tickEvent.scheduled())
tickEvent.squash();
- _status = SwitchedOut;
+ _status = Drained;
+ drainEvent->process();
}
- assert(switchCount <= 5);
+ assert(drainCount <= 5);
+}
+
+template <class Impl>
+void
+FullO3CPU<Impl>::switchOut()
+{
+ fetch.switchOut();
+ rename.switchOut();
+ commit.switchOut();
+ instList.clear();
+ while (!removeList.empty()) {
+ removeList.pop();
+ }
+
+ _status = SwitchedOut;
+#if USE_CHECKER
+ if (checker)
+ checker->switchOut();
+#endif
}
template <class Impl>
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index bd0451601..cf3747601 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -57,6 +57,8 @@ class Checker;
class ThreadContext;
template <class>
class O3ThreadContext;
+
+class Checkpoint;
class MemObject;
class Process;
@@ -109,6 +111,7 @@ class FullO3CPU : public BaseO3CPU
Idle,
Halted,
Blocked,
+ Drained,
SwitchedOut
};
@@ -270,14 +273,21 @@ class FullO3CPU : public BaseO3CPU
*/
virtual void syscall(int tid) { panic("Unimplemented!"); }
- /** Switches out this CPU. */
- void switchOut();
+ /** Starts draining the CPU's pipeline of all instructions in
+ * order to stop all memory accesses. */
+ virtual bool drain(Event *drain_event);
+
+ /** Resumes execution after a drain. */
+ virtual void resume();
/** Signals to this CPU that a stage has completed switching out. */
- void signalSwitched();
+ void signalDrained();
+
+ /** Switches out this CPU. */
+ virtual void switchOut();
/** Takes over from another CPU. */
- void takeOverFrom(BaseCPU *oldCPU);
+ virtual void takeOverFrom(BaseCPU *oldCPU);
/** Get the current instruction sequence number, and increment it. */
InstSeqNum getAndIncrementInstSeq()
@@ -550,8 +560,11 @@ class FullO3CPU : public BaseO3CPU
/** Pointer to memory. */
MemObject *mem;
- /** Counter of how many stages have completed switching out. */
- int switchCount;
+ /** Event to call process() on once draining has completed. */
+ Event *drainEvent;
+
+ /** Counter of how many stages have completed draining. */
+ int drainCount;
/** Pointers to all of the threads in the CPU. */
std::vector<Thread *> thread;
diff --git a/src/cpu/o3/decode.hh b/src/cpu/o3/decode.hh
index 1edf3335d..1e96f1884 100644
--- a/src/cpu/o3/decode.hh
+++ b/src/cpu/o3/decode.hh
@@ -109,8 +109,14 @@ class DefaultDecode
/** Sets pointer to list of active threads. */
void setActiveThreads(std::list<unsigned> *at_ptr);
+ /** Drains the decode stage. */
+ void drain();
+
+ /** Resumes execution after a drain. */
+ void resume() { }
+
/** Switches out the decode stage. */
- void switchOut();
+ void switchOut() { }
/** Takes over from another CPU's thread. */
void takeOverFrom();
diff --git a/src/cpu/o3/decode_impl.hh b/src/cpu/o3/decode_impl.hh
index 16be01784..71637883b 100644
--- a/src/cpu/o3/decode_impl.hh
+++ b/src/cpu/o3/decode_impl.hh
@@ -166,10 +166,10 @@ DefaultDecode<Impl>::setActiveThreads(list<unsigned> *at_ptr)
template <class Impl>
void
-DefaultDecode<Impl>::switchOut()
+DefaultDecode<Impl>::drain()
{
- // Decode can immediately switch out.
- cpu->signalSwitched();
+ // Decode is done draining at any time.
+ cpu->signalDrained();
}
template <class Impl>
diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh
index 848ebf39e..9611f0455 100644
--- a/src/cpu/o3/fetch.hh
+++ b/src/cpu/o3/fetch.hh
@@ -180,11 +180,14 @@ class DefaultFetch
/** Processes cache completion event. */
void processCacheCompletion(PacketPtr pkt);
- /** Begins the switch out of the fetch stage. */
- void switchOut();
+ /** Begins the drain of the fetch stage. */
+ void drain();
+
+ /** Resumes execution after a drain. */
+ void resume();
- /** Completes the switch out of the fetch stage. */
- void doSwitchOut();
+ /** Tells fetch stage to prepare to be switched out. */
+ void switchOut();
/** Takes over from another CPU's thread. */
void takeOverFrom();
@@ -421,6 +424,9 @@ class DefaultFetch
*/
bool interruptPending;
+ /** Is there a drain pending. */
+ bool drainPending;
+
/** Records if fetch is switched out. */
bool switchedOut;
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index 60eb76d17..500b5304e 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -109,6 +109,7 @@ DefaultFetch<Impl>::DefaultFetch(Params *params)
numThreads(params->numberOfThreads),
numFetchingThreads(params->smtNumFetchingThreads),
interruptPending(false),
+ drainPending(false),
switchedOut(false)
{
if (numThreads > Impl::MaxThreads)
@@ -353,7 +354,8 @@ DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)
// to return.
if (fetchStatus[tid] != IcacheWaitResponse ||
pkt->req != memReq[tid] ||
- isSwitchedOut()) {
+ isSwitchedOut() ||
+ drainPending) {
++fetchIcacheSquashes;
delete pkt->req;
delete pkt;
@@ -384,17 +386,25 @@ DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)
template <class Impl>
void
-DefaultFetch<Impl>::switchOut()
+DefaultFetch<Impl>::drain()
{
- // Fetch is ready to switch out at any time.
- switchedOut = true;
- cpu->signalSwitched();
+ // Fetch is ready to drain at any time.
+ cpu->signalDrained();
+ drainPending = true;
}
template <class Impl>
void
-DefaultFetch<Impl>::doSwitchOut()
+DefaultFetch<Impl>::resume()
{
+ drainPending = false;
+}
+
+template <class Impl>
+void
+DefaultFetch<Impl>::switchOut()
+{
+ switchedOut = true;
// Branch predictor needs to have its state cleared.
branchPred.switchOut();
}
@@ -498,7 +508,7 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
unsigned flags = 0;
#endif // FULL_SYSTEM
- if (cacheBlocked || (interruptPending && flags == 0) || switchedOut) {
+ if (cacheBlocked || (interruptPending && flags == 0) || drainPending) {
// Hold off fetch from getting new instructions when:
// Cache is blocked, or
// while an interrupt is pending and we're not in PAL mode, or
diff --git a/src/cpu/o3/iew.hh b/src/cpu/o3/iew.hh
index 9627609c2..774b6dcbd 100644
--- a/src/cpu/o3/iew.hh
+++ b/src/cpu/o3/iew.hh
@@ -143,11 +143,14 @@ class DefaultIEW
/** Sets pointer to the scoreboard. */
void setScoreboard(Scoreboard *sb_ptr);
- /** Starts switch out of IEW stage. */
- void switchOut();
+ /** Drains IEW stage. */
+ void drain();
+
+ /** Resumes execution after a drain. */
+ void resume();
/** Completes switch out of IEW stage. */
- void doSwitchOut();
+ void switchOut();
/** Takes over from another CPU's thread. */
void takeOverFrom();
diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh
index 118038b65..c3aa748ae 100644
--- a/src/cpu/o3/iew_impl.hh
+++ b/src/cpu/o3/iew_impl.hh
@@ -355,15 +355,21 @@ DefaultIEW<Impl>::setScoreboard(Scoreboard *sb_ptr)
template <class Impl>
void
-DefaultIEW<Impl>::switchOut()
+DefaultIEW<Impl>::drain()
{
- // IEW is ready to switch out at any time.
- cpu->signalSwitched();
+ // IEW is ready to drain at any time.
+ cpu->signalDrained();
}
template <class Impl>
void
-DefaultIEW<Impl>::doSwitchOut()
+DefaultIEW<Impl>::resume()
+{
+}
+
+template <class Impl>
+void
+DefaultIEW<Impl>::switchOut()
{
// Clear any state.
switchedOut = true;
diff --git a/src/cpu/o3/rename.hh b/src/cpu/o3/rename.hh
index 581fc8f81..538dd9bb4 100644
--- a/src/cpu/o3/rename.hh
+++ b/src/cpu/o3/rename.hh
@@ -157,12 +157,15 @@ class DefaultRename
/** Sets pointer to the scoreboard. */
void setScoreboard(Scoreboard *_scoreboard);
+ /** Drains the rename stage. */
+ void drain();
+
+ /** Resumes execution after a drain. */
+ void resume() { }
+
/** Switches out the rename stage. */
void switchOut();
- /** Completes the switch out. */
- void doSwitchOut();
-
/** Takes over from another CPU's thread. */
void takeOverFrom();
diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh
index df8b7f9da..fddbae3db 100644
--- a/src/cpu/o3/rename_impl.hh
+++ b/src/cpu/o3/rename_impl.hh
@@ -258,15 +258,15 @@ DefaultRename<Impl>::setScoreboard(Scoreboard *_scoreboard)
template <class Impl>
void
-DefaultRename<Impl>::switchOut()
+DefaultRename<Impl>::drain()
{
// Rename is ready to switch out at any time.
- cpu->signalSwitched();
+ cpu->signalDrained();
}
template <class Impl>
void
-DefaultRename<Impl>::doSwitchOut()
+DefaultRename<Impl>::switchOut()
{
// Clear any state, fix up the rename map.
for (int i = 0; i < numThreads; i++) {