summaryrefslogtreecommitdiff
path: root/cpu/simple_cpu/simple_cpu.cc
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/simple_cpu/simple_cpu.cc')
-rw-r--r--cpu/simple_cpu/simple_cpu.cc86
1 files changed, 57 insertions, 29 deletions
diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc
index 044ee9b9d..6a95a52c2 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,20 @@ template <class T>
Fault
SimpleCPU::read(Addr addr, T &data, unsigned flags)
{
+ if (status() == DcacheMissStall || status() == DcacheMissSwitch) {
+ Fault fault = xc->read(memReq,data);
+
+ if (traceData) {
+ traceData->setAddr(addr);
+ }
+ 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,7 +422,15 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
lastDcacheStall = curTick;
unscheduleTickEvent();
_status = DcacheMissStall;
+ } else {
+ // do functional access
+ fault = xc->read(memReq, data);
+
}
+ } else if(fault == No_Fault) {
+ // do functional access
+ fault = xc->read(memReq, data);
+
}
if (!dcacheInterface && (memReq->flags & UNCACHEABLE))
@@ -470,11 +486,6 @@ template <class T>
Fault
SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
{
- if (traceData) {
- traceData->setAddr(addr);
- traceData->setData(data);
- }
-
memReq->reset(addr, sizeof(T), flags);
// translate to physical address
@@ -575,10 +586,23 @@ SimpleCPU::processCacheCompletion()
scheduleTickEvent(1);
break;
case DcacheMissStall:
+ if (memReq->cmd.isRead()) {
+ curStaticInst->execute(this,traceData);
+ if (traceData)
+ traceData->finalize();
+ }
dcacheStallCycles += curTick - lastDcacheStall;
_status = Running;
scheduleTickEvent(1);
break;
+ case DcacheMissSwitch:
+ if (memReq->cmd.isRead()) {
+ curStaticInst->execute(this,traceData);
+ if (traceData)
+ traceData->finalize();
+ }
+ _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
@@ -720,10 +744,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
@@ -732,24 +756,28 @@ 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);
}
- if (traceData)
+ // If we have a dcache miss, then we can't finialize the instruction
+ // trace yet because we want to populate it with the data later
+ if (traceData &&
+ !(status() == DcacheMissStall && memReq->cmd.isRead())) {
traceData->finalize();
+ }
traceFunctions(xc->regs.pc);