diff options
-rw-r--r-- | cpu/base_cpu.cc | 6 | ||||
-rw-r--r-- | cpu/base_cpu.hh | 7 | ||||
-rw-r--r-- | cpu/pc_event.cc | 7 | ||||
-rw-r--r-- | cpu/simple_cpu/simple_cpu.cc | 83 | ||||
-rw-r--r-- | cpu/simple_cpu/simple_cpu.hh | 11 | ||||
-rw-r--r-- | kern/linux/linux_system.cc | 11 | ||||
-rw-r--r-- | kern/linux/linux_system.hh | 5 |
7 files changed, 96 insertions, 34 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 0283545f4..425b86ee5 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: diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc index 401b4ef44..4ac03143e 100644 --- a/kern/linux/linux_system.cc +++ b/kern/linux/linux_system.cc @@ -102,12 +102,19 @@ LinuxSystem::LinuxSystem(Params *p) } else panic("could not find dp264_mv\n"); -#ifdef DEBUG +#ifndef NDEBUG kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic"); if (kernelSymtab->findAddress("panic", addr)) kernelPanicEvent->schedule(addr); else panic("could not find kernel symbol \'panic\'"); + + kernelDieEvent = new BreakPCEvent(&pcEventQueue, "die if kernel"); + if (kernelSymtab->findAddress("die_if_kernel", addr)) + kernelDieEvent->schedule(addr); + else + panic("could not find kernel symbol \'die_if_kernel\'"); + #endif /** @@ -174,7 +181,7 @@ LinuxSystem::LinuxSystem(Params *p) LinuxSystem::~LinuxSystem() { -#ifdef DEBUG +#ifndef NDEBUG delete kernelPanicEvent; #endif delete skipIdeDelay50msEvent; diff --git a/kern/linux/linux_system.hh b/kern/linux/linux_system.hh index 5e3cba9b3..905b0ee70 100644 --- a/kern/linux/linux_system.hh +++ b/kern/linux/linux_system.hh @@ -57,9 +57,12 @@ class PrintThreadInfo; class LinuxSystem : public System { private: -#ifdef DEBUG +#ifndef NDEBUG /** Event to halt the simulator if the kernel calls panic() */ BreakPCEvent *kernelPanicEvent; + + /** Event to halt the simulator if the kernel calls die_if_kernel */ + BreakPCEvent *kernelDieEvent; #endif /** |