diff options
Diffstat (limited to 'cpu/simple_cpu')
-rw-r--r-- | cpu/simple_cpu/simple_cpu.cc | 83 | ||||
-rw-r--r-- | cpu/simple_cpu/simple_cpu.hh | 11 |
2 files changed, 70 insertions, 24 deletions
diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc index df78eb9a9..254c21b15 100644 --- a/cpu/simple_cpu/simple_cpu.cc +++ b/cpu/simple_cpu/simple_cpu.cc @@ -47,6 +47,7 @@ #include "cpu/exec_context.hh" #include "cpu/exetrace.hh" #include "cpu/full_cpu/smt.hh" +#include "cpu/sampling_cpu/sampling_cpu.hh" #include "cpu/simple_cpu/simple_cpu.hh" #include "cpu/static_inst.hh" #include "mem/base_mem.hh" @@ -149,11 +150,21 @@ SimpleCPU::~SimpleCPU() } void -SimpleCPU::switchOut() +SimpleCPU::switchOut(SamplingCPU *s) { - _status = SwitchedOut; - if (tickEvent.scheduled()) - tickEvent.squash(); + sampler = s; + if (status() == DcacheMissStall) { + DPRINTF(Sampler,"Outstanding dcache access, waiting for completion\n"); + _status = DcacheMissSwitch; + } + else { + _status = SwitchedOut; + + if (tickEvent.scheduled()) + tickEvent.squash(); + + sampler->signalSwitched(); + } } @@ -173,8 +184,6 @@ SimpleCPU::takeOverFrom(BaseCPU *oldCPU) tickEvent.schedule(curTick); } } - - oldCPU->switchOut(); } @@ -384,21 +393,22 @@ template <class T> Fault SimpleCPU::read(Addr addr, T &data, unsigned flags) { + if (status() == DcacheMissStall) { + Fault fault = xc->read(memReq,data); + + if (traceData) { + traceData->setAddr(addr); + if (fault == No_Fault) + traceData->setData(data); + } + return fault; + } + memReq->reset(addr, sizeof(T), flags); // translate to physical address Fault fault = xc->translateDataReadReq(memReq); - // do functional access - if (fault == No_Fault) - fault = xc->read(memReq, data); - - if (traceData) { - traceData->setAddr(addr); - if (fault == No_Fault) - traceData->setData(data); - } - // if we have a cache, do cache access too if (fault == No_Fault && dcacheInterface) { memReq->cmd = Read; @@ -414,6 +424,24 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) lastDcacheStall = curTick; unscheduleTickEvent(); _status = DcacheMissStall; + } else { + // do functional access + fault = xc->read(memReq, data); + + if (traceData) { + traceData->setAddr(addr); + if (fault == No_Fault) + traceData->setData(data); + } + } + } else if(fault == No_Fault) { + // do functional access + fault = xc->read(memReq, data); + + if (traceData) { + traceData->setAddr(addr); + if (fault == No_Fault) + traceData->setData(data); } } @@ -572,10 +600,19 @@ SimpleCPU::processCacheCompletion() scheduleTickEvent(1); break; case DcacheMissStall: + if (memReq->cmd.isRead()) { + curStaticInst->execute(this,traceData); + } dcacheStallCycles += curTick - lastDcacheStall; _status = Running; scheduleTickEvent(1); break; + case DcacheMissSwitch: + if (memReq->cmd.isRead()) { + curStaticInst->execute(this,traceData); + } + _status = SwitchedOut; + sampler->signalSwitched(); case SwitchedOut: // If this CPU has been switched out due to sampling/warm-up, // ignore any further status changes (e.g., due to cache @@ -717,10 +754,10 @@ SimpleCPU::tick() comInstEventQueue[0]->serviceEvents(numInst); // decode the instruction - inst = htoa(inst); - StaticInstPtr<TheISA> si(inst); + inst = htoa(inst); + curStaticInst = StaticInst<TheISA>::decode(inst); - traceData = Trace::getInstRecord(curTick, xc, this, si, + traceData = Trace::getInstRecord(curTick, xc, this, curStaticInst, xc->regs.pc); #ifdef FULL_SYSTEM @@ -729,18 +766,18 @@ SimpleCPU::tick() xc->func_exe_inst++; - fault = si->execute(this, traceData); + fault = curStaticInst->execute(this, traceData); #ifdef FULL_SYSTEM if (xc->fnbin) - xc->execute(si.get()); + xc->execute(curStaticInst.get()); #endif - if (si->isMemRef()) { + if (curStaticInst->isMemRef()) { numMemRefs++; } - if (si->isLoad()) { + if (curStaticInst->isLoad()) { ++numLoad; comLoadEventQueue[0]->serviceEvents(numLoad); } diff --git a/cpu/simple_cpu/simple_cpu.hh b/cpu/simple_cpu/simple_cpu.hh index c802a1c06..f245a7bba 100644 --- a/cpu/simple_cpu/simple_cpu.hh +++ b/cpu/simple_cpu/simple_cpu.hh @@ -33,6 +33,7 @@ #include "cpu/base_cpu.hh" #include "cpu/exec_context.hh" #include "cpu/pc_event.hh" +#include "cpu/sampling_cpu/sampling_cpu.hh" #include "cpu/static_inst.hh" #include "sim/eventq.hh" @@ -105,6 +106,7 @@ class SimpleCPU : public BaseCPU IcacheMissStall, IcacheMissComplete, DcacheMissStall, + DcacheMissSwitch, SwitchedOut }; @@ -143,7 +145,7 @@ class SimpleCPU : public BaseCPU // execution context ExecContext *xc; - void switchOut(); + void switchOut(SamplingCPU *s); void takeOverFrom(BaseCPU *oldCPU); #ifdef FULL_SYSTEM @@ -164,6 +166,13 @@ class SimpleCPU : public BaseCPU // Refcounted pointer to the one memory request. MemReqPtr memReq; + // Pointer to the sampler that is telling us to switchover. + // Used to signal the completion of the pipe drain and schedule + // the next switchover + SamplingCPU *sampler; + + StaticInstPtr<TheISA> curStaticInst; + class CacheCompletionEvent : public Event { private: |