summaryrefslogtreecommitdiff
path: root/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'cpu')
-rw-r--r--cpu/base_cpu.cc6
-rw-r--r--cpu/base_cpu.hh7
-rw-r--r--cpu/pc_event.cc7
-rw-r--r--cpu/simple_cpu/simple_cpu.cc83
-rw-r--r--cpu/simple_cpu/simple_cpu.hh11
5 files changed, 83 insertions, 31 deletions
diff --git a/cpu/base_cpu.cc b/cpu/base_cpu.cc
index a17edd371..181b484e7 100644
--- a/cpu/base_cpu.cc
+++ b/cpu/base_cpu.cc
@@ -36,6 +36,7 @@
#include "base/output.hh"
#include "cpu/base_cpu.hh"
#include "cpu/exec_context.hh"
+#include "cpu/sampling_cpu/sampling_cpu.hh"
#include "sim/param.hh"
#include "sim/sim_events.hh"
@@ -194,9 +195,10 @@ BaseCPU::registerExecContexts()
void
-BaseCPU::switchOut()
+BaseCPU::switchOut(SamplingCPU *sampler)
{
- // default: do nothing
+ // default: do nothing, signal done
+ sampler->signalSwitched();
}
void
diff --git a/cpu/base_cpu.hh b/cpu/base_cpu.hh
index dd1c7ac58..f346f4ec5 100644
--- a/cpu/base_cpu.hh
+++ b/cpu/base_cpu.hh
@@ -32,6 +32,7 @@
#include <vector>
#include "base/statistics.hh"
+#include "cpu/sampling_cpu/sampling_cpu.hh"
#include "sim/eventq.hh"
#include "sim/sim_object.hh"
#include "targetarch/isa_traits.hh"
@@ -117,9 +118,9 @@ class BaseCPU : public SimObject
void registerExecContexts();
- /// Prepare for another CPU to take over execution. Called by
- /// takeOverFrom() on its argument.
- virtual void switchOut();
+ /// Prepare for another CPU to take over execution. When it is
+ /// is ready (drained pipe) it signals the sampler.
+ virtual void switchOut(SamplingCPU *);
/// Take over execution from the given CPU. Used for warm-up and
/// sampling.
diff --git a/cpu/pc_event.cc b/cpu/pc_event.cc
index 8f046a7a4..21eef677a 100644
--- a/cpu/pc_event.cc
+++ b/cpu/pc_event.cc
@@ -31,10 +31,11 @@
#include <string>
#include <utility>
-#include "sim/debug.hh"
+#include "base/trace.hh"
+#include "cpu/base_cpu.hh"
#include "cpu/exec_context.hh"
#include "cpu/pc_event.hh"
-#include "base/trace.hh"
+#include "sim/debug.hh"
#include "sim/universe.hh"
using namespace std;
@@ -123,6 +124,8 @@ BreakPCEvent::BreakPCEvent(PCEventQueue *q, const std::string &desc, bool del)
void
BreakPCEvent::process(ExecContext *xc)
{
+ StringWrap name(xc->cpu->name() + ".break_event");
+ DPRINTFN("break event %s triggered", descr());
debug_break();
if (remove)
delete this;
diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc
index 044ee9b9d..86aeab7d7 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);
}
}
@@ -575,10 +603,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
@@ -720,10 +757,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,18 +769,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: