#include "cpu/thread_context.hh"
#include "cpu/profile.hh"
#include "sim/sim_exit.hh"
-#include "sim/param.hh"
#include "sim/process.hh"
#include "sim/sim_events.hh"
#include "sim/system.hh"
CPUProgressEvent::CPUProgressEvent(EventQueue *q, Tick ival,
BaseCPU *_cpu)
- : Event(q, Event::Stat_Event_Pri), interval(ival),
+ : Event(q, Event::Progress_Event_Pri), interval(ival),
lastNumInst(0), cpu(_cpu)
{
if (interval)
{
Counter temp = cpu->totalInstructions();
#ifndef NDEBUG
- double ipc = double(temp - lastNumInst) / (interval / cpu->cycles(1));
+ double ipc = double(temp - lastNumInst) / (interval / cpu->ticks(1));
DPRINTFN("%s progress event, instructions committed: %lli, IPC: %0.8d\n",
cpu->name(), temp - lastNumInst, ipc);
const char *
CPUProgressEvent::description()
{
- return "CPU Progress event";
+ return "CPU Progress";
}
#if FULL_SYSTEM
BaseCPU::BaseCPU(Params *p)
- : MemObject(p->name), clock(p->clock), checkInterrupts(true),
- params(p), number_of_threads(p->numberOfThreads), system(p->system)
+ : MemObject(makeParams(p->name)), clock(p->clock), instCnt(0),
+ params(p), number_of_threads(p->numberOfThreads), system(p->system),
+ phase(p->phase)
#else
BaseCPU::BaseCPU(Params *p)
- : MemObject(p->name), clock(p->clock), params(p),
- number_of_threads(p->numberOfThreads), system(p->system)
+ : MemObject(makeParams(p->name)), clock(p->clock), params(p),
+ number_of_threads(p->numberOfThreads), system(p->system),
+ phase(p->phase)
#endif
{
// currentTick = curTick;
- DPRINTF(FullCPU, "BaseCPU: Creating object, mem address %#x.\n", this);
// add self to global list of CPUs
cpuList.push_back(this);
- DPRINTF(FullCPU, "BaseCPU: CPU added to cpuList, mem address %#x.\n",
- this);
-
if (number_of_threads > maxThreadsPerCPU)
maxThreadsPerCPU = number_of_threads;
p->max_loads_all_threads, *counter);
}
-#if FULL_SYSTEM
- memset(interrupts, 0, sizeof(interrupts));
- intstatus = 0;
-#endif
-
functionTracingEnabled = false;
if (p->functionTrace) {
functionTraceStream = simout.find(csprintf("ftrace.%s", name()));
if (p->functionTraceStart == 0) {
functionTracingEnabled = true;
} else {
- Event *e =
- new EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace>(this,
- true);
- e->schedule(p->functionTraceStart);
+ new EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace>(this,
+ p->functionTraceStart,
+ true);
}
}
#if FULL_SYSTEM
if (params->profile)
profileEvent = new ProfileEvent(this, params->profile);
#endif
+ tracer = params->tracer;
}
BaseCPU::Params::Params()
profile = false;
#endif
checker = NULL;
+ tracer = NULL;
}
void
#endif
if (params->progress_interval) {
- new CPUProgressEvent(&mainEventQueue, params->progress_interval,
+ new CPUProgressEvent(&mainEventQueue,
+ ticks(params->progress_interval),
this);
}
}
Tick
BaseCPU::nextCycle()
{
- Tick next_tick = curTick + clock - 1;
+ Tick next_tick = curTick - phase + clock - 1;
next_tick -= (next_tick % clock);
+ next_tick += phase;
return next_tick;
}
BaseCPU::nextCycle(Tick begin_tick)
{
Tick next_tick = begin_tick;
+ if (next_tick % clock != 0)
+ next_tick = next_tick - (next_tick % clock) + clock;
+ next_tick += phase;
- while (next_tick < curTick)
- next_tick += clock;
-
- next_tick -= (next_tick % clock);
assert(next_tick >= curTick);
return next_tick;
}
}
+int
+BaseCPU::findContext(ThreadContext *tc)
+{
+ for (int i = 0; i < threadContexts.size(); ++i) {
+ if (tc == threadContexts[i])
+ return i;
+ }
+ return 0;
+}
+
void
BaseCPU::switchOut()
{
}
void
-BaseCPU::takeOverFrom(BaseCPU *oldCPU)
+BaseCPU::takeOverFrom(BaseCPU *oldCPU, Port *ic, Port *dc)
{
assert(threadContexts.size() == oldCPU->threadContexts.size());
}
#if FULL_SYSTEM
- for (int i = 0; i < TheISA::NumInterruptLevels; ++i)
- interrupts[i] = oldCPU->interrupts[i];
- intstatus = oldCPU->intstatus;
- checkInterrupts = oldCPU->checkInterrupts;
+ interrupts = oldCPU->interrupts;
for (int i = 0; i < threadContexts.size(); ++i)
threadContexts[i]->profileClear();
- // The Sampler must take care of this!
-// if (profileEvent)
-// profileEvent->schedule(curTick);
+ if (profileEvent)
+ profileEvent->schedule(curTick);
#endif
+
+ // Connect new CPU to old CPU's memory only if new CPU isn't
+ // connected to anything. Also connect old CPU's memory to new
+ // CPU.
+ Port *peer;
+ if (ic->getPeer() == NULL) {
+ peer = oldCPU->getPort("icache_port")->getPeer();
+ ic->setPeer(peer);
+ } else {
+ peer = ic->getPeer();
+ }
+ peer->setPeer(ic);
+
+ if (dc->getPeer() == NULL) {
+ peer = oldCPU->getPort("dcache_port")->getPeer();
+ dc->setPeer(peer);
+ } else {
+ peer = dc->getPeer();
+ }
+ peer->setPeer(dc);
}
void
BaseCPU::post_interrupt(int int_num, int index)
{
- DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
-
- if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
- panic("int_num out of bounds\n");
-
- if (index < 0 || index >= sizeof(uint64_t) * 8)
- panic("int_num out of bounds\n");
-
- checkInterrupts = true;
- interrupts[int_num] |= 1 << index;
- intstatus |= (ULL(1) << int_num);
+ interrupts.post(int_num, index);
}
void
BaseCPU::clear_interrupt(int int_num, int index)
{
- DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
-
- if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
- panic("int_num out of bounds\n");
-
- if (index < 0 || index >= sizeof(uint64_t) * 8)
- panic("int_num out of bounds\n");
-
- interrupts[int_num] &= ~(1 << index);
- if (interrupts[int_num] == 0)
- intstatus &= ~(ULL(1) << int_num);
+ interrupts.clear(int_num, index);
}
void
BaseCPU::clear_interrupts()
{
- DPRINTF(Interrupt, "Interrupts all cleared\n");
-
- memset(interrupts, 0, sizeof(interrupts));
- intstatus = 0;
+ interrupts.clear_all();
}
+uint64_t
+BaseCPU::get_interrupts(int int_num)
+{
+ return interrupts.get_vec(int_num);
+}
void
BaseCPU::serialize(std::ostream &os)
{
- SERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
- SERIALIZE_SCALAR(intstatus);
+ SERIALIZE_SCALAR(instCnt);
+ interrupts.serialize(os);
}
void
BaseCPU::unserialize(Checkpoint *cp, const std::string §ion)
{
- UNSERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
- UNSERIALIZE_SCALAR(intstatus);
+ UNSERIALIZE_SCALAR(instCnt);
+ interrupts.unserialize(cp, section);
}
#endif // FULL_SYSTEM
functionEntryTick = curTick;
}
}
-
-
-DEFINE_SIM_OBJECT_CLASS_NAME("BaseCPU", BaseCPU)