Merge ktlim@zizzer:/bk/newmem
into zamp.eecs.umich.edu:/z/ktlim2/clean/newmem-merge --HG-- extra : convert_revision : 00f8eecf99c771ae8943ed1d3a652bfbcfe1c6bc
This commit is contained in:
commit
05eef5ee15
15 changed files with 157 additions and 73 deletions
|
@ -187,11 +187,14 @@ class DefaultCommit
|
||||||
/** Initializes stage by sending back the number of free entries. */
|
/** Initializes stage by sending back the number of free entries. */
|
||||||
void initStage();
|
void initStage();
|
||||||
|
|
||||||
/** Initializes the switching out of commit. */
|
/** Initializes the draining of commit. */
|
||||||
void switchOut();
|
void drain();
|
||||||
|
|
||||||
|
/** Resumes execution after draining. */
|
||||||
|
void resume();
|
||||||
|
|
||||||
/** Completes the switch out of commit. */
|
/** Completes the switch out of commit. */
|
||||||
void doSwitchOut();
|
void switchOut();
|
||||||
|
|
||||||
/** Takes over from another CPU's thread. */
|
/** Takes over from another CPU's thread. */
|
||||||
void takeOverFrom();
|
void takeOverFrom();
|
||||||
|
@ -383,8 +386,8 @@ class DefaultCommit
|
||||||
/** Number of Active Threads */
|
/** Number of Active Threads */
|
||||||
unsigned numThreads;
|
unsigned numThreads;
|
||||||
|
|
||||||
/** Is a switch out pending. */
|
/** Is a drain pending. */
|
||||||
bool switchPending;
|
bool drainPending;
|
||||||
|
|
||||||
/** Is commit switched out. */
|
/** Is commit switched out. */
|
||||||
bool switchedOut;
|
bool switchedOut;
|
||||||
|
|
|
@ -80,7 +80,7 @@ DefaultCommit<Impl>::DefaultCommit(Params *params)
|
||||||
renameWidth(params->renameWidth),
|
renameWidth(params->renameWidth),
|
||||||
commitWidth(params->commitWidth),
|
commitWidth(params->commitWidth),
|
||||||
numThreads(params->numberOfThreads),
|
numThreads(params->numberOfThreads),
|
||||||
switchPending(false),
|
drainPending(false),
|
||||||
switchedOut(false),
|
switchedOut(false),
|
||||||
trapLatency(params->trapLatency),
|
trapLatency(params->trapLatency),
|
||||||
fetchTrapLatency(params->fetchTrapLatency)
|
fetchTrapLatency(params->fetchTrapLatency)
|
||||||
|
@ -351,20 +351,26 @@ DefaultCommit<Impl>::initStage()
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
void
|
||||||
DefaultCommit<Impl>::switchOut()
|
DefaultCommit<Impl>::drain()
|
||||||
{
|
{
|
||||||
switchPending = true;
|
drainPending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
void
|
||||||
DefaultCommit<Impl>::doSwitchOut()
|
DefaultCommit<Impl>::switchOut()
|
||||||
{
|
{
|
||||||
switchedOut = true;
|
switchedOut = true;
|
||||||
switchPending = false;
|
drainPending = false;
|
||||||
rob->switchOut();
|
rob->switchOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class Impl>
|
||||||
|
void
|
||||||
|
DefaultCommit<Impl>::resume()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
void
|
||||||
DefaultCommit<Impl>::takeOverFrom()
|
DefaultCommit<Impl>::takeOverFrom()
|
||||||
|
@ -557,8 +563,9 @@ DefaultCommit<Impl>::tick()
|
||||||
wroteToTimeBuffer = false;
|
wroteToTimeBuffer = false;
|
||||||
_nextStatus = Inactive;
|
_nextStatus = Inactive;
|
||||||
|
|
||||||
if (switchPending && rob->isEmpty() && !iewStage->hasStoresToWB()) {
|
if (drainPending && rob->isEmpty() && !iewStage->hasStoresToWB()) {
|
||||||
cpu->signalSwitched();
|
cpu->signalDrained();
|
||||||
|
drainPending = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -158,7 +158,7 @@ FullO3CPU<Impl>::FullO3CPU(Params *params)
|
||||||
physmem(system->physmem),
|
physmem(system->physmem),
|
||||||
#endif // FULL_SYSTEM
|
#endif // FULL_SYSTEM
|
||||||
mem(params->mem),
|
mem(params->mem),
|
||||||
switchCount(0),
|
drainCount(0),
|
||||||
deferRegistration(params->deferRegistration),
|
deferRegistration(params->deferRegistration),
|
||||||
numThreads(number_of_threads)
|
numThreads(number_of_threads)
|
||||||
{
|
{
|
||||||
|
@ -708,45 +708,72 @@ FullO3CPU<Impl>::haltContext(int tid)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
bool
|
||||||
FullO3CPU<Impl>::switchOut()
|
FullO3CPU<Impl>::drain(Event *drain_event)
|
||||||
{
|
{
|
||||||
switchCount = 0;
|
drainCount = 0;
|
||||||
fetch.switchOut();
|
drainEvent = drain_event;
|
||||||
decode.switchOut();
|
fetch.drain();
|
||||||
rename.switchOut();
|
decode.drain();
|
||||||
iew.switchOut();
|
rename.drain();
|
||||||
commit.switchOut();
|
iew.drain();
|
||||||
|
commit.drain();
|
||||||
|
|
||||||
// Wake the CPU and record activity so everything can drain out if
|
// Wake the CPU and record activity so everything can drain out if
|
||||||
// the CPU is currently idle.
|
// the CPU is currently idle.
|
||||||
wakeCPU();
|
wakeCPU();
|
||||||
activityRec.activity();
|
activityRec.activity();
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
void
|
||||||
FullO3CPU<Impl>::signalSwitched()
|
FullO3CPU<Impl>::resume()
|
||||||
{
|
{
|
||||||
if (++switchCount == NumStages) {
|
if (_status == SwitchedOut)
|
||||||
fetch.doSwitchOut();
|
return;
|
||||||
rename.doSwitchOut();
|
fetch.resume();
|
||||||
commit.doSwitchOut();
|
decode.resume();
|
||||||
instList.clear();
|
rename.resume();
|
||||||
while (!removeList.empty()) {
|
iew.resume();
|
||||||
removeList.pop();
|
commit.resume();
|
||||||
}
|
|
||||||
|
|
||||||
#if USE_CHECKER
|
if (!tickEvent.scheduled())
|
||||||
if (checker)
|
tickEvent.schedule(curTick);
|
||||||
checker->switchOut();
|
_status = Running;
|
||||||
#endif
|
}
|
||||||
|
|
||||||
|
template <class Impl>
|
||||||
|
void
|
||||||
|
FullO3CPU<Impl>::signalDrained()
|
||||||
|
{
|
||||||
|
if (++drainCount == NumStages) {
|
||||||
if (tickEvent.scheduled())
|
if (tickEvent.scheduled())
|
||||||
tickEvent.squash();
|
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>
|
template <class Impl>
|
||||||
|
|
|
@ -57,6 +57,8 @@ class Checker;
|
||||||
class ThreadContext;
|
class ThreadContext;
|
||||||
template <class>
|
template <class>
|
||||||
class O3ThreadContext;
|
class O3ThreadContext;
|
||||||
|
|
||||||
|
class Checkpoint;
|
||||||
class MemObject;
|
class MemObject;
|
||||||
class Process;
|
class Process;
|
||||||
|
|
||||||
|
@ -109,6 +111,7 @@ class FullO3CPU : public BaseO3CPU
|
||||||
Idle,
|
Idle,
|
||||||
Halted,
|
Halted,
|
||||||
Blocked,
|
Blocked,
|
||||||
|
Drained,
|
||||||
SwitchedOut
|
SwitchedOut
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -270,14 +273,21 @@ class FullO3CPU : public BaseO3CPU
|
||||||
*/
|
*/
|
||||||
virtual void syscall(int tid) { panic("Unimplemented!"); }
|
virtual void syscall(int tid) { panic("Unimplemented!"); }
|
||||||
|
|
||||||
/** Switches out this CPU. */
|
/** Starts draining the CPU's pipeline of all instructions in
|
||||||
void switchOut();
|
* 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. */
|
/** 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. */
|
/** Takes over from another CPU. */
|
||||||
void takeOverFrom(BaseCPU *oldCPU);
|
virtual void takeOverFrom(BaseCPU *oldCPU);
|
||||||
|
|
||||||
/** Get the current instruction sequence number, and increment it. */
|
/** Get the current instruction sequence number, and increment it. */
|
||||||
InstSeqNum getAndIncrementInstSeq()
|
InstSeqNum getAndIncrementInstSeq()
|
||||||
|
@ -550,8 +560,11 @@ class FullO3CPU : public BaseO3CPU
|
||||||
/** Pointer to memory. */
|
/** Pointer to memory. */
|
||||||
MemObject *mem;
|
MemObject *mem;
|
||||||
|
|
||||||
/** Counter of how many stages have completed switching out. */
|
/** Event to call process() on once draining has completed. */
|
||||||
int switchCount;
|
Event *drainEvent;
|
||||||
|
|
||||||
|
/** Counter of how many stages have completed draining. */
|
||||||
|
int drainCount;
|
||||||
|
|
||||||
/** Pointers to all of the threads in the CPU. */
|
/** Pointers to all of the threads in the CPU. */
|
||||||
std::vector<Thread *> thread;
|
std::vector<Thread *> thread;
|
||||||
|
|
|
@ -109,8 +109,14 @@ class DefaultDecode
|
||||||
/** Sets pointer to list of active threads. */
|
/** Sets pointer to list of active threads. */
|
||||||
void setActiveThreads(std::list<unsigned> *at_ptr);
|
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. */
|
/** Switches out the decode stage. */
|
||||||
void switchOut();
|
void switchOut() { }
|
||||||
|
|
||||||
/** Takes over from another CPU's thread. */
|
/** Takes over from another CPU's thread. */
|
||||||
void takeOverFrom();
|
void takeOverFrom();
|
||||||
|
|
|
@ -166,10 +166,10 @@ DefaultDecode<Impl>::setActiveThreads(list<unsigned> *at_ptr)
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
void
|
||||||
DefaultDecode<Impl>::switchOut()
|
DefaultDecode<Impl>::drain()
|
||||||
{
|
{
|
||||||
// Decode can immediately switch out.
|
// Decode is done draining at any time.
|
||||||
cpu->signalSwitched();
|
cpu->signalDrained();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
|
|
|
@ -180,11 +180,14 @@ class DefaultFetch
|
||||||
/** Processes cache completion event. */
|
/** Processes cache completion event. */
|
||||||
void processCacheCompletion(PacketPtr pkt);
|
void processCacheCompletion(PacketPtr pkt);
|
||||||
|
|
||||||
/** Begins the switch out of the fetch stage. */
|
/** Begins the drain of the fetch stage. */
|
||||||
void switchOut();
|
void drain();
|
||||||
|
|
||||||
/** Completes the switch out of the fetch stage. */
|
/** Resumes execution after a drain. */
|
||||||
void doSwitchOut();
|
void resume();
|
||||||
|
|
||||||
|
/** Tells fetch stage to prepare to be switched out. */
|
||||||
|
void switchOut();
|
||||||
|
|
||||||
/** Takes over from another CPU's thread. */
|
/** Takes over from another CPU's thread. */
|
||||||
void takeOverFrom();
|
void takeOverFrom();
|
||||||
|
@ -421,6 +424,9 @@ class DefaultFetch
|
||||||
*/
|
*/
|
||||||
bool interruptPending;
|
bool interruptPending;
|
||||||
|
|
||||||
|
/** Is there a drain pending. */
|
||||||
|
bool drainPending;
|
||||||
|
|
||||||
/** Records if fetch is switched out. */
|
/** Records if fetch is switched out. */
|
||||||
bool switchedOut;
|
bool switchedOut;
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,7 @@ DefaultFetch<Impl>::DefaultFetch(Params *params)
|
||||||
numThreads(params->numberOfThreads),
|
numThreads(params->numberOfThreads),
|
||||||
numFetchingThreads(params->smtNumFetchingThreads),
|
numFetchingThreads(params->smtNumFetchingThreads),
|
||||||
interruptPending(false),
|
interruptPending(false),
|
||||||
|
drainPending(false),
|
||||||
switchedOut(false)
|
switchedOut(false)
|
||||||
{
|
{
|
||||||
if (numThreads > Impl::MaxThreads)
|
if (numThreads > Impl::MaxThreads)
|
||||||
|
@ -353,7 +354,8 @@ DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)
|
||||||
// to return.
|
// to return.
|
||||||
if (fetchStatus[tid] != IcacheWaitResponse ||
|
if (fetchStatus[tid] != IcacheWaitResponse ||
|
||||||
pkt->req != memReq[tid] ||
|
pkt->req != memReq[tid] ||
|
||||||
isSwitchedOut()) {
|
isSwitchedOut() ||
|
||||||
|
drainPending) {
|
||||||
++fetchIcacheSquashes;
|
++fetchIcacheSquashes;
|
||||||
delete pkt->req;
|
delete pkt->req;
|
||||||
delete pkt;
|
delete pkt;
|
||||||
|
@ -384,17 +386,25 @@ DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
void
|
||||||
DefaultFetch<Impl>::switchOut()
|
DefaultFetch<Impl>::drain()
|
||||||
{
|
{
|
||||||
// Fetch is ready to switch out at any time.
|
// Fetch is ready to drain at any time.
|
||||||
switchedOut = true;
|
cpu->signalDrained();
|
||||||
cpu->signalSwitched();
|
drainPending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
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.
|
// Branch predictor needs to have its state cleared.
|
||||||
branchPred.switchOut();
|
branchPred.switchOut();
|
||||||
}
|
}
|
||||||
|
@ -498,7 +508,7 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
|
||||||
unsigned flags = 0;
|
unsigned flags = 0;
|
||||||
#endif // FULL_SYSTEM
|
#endif // FULL_SYSTEM
|
||||||
|
|
||||||
if (cacheBlocked || (interruptPending && flags == 0) || switchedOut) {
|
if (cacheBlocked || (interruptPending && flags == 0) || drainPending) {
|
||||||
// Hold off fetch from getting new instructions when:
|
// Hold off fetch from getting new instructions when:
|
||||||
// Cache is blocked, or
|
// Cache is blocked, or
|
||||||
// while an interrupt is pending and we're not in PAL mode, or
|
// while an interrupt is pending and we're not in PAL mode, or
|
||||||
|
|
|
@ -143,11 +143,14 @@ class DefaultIEW
|
||||||
/** Sets pointer to the scoreboard. */
|
/** Sets pointer to the scoreboard. */
|
||||||
void setScoreboard(Scoreboard *sb_ptr);
|
void setScoreboard(Scoreboard *sb_ptr);
|
||||||
|
|
||||||
/** Starts switch out of IEW stage. */
|
/** Drains IEW stage. */
|
||||||
void switchOut();
|
void drain();
|
||||||
|
|
||||||
|
/** Resumes execution after a drain. */
|
||||||
|
void resume();
|
||||||
|
|
||||||
/** Completes switch out of IEW stage. */
|
/** Completes switch out of IEW stage. */
|
||||||
void doSwitchOut();
|
void switchOut();
|
||||||
|
|
||||||
/** Takes over from another CPU's thread. */
|
/** Takes over from another CPU's thread. */
|
||||||
void takeOverFrom();
|
void takeOverFrom();
|
||||||
|
|
|
@ -355,15 +355,21 @@ DefaultIEW<Impl>::setScoreboard(Scoreboard *sb_ptr)
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
void
|
||||||
DefaultIEW<Impl>::switchOut()
|
DefaultIEW<Impl>::drain()
|
||||||
{
|
{
|
||||||
// IEW is ready to switch out at any time.
|
// IEW is ready to drain at any time.
|
||||||
cpu->signalSwitched();
|
cpu->signalDrained();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
void
|
||||||
DefaultIEW<Impl>::doSwitchOut()
|
DefaultIEW<Impl>::resume()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Impl>
|
||||||
|
void
|
||||||
|
DefaultIEW<Impl>::switchOut()
|
||||||
{
|
{
|
||||||
// Clear any state.
|
// Clear any state.
|
||||||
switchedOut = true;
|
switchedOut = true;
|
||||||
|
|
|
@ -157,12 +157,15 @@ class DefaultRename
|
||||||
/** Sets pointer to the scoreboard. */
|
/** Sets pointer to the scoreboard. */
|
||||||
void setScoreboard(Scoreboard *_scoreboard);
|
void setScoreboard(Scoreboard *_scoreboard);
|
||||||
|
|
||||||
|
/** Drains the rename stage. */
|
||||||
|
void drain();
|
||||||
|
|
||||||
|
/** Resumes execution after a drain. */
|
||||||
|
void resume() { }
|
||||||
|
|
||||||
/** Switches out the rename stage. */
|
/** Switches out the rename stage. */
|
||||||
void switchOut();
|
void switchOut();
|
||||||
|
|
||||||
/** Completes the switch out. */
|
|
||||||
void doSwitchOut();
|
|
||||||
|
|
||||||
/** Takes over from another CPU's thread. */
|
/** Takes over from another CPU's thread. */
|
||||||
void takeOverFrom();
|
void takeOverFrom();
|
||||||
|
|
||||||
|
|
|
@ -258,15 +258,15 @@ DefaultRename<Impl>::setScoreboard(Scoreboard *_scoreboard)
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
void
|
||||||
DefaultRename<Impl>::switchOut()
|
DefaultRename<Impl>::drain()
|
||||||
{
|
{
|
||||||
// Rename is ready to switch out at any time.
|
// Rename is ready to switch out at any time.
|
||||||
cpu->signalSwitched();
|
cpu->signalDrained();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
void
|
||||||
DefaultRename<Impl>::doSwitchOut()
|
DefaultRename<Impl>::switchOut()
|
||||||
{
|
{
|
||||||
// Clear any state, fix up the rename map.
|
// Clear any state, fix up the rename map.
|
||||||
for (int i = 0; i < numThreads; i++) {
|
for (int i = 0; i < numThreads; i++) {
|
||||||
|
|
|
@ -547,7 +547,7 @@ class SimObject(object):
|
||||||
count = 0
|
count = 0
|
||||||
# ParamContexts don't serialize
|
# ParamContexts don't serialize
|
||||||
if isinstance(self, SimObject) and not isinstance(self, ParamContext):
|
if isinstance(self, SimObject) and not isinstance(self, ParamContext):
|
||||||
if self._ccObject.drain(drain_event):
|
if not self._ccObject.drain(drain_event):
|
||||||
count = 1
|
count = 1
|
||||||
if recursive:
|
if recursive:
|
||||||
for child in self._children.itervalues():
|
for child in self._children.itervalues():
|
||||||
|
|
|
@ -277,7 +277,7 @@ SimObject::drain(Event *drain_event)
|
||||||
"in timing mode!");
|
"in timing mode!");
|
||||||
}
|
}
|
||||||
state = DrainedAtomic;
|
state = DrainedAtomic;
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -116,7 +116,7 @@ class SimObject : public Serializable, protected StartupCallback
|
||||||
|
|
||||||
// Methods to drain objects in order to take checkpoints
|
// Methods to drain objects in order to take checkpoints
|
||||||
// Or switch from timing -> atomic memory model
|
// Or switch from timing -> atomic memory model
|
||||||
// Quiesce returns true if the SimObject cannot quiesce immediately.
|
// Drain returns false if the SimObject cannot drain immediately.
|
||||||
virtual bool drain(Event *drain_event);
|
virtual bool drain(Event *drain_event);
|
||||||
virtual void resume();
|
virtual void resume();
|
||||||
virtual void setMemoryMode(State new_mode);
|
virtual void setMemoryMode(State new_mode);
|
||||||
|
|
Loading…
Reference in a new issue