BaseCPU::init();
#if FULL_SYSTEM
- for (int i = 0; i < execContexts.size(); ++i) {
- ExecContext *xc = execContexts[i];
+ for (int i = 0; i < threadContexts.size(); ++i) {
+ ThreadContext *tc = threadContexts[i];
// initialize CPU, including PC
- TheISA::initCPU(xc, xc->readCpuId());
+ TheISA::initCPU(tc, tc->readCpuId());
}
#endif
}
{
_status = Idle;
ifetch_pkt = dcache_pkt = NULL;
+ quiesceEvent = NULL;
+ state = SimObject::Timing;
}
void
TimingSimpleCPU::serialize(ostream &os)
{
- BaseSimpleCPU::serialize(os);
SERIALIZE_ENUM(_status);
+ BaseSimpleCPU::serialize(os);
}
void
TimingSimpleCPU::unserialize(Checkpoint *cp, const string §ion)
{
- BaseSimpleCPU::unserialize(cp, section);
UNSERIALIZE_ENUM(_status);
+ BaseSimpleCPU::unserialize(cp, section);
+}
+
+bool
+TimingSimpleCPU::quiesce(Event *quiesce_event)
+{
+ // TimingSimpleCPU is ready to quiesce if it's not waiting for
+ // an access to complete.
+ if (status() == Idle || status() == Running || status() == SwitchedOut) {
+ DPRINTF(Config, "Ready to quiesce\n");
+ return false;
+ } else {
+ DPRINTF(Config, "Waiting to quiesce\n");
+ changeState(SimObject::Quiescing);
+ quiesceEvent = quiesce_event;
+ return true;
+ }
}
void
-TimingSimpleCPU::switchOut(Sampler *s)
+TimingSimpleCPU::resume()
{
- sampler = s;
- if (status() == Running) {
- _status = SwitchedOut;
+ if (_status != SwitchedOut && _status != Idle) {
+ Event *e =
+ new EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch>(this, true);
+ e->schedule(curTick);
}
- sampler->signalSwitched();
+}
+
+void
+TimingSimpleCPU::setMemoryMode(State new_mode)
+{
+ assert(new_mode == SimObject::Timing);
+}
+
+void
+TimingSimpleCPU::switchOut()
+{
+ assert(status() == Running || status() == Idle);
+ _status = SwitchedOut;
}
{
BaseCPU::takeOverFrom(oldCPU);
- // if any of this CPU's ExecContexts are active, mark the CPU as
+ // if any of this CPU's ThreadContexts are active, mark the CPU as
// running and schedule its tick event.
- for (int i = 0; i < execContexts.size(); ++i) {
- ExecContext *xc = execContexts[i];
- if (xc->status() == ExecContext::Active && _status != Running) {
+ for (int i = 0; i < threadContexts.size(); ++i) {
+ ThreadContext *tc = threadContexts[i];
+ if (tc->status() == ThreadContext::Active && _status != Running) {
_status = Running;
break;
}
TimingSimpleCPU::activateContext(int thread_num, int delay)
{
assert(thread_num == 0);
- assert(cpuXC);
+ assert(thread);
assert(_status == Idle);
TimingSimpleCPU::suspendContext(int thread_num)
{
assert(thread_num == 0);
- assert(cpuXC);
+ assert(thread);
assert(_status == Running);
{
// need to fill in CPU & thread IDs here
Request *data_read_req = new Request();
-
- data_read_req->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC());
+ data_read_req->setThreadContext(0,0); //Need CPU/Thread IDS HERE
+ data_read_req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
if (traceData) {
traceData->setAddr(data_read_req->getVaddr());
}
// translate to physical address
- Fault fault = cpuXC->translateDataReadReq(data_read_req);
+ Fault fault = thread->translateDataReadReq(data_read_req);
// Now do the access.
if (fault == NoFault) {
{
// need to fill in CPU & thread IDs here
Request *data_write_req = new Request();
- data_write_req->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC());
+ data_write_req->setThreadContext(0,0); //Need CPU/Thread IDS HERE
+ data_write_req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
// translate to physical address
- Fault fault = cpuXC->translateDataWriteReq(data_write_req);
+ Fault fault = thread->translateDataWriteReq(data_write_req);
// Now do the access.
if (fault == NoFault) {
Packet *data_write_pkt =
// need to fill in CPU & thread IDs here
Request *ifetch_req = new Request();
+ ifetch_req->setThreadContext(0,0); //Need CPU/Thread IDS HERE
Fault fault = setupFetchRequest(ifetch_req);
ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast);
// instruction
assert(pkt->result == Packet::Success);
assert(_status == IcacheWaitResponse);
+
_status = Running;
delete pkt->req;
delete pkt;
+ if (getState() == SimObject::Quiescing) {
+ completeQuiesce();
+ return;
+ }
+
preExecute();
if (curStaticInst->isMemRef() && !curStaticInst->isDataPrefetch()) {
// load or store: just send to dcache
assert(_status == DcacheWaitResponse);
_status = Running;
+ if (getState() == SimObject::Quiescing) {
+ completeQuiesce();
+
+ delete pkt->req;
+ delete pkt;
+
+ return;
+ }
+
Fault fault = curStaticInst->completeAcc(pkt, this, traceData);
delete pkt->req;
}
+void
+TimingSimpleCPU::completeQuiesce()
+{
+ DPRINTF(Config, "Done quiescing\n");
+ changeState(SimObject::QuiescedTiming);
+ quiesceEvent->process();
+}
bool
TimingSimpleCPU::DcachePort::recvTiming(Packet *pkt)