Merge zizzer:/bk/newmem
[gem5.git] / src / cpu / simple / timing.cc
index 1e5a628c7f45ee26d399a3cd14acc2c55095c1b9..d5bdcfa9b1d3677babdf2d533a9ed8797668f987 100644 (file)
@@ -52,11 +52,11 @@ TimingSimpleCPU::init()
 
     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
 }
@@ -88,6 +88,8 @@ TimingSimpleCPU::TimingSimpleCPU(Params *p)
 {
     _status = Idle;
     ifetch_pkt = dcache_pkt = NULL;
+    quiesceEvent = NULL;
+    state = SimObject::Timing;
 }
 
 
@@ -98,25 +100,54 @@ TimingSimpleCPU::~TimingSimpleCPU()
 void
 TimingSimpleCPU::serialize(ostream &os)
 {
-    BaseSimpleCPU::serialize(os);
     SERIALIZE_ENUM(_status);
+    BaseSimpleCPU::serialize(os);
 }
 
 void
 TimingSimpleCPU::unserialize(Checkpoint *cp, const string &section)
 {
-    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;
 }
 
 
@@ -125,11 +156,11 @@ TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
 {
     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;
         }
@@ -141,7 +172,7 @@ void
 TimingSimpleCPU::activateContext(int thread_num, int delay)
 {
     assert(thread_num == 0);
-    assert(cpuXC);
+    assert(thread);
 
     assert(_status == Idle);
 
@@ -158,7 +189,7 @@ void
 TimingSimpleCPU::suspendContext(int thread_num)
 {
     assert(thread_num == 0);
-    assert(cpuXC);
+    assert(thread);
 
     assert(_status == Running);
 
@@ -176,15 +207,15 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
 {
     // 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) {
@@ -257,10 +288,11 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
 {
     // 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 =
@@ -340,6 +372,7 @@ TimingSimpleCPU::fetch()
 
     // 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);
@@ -383,11 +416,17 @@ TimingSimpleCPU::completeIfetch(Packet *pkt)
     // 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
@@ -440,6 +479,15 @@ TimingSimpleCPU::completeDataAccess(Packet *pkt)
     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;
@@ -450,6 +498,13 @@ TimingSimpleCPU::completeDataAccess(Packet *pkt)
 }
 
 
+void
+TimingSimpleCPU::completeQuiesce()
+{
+    DPRINTF(Config, "Done quiescing\n");
+    changeState(SimObject::QuiescedTiming);
+    quiesceEvent->process();
+}
 
 bool
 TimingSimpleCPU::DcachePort::recvTiming(Packet *pkt)