diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cpu/base.cc | 2 | ||||
-rw-r--r-- | src/cpu/base.hh | 2 | ||||
-rw-r--r-- | src/cpu/simple/atomic.cc | 15 | ||||
-rw-r--r-- | src/cpu/simple/atomic.hh | 2 | ||||
-rw-r--r-- | src/cpu/simple/timing.cc | 67 | ||||
-rw-r--r-- | src/cpu/simple/timing.hh | 10 |
6 files changed, 78 insertions, 20 deletions
diff --git a/src/cpu/base.cc b/src/cpu/base.cc index 55c04c498..40cec416b 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -237,7 +237,7 @@ BaseCPU::registerThreadContexts() void -BaseCPU::switchOut(Sampler *sampler) +BaseCPU::switchOut() { panic("This CPU doesn't support sampling!"); } diff --git a/src/cpu/base.hh b/src/cpu/base.hh index 43122f238..51f3bb905 100644 --- a/src/cpu/base.hh +++ b/src/cpu/base.hh @@ -148,7 +148,7 @@ class BaseCPU : public SimObject /// Prepare for another CPU to take over execution. When it is /// is ready (drained pipe) it signals the sampler. - virtual void switchOut(Sampler *); + virtual void switchOut(); /// Take over execution from the given CPU. Used for warm-up and /// sampling. diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 071193f02..7be74e97e 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -145,8 +145,8 @@ AtomicSimpleCPU::~AtomicSimpleCPU() void AtomicSimpleCPU::serialize(ostream &os) { - BaseSimpleCPU::serialize(os); SERIALIZE_ENUM(_status); + BaseSimpleCPU::serialize(os); nameOut(os, csprintf("%s.tickEvent", name())); tickEvent.serialize(os); } @@ -154,21 +154,18 @@ AtomicSimpleCPU::serialize(ostream &os) void AtomicSimpleCPU::unserialize(Checkpoint *cp, const string §ion) { - BaseSimpleCPU::unserialize(cp, section); UNSERIALIZE_ENUM(_status); + BaseSimpleCPU::unserialize(cp, section); tickEvent.unserialize(cp, csprintf("%s.tickEvent", section)); } void -AtomicSimpleCPU::switchOut(Sampler *s) +AtomicSimpleCPU::switchOut() { - sampler = s; - if (status() == Running) { - _status = SwitchedOut; + assert(status() == Running || status() == Idle); + _status = SwitchedOut; - tickEvent.squash(); - } - sampler->signalSwitched(); + tickEvent.squash(); } diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh index 7f4956da9..951a8da06 100644 --- a/src/cpu/simple/atomic.hh +++ b/src/cpu/simple/atomic.hh @@ -125,7 +125,7 @@ class AtomicSimpleCPU : public BaseSimpleCPU virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); - void switchOut(Sampler *s); + void switchOut(); void takeOverFrom(BaseCPU *oldCPU); virtual void activateContext(int thread_num, int delay); diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index c99db8fbf..0729f9489 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -88,6 +88,8 @@ TimingSimpleCPU::TimingSimpleCPU(Params *p) { _status = Idle; ifetch_pkt = dcache_pkt = NULL; + quiesceEvent = NULL; + state = SimObject::Timing; } @@ -98,25 +100,54 @@ TimingSimpleCPU::~TimingSimpleCPU() void TimingSimpleCPU::serialize(ostream &os) { - BaseSimpleCPU::serialize(os); SERIALIZE_ENUM(_status); + BaseSimpleCPU::serialize(os); } void TimingSimpleCPU::unserialize(Checkpoint *cp, const string §ion) { - BaseSimpleCPU::unserialize(cp, section); UNSERIALIZE_ENUM(_status); + BaseSimpleCPU::unserialize(cp, section); +} + +bool +TimingSimpleCPU::quiesce(Event *quiesce_event) +{ + // TimingSimpleCPU is ready to quiesce if it's not waiting for + // an access to complete. + if (status() == Idle || status() == Running || status() == SwitchedOut) { + DPRINTF(Config, "Ready to quiesce\n"); + return false; + } else { + DPRINTF(Config, "Waiting to quiesce\n"); + changeState(SimObject::Quiescing); + quiesceEvent = quiesce_event; + return true; + } } void -TimingSimpleCPU::switchOut(Sampler *s) +TimingSimpleCPU::resume() { - sampler = s; - if (status() == Running) { - _status = SwitchedOut; + if (_status != SwitchedOut && _status != Idle) { + Event *e = + new EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch>(this, true); + e->schedule(curTick); } - sampler->signalSwitched(); +} + +void +TimingSimpleCPU::setMemoryMode(State new_mode) +{ + assert(new_mode == SimObject::Timing); +} + +void +TimingSimpleCPU::switchOut() +{ + assert(status() == Running || status() == Idle); + _status = SwitchedOut; } @@ -383,11 +414,17 @@ TimingSimpleCPU::completeIfetch(Packet *pkt) // instruction assert(pkt->result == Packet::Success); assert(_status == IcacheWaitResponse); + _status = Running; delete pkt->req; delete pkt; + if (getState() == SimObject::Quiescing) { + completeQuiesce(); + return; + } + preExecute(); if (curStaticInst->isMemRef() && !curStaticInst->isDataPrefetch()) { // load or store: just send to dcache @@ -440,6 +477,15 @@ TimingSimpleCPU::completeDataAccess(Packet *pkt) assert(_status == DcacheWaitResponse); _status = Running; + if (getState() == SimObject::Quiescing) { + completeQuiesce(); + + delete pkt->req; + delete pkt; + + return; + } + Fault fault = curStaticInst->completeAcc(pkt, this, traceData); delete pkt->req; @@ -450,6 +496,13 @@ TimingSimpleCPU::completeDataAccess(Packet *pkt) } +void +TimingSimpleCPU::completeQuiesce() +{ + DPRINTF(Config, "Done quiescing\n"); + changeState(SimObject::QuiescedTiming); + quiesceEvent->process(); +} bool TimingSimpleCPU::DcachePort::recvTiming(Packet *pkt) diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh index ab0b2d2ca..d91144e4a 100644 --- a/src/cpu/simple/timing.hh +++ b/src/cpu/simple/timing.hh @@ -64,6 +64,8 @@ class TimingSimpleCPU : public BaseSimpleCPU Status status() const { return _status; } + Event *quiesceEvent; + private: class CpuPort : public Port @@ -131,7 +133,11 @@ class TimingSimpleCPU : public BaseSimpleCPU virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); - void switchOut(Sampler *s); + virtual bool quiesce(Event *quiesce_event); + virtual void resume(); + virtual void setMemoryMode(State new_mode); + + void switchOut(); void takeOverFrom(BaseCPU *oldCPU); virtual void activateContext(int thread_num, int delay); @@ -147,6 +153,8 @@ class TimingSimpleCPU : public BaseSimpleCPU void completeIfetch(Packet *); void completeDataAccess(Packet *); void advanceInst(Fault fault); + private: + void completeQuiesce(); }; #endif // __CPU_SIMPLE_TIMING_HH__ |