{
Counter temp = cpu->totalOps();
#ifndef NDEBUG
- double ipc = double(temp - lastNumInst) / (_interval / cpu->ticks(1));
+ double ipc = double(temp - lastNumInst) / (_interval / cpu->clockPeriod());
DPRINTFN("%s progress event, total committed:%i, progress insts committed: "
"%lli, IPC: %0.8d\n", cpu->name(), temp, temp - lastNumInst,
}
BaseCPU::BaseCPU(Params *p, bool is_checker)
- : MemObject(p), clock(p->clock), instCnt(0), _cpuId(p->cpu_id),
+ : MemObject(p), instCnt(0), _cpuId(p->cpu_id),
_instMasterId(p->system->getMasterId(name() + ".inst")),
_dataMasterId(p->system->getMasterId(name() + ".data")),
- interrupts(p->interrupts),
- numThreads(p->numThreads), system(p->system),
- phase(p->phase)
+ _taskId(ContextSwitchTaskId::Unknown), _pid(Request::invldPid),
+ interrupts(p->interrupts), profileEvent(NULL),
+ numThreads(p->numThreads), system(p->system)
{
-// currentTick = curTick();
-
// if Python did not provide a valid ID, do it here
if (_cpuId == -1 ) {
_cpuId = cpuList.size();
}
if (FullSystem) {
- profileEvent = NULL;
if (params()->profile)
profileEvent = new ProfileEvent(this, params()->profile);
}
tracer = params()->tracer;
+
+ if (params()->isa.size() != numThreads) {
+ fatal("Number of ISAs (%i) assigned to the CPU does not equal number "
+ "of threads (%i).\n", params()->isa.size(), numThreads);
+ }
}
void
BaseCPU::~BaseCPU()
{
+ delete profileEvent;
+ delete[] comLoadEventQueue;
+ delete[] comInstEventQueue;
}
void
}
if (params()->progress_interval) {
- Tick num_ticks = ticks(params()->progress_interval);
-
- new CPUProgressEvent(this, num_ticks);
+ new CPUProgressEvent(this, params()->progress_interval);
}
}
threadContexts[0]->regStats(name());
}
-MasterPort &
-BaseCPU::getMasterPort(const string &if_name, int idx)
+BaseMasterPort &
+BaseCPU::getMasterPort(const string &if_name, PortID idx)
{
// Get the right port based on name. This applies to all the
// subclasses of the base CPU and relies on their implementation
return MemObject::getMasterPort(if_name, idx);
}
-Tick
-BaseCPU::nextCycle()
-{
- Tick next_tick = curTick() - phase + clock - 1;
- next_tick -= (next_tick % clock);
- next_tick += phase;
- return next_tick;
-}
-
-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;
-
- assert(next_tick >= curTick());
- return next_tick;
-}
-
void
BaseCPU::registerThreadContexts()
{
BaseCPU::takeOverFrom(BaseCPU *oldCPU)
{
assert(threadContexts.size() == oldCPU->threadContexts.size());
-
- _cpuId = oldCPU->cpuId();
+ assert(_cpuId == oldCPU->cpuId());
+ _pid = oldCPU->getPid();
+ _taskId = oldCPU->taskId();
ThreadID size = threadContexts.size();
for (ThreadID i = 0; i < size; ++i) {
ThreadContext::compare(oldTC, newTC);
*/
- MasterPort *old_itb_port = oldTC->getITBPtr()->getMasterPort();
- MasterPort *old_dtb_port = oldTC->getDTBPtr()->getMasterPort();
- MasterPort *new_itb_port = newTC->getITBPtr()->getMasterPort();
- MasterPort *new_dtb_port = newTC->getDTBPtr()->getMasterPort();
+ BaseMasterPort *old_itb_port = oldTC->getITBPtr()->getMasterPort();
+ BaseMasterPort *old_dtb_port = oldTC->getDTBPtr()->getMasterPort();
+ BaseMasterPort *new_itb_port = newTC->getITBPtr()->getMasterPort();
+ BaseMasterPort *new_dtb_port = newTC->getDTBPtr()->getMasterPort();
// Move over any table walker ports if they exist
- if (new_itb_port && !new_itb_port->isConnected()) {
+ if (new_itb_port) {
+ assert(!new_itb_port->isConnected());
assert(old_itb_port);
- SlavePort &slavePort = old_itb_port->getSlavePort();
+ assert(old_itb_port->isConnected());
+ BaseSlavePort &slavePort = old_itb_port->getSlavePort();
+ old_itb_port->unbind();
new_itb_port->bind(slavePort);
}
- if (new_dtb_port && !new_dtb_port->isConnected()) {
+ if (new_dtb_port) {
+ assert(!new_dtb_port->isConnected());
assert(old_dtb_port);
- SlavePort &slavePort = old_dtb_port->getSlavePort();
+ assert(old_dtb_port->isConnected());
+ BaseSlavePort &slavePort = old_dtb_port->getSlavePort();
+ old_dtb_port->unbind();
new_dtb_port->bind(slavePort);
}
CheckerCPU *oldChecker = oldTC->getCheckerCpuPtr();
CheckerCPU *newChecker = newTC->getCheckerCpuPtr();
if (oldChecker && newChecker) {
- MasterPort *old_checker_itb_port =
+ BaseMasterPort *old_checker_itb_port =
oldChecker->getITBPtr()->getMasterPort();
- MasterPort *old_checker_dtb_port =
+ BaseMasterPort *old_checker_dtb_port =
oldChecker->getDTBPtr()->getMasterPort();
- MasterPort *new_checker_itb_port =
+ BaseMasterPort *new_checker_itb_port =
newChecker->getITBPtr()->getMasterPort();
- MasterPort *new_checker_dtb_port =
+ BaseMasterPort *new_checker_dtb_port =
newChecker->getDTBPtr()->getMasterPort();
// Move over any table walker ports if they exist for checker
- if (new_checker_itb_port && !new_checker_itb_port->isConnected()) {
+ if (new_checker_itb_port) {
+ assert(!new_checker_itb_port->isConnected());
assert(old_checker_itb_port);
- SlavePort &slavePort = old_checker_itb_port->getSlavePort();;
+ assert(old_checker_itb_port->isConnected());
+ BaseSlavePort &slavePort =
+ old_checker_itb_port->getSlavePort();
+ old_checker_itb_port->unbind();
new_checker_itb_port->bind(slavePort);
}
- if (new_checker_dtb_port && !new_checker_dtb_port->isConnected()) {
+ if (new_checker_dtb_port) {
+ assert(!new_checker_dtb_port->isConnected());
assert(old_checker_dtb_port);
- SlavePort &slavePort = old_checker_dtb_port->getSlavePort();;
+ assert(old_checker_dtb_port->isConnected());
+ BaseSlavePort &slavePort =
+ old_checker_dtb_port->getSlavePort();
+ old_checker_dtb_port->unbind();
new_checker_dtb_port->bind(slavePort);
}
}
interrupts = oldCPU->interrupts;
interrupts->setCPU(this);
+ oldCPU->interrupts = NULL;
if (FullSystem) {
for (ThreadID i = 0; i < size; ++i)
schedule(profileEvent, curTick());
}
- // 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.
- if (!getInstPort().isConnected()) {
- getInstPort().bind(oldCPU->getInstPort().getSlavePort());
- }
-
- if (!getDataPort().isConnected()) {
- getDataPort().bind(oldCPU->getDataPort().getSlavePort());
- }
+ // All CPUs have an instruction and a data port, and the new CPU's
+ // ports are dangling while the old CPU has its ports connected
+ // already. Unbind the old CPU and then bind the ports of the one
+ // we are switching to.
+ assert(!getInstPort().isConnected());
+ assert(oldCPU->getInstPort().isConnected());
+ BaseSlavePort &inst_peer_port = oldCPU->getInstPort().getSlavePort();
+ oldCPU->getInstPort().unbind();
+ getInstPort().bind(inst_peer_port);
+
+ assert(!getDataPort().isConnected());
+ assert(oldCPU->getDataPort().isConnected());
+ BaseSlavePort &data_peer_port = oldCPU->getDataPort().getSlavePort();
+ oldCPU->getDataPort().unbind();
+ getDataPort().bind(data_peer_port);
}
BaseCPU::serialize(std::ostream &os)
{
SERIALIZE_SCALAR(instCnt);
+
+ /* Unlike _pid, _taskId is not serialized, as they are dynamically
+ * assigned unique ids that are only meaningful for the duration of
+ * a specific run. We will need to serialize the entire taskMap in
+ * system. */
+ SERIALIZE_SCALAR(_pid);
+
interrupts->serialize(os);
}
BaseCPU::unserialize(Checkpoint *cp, const std::string §ion)
{
UNSERIALIZE_SCALAR(instCnt);
+ UNSERIALIZE_SCALAR(_pid);
interrupts->unserialize(cp, section);
}