Merge ktlim@zizzer:/bk/newmem
[gem5.git] / src / cpu / simple / atomic.cc
index ec629304bd5fdf065e7885be9e896fe95af68277..b7202cbbb7391e38f77e6f62c249d688b8874a7d 100644 (file)
@@ -24,6 +24,8 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Steve Reinhardt
  */
 
 #include "arch/utility.hh"
@@ -68,11 +70,11 @@ AtomicSimpleCPU::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
 }
@@ -106,11 +108,10 @@ AtomicSimpleCPU::CpuPort::recvStatusChange(Status status)
     panic("AtomicSimpleCPU doesn't expect recvStatusChange callback!");
 }
 
-Packet *
+void
 AtomicSimpleCPU::CpuPort::recvRetry()
 {
     panic("AtomicSimpleCPU doesn't expect recvRetry callback!");
-    return NULL;
 }
 
 
@@ -121,26 +122,20 @@ AtomicSimpleCPU::AtomicSimpleCPU(Params *p)
 {
     _status = Idle;
 
-    ifetch_req = new Request(true);
-    ifetch_req->setAsid(0);
-    // @todo fix me and get the real cpu iD!!!
-    ifetch_req->setCpuNum(0);
-    ifetch_req->setSize(sizeof(MachInst));
+    // @todo fix me and get the real cpu id & thread number!!!
+    ifetch_req = new Request();
+    ifetch_req->setThreadContext(0,0); //Need CPU/Thread IDS HERE
     ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast);
     ifetch_pkt->dataStatic(&inst);
 
-    data_read_req = new Request(true);
-    // @todo fix me and get the real cpu iD!!!
-    data_read_req->setCpuNum(0);
-    data_read_req->setAsid(0);
+    data_read_req = new Request();
+    data_read_req->setThreadContext(0,0); //Need CPU/Thread IDS HERE
     data_read_pkt = new Packet(data_read_req, Packet::ReadReq,
                                Packet::Broadcast);
     data_read_pkt->dataStatic(&dataReg);
 
-    data_write_req = new Request(true);
-    // @todo fix me and get the real cpu iD!!!
-    data_write_req->setCpuNum(0);
-    data_write_req->setAsid(0);
+    data_write_req = new Request();
+    data_write_req->setThreadContext(0,0); //Need CPU/Thread IDS HERE
     data_write_pkt = new Packet(data_write_req, Packet::WriteReq,
                                 Packet::Broadcast);
 }
@@ -153,8 +148,8 @@ AtomicSimpleCPU::~AtomicSimpleCPU()
 void
 AtomicSimpleCPU::serialize(ostream &os)
 {
-    BaseSimpleCPU::serialize(os);
     SERIALIZE_ENUM(_status);
+    BaseSimpleCPU::serialize(os);
     nameOut(os, csprintf("%s.tickEvent", name()));
     tickEvent.serialize(os);
 }
@@ -162,21 +157,18 @@ AtomicSimpleCPU::serialize(ostream &os)
 void
 AtomicSimpleCPU::unserialize(Checkpoint *cp, const string &section)
 {
-    BaseSimpleCPU::unserialize(cp, section);
     UNSERIALIZE_ENUM(_status);
+    BaseSimpleCPU::unserialize(cp, section);
     tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
 }
 
 void
-AtomicSimpleCPU::switchOut(Sampler *s)
+AtomicSimpleCPU::switchOut()
 {
-    sampler = s;
-    if (status() == Running) {
-        _status = SwitchedOut;
+    assert(status() == Running || status() == Idle);
+    _status = SwitchedOut;
 
-        tickEvent.squash();
-    }
-    sampler->signalSwitched();
+    tickEvent.squash();
 }
 
 
@@ -187,11 +179,11 @@ AtomicSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
 
     assert(!tickEvent.scheduled());
 
-    // 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;
             tickEvent.schedule(curTick);
             break;
@@ -204,7 +196,7 @@ void
 AtomicSimpleCPU::activateContext(int thread_num, int delay)
 {
     assert(thread_num == 0);
-    assert(cpuXC);
+    assert(thread);
 
     assert(_status == Idle);
     assert(!tickEvent.scheduled());
@@ -219,7 +211,7 @@ void
 AtomicSimpleCPU::suspendContext(int thread_num)
 {
     assert(thread_num == 0);
-    assert(cpuXC);
+    assert(thread);
 
     assert(_status == Running);
 
@@ -237,24 +229,20 @@ template <class T>
 Fault
 AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags)
 {
-    data_read_req->setVaddr(addr);
-    data_read_req->setSize(sizeof(T));
-    data_read_req->setFlags(flags);
-    data_read_req->setTime(curTick);
+    data_read_req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
 
     if (traceData) {
         traceData->setAddr(addr);
     }
 
     // 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) {
-        data_read_pkt->reset();
         data_read_pkt->reinitFromRequest();
 
-        dcache_complete = dcachePort.sendAtomic(data_read_pkt);
+        dcache_latency = dcachePort.sendAtomic(data_read_pkt);
         dcache_access = true;
 
         assert(data_read_pkt->result == Packet::Success);
@@ -316,26 +304,22 @@ template <class T>
 Fault
 AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
 {
-    data_write_req->setVaddr(addr);
-    data_write_req->setTime(curTick);
-    data_write_req->setSize(sizeof(T));
-    data_write_req->setFlags(flags);
+    data_write_req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
 
     if (traceData) {
         traceData->setAddr(addr);
     }
 
     // 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) {
-        data_write_pkt->reset();
         data = htog(data);
-        data_write_pkt->dataStatic(&data);
         data_write_pkt->reinitFromRequest();
+        data_write_pkt->dataStatic(&data);
 
-        dcache_complete = dcachePort.sendAtomic(data_write_pkt);
+        dcache_latency = dcachePort.sendAtomic(data_write_pkt);
         dcache_access = true;
 
         assert(data_write_pkt->result == Packet::Success);
@@ -411,12 +395,12 @@ AtomicSimpleCPU::tick()
 
         checkForInterrupts();
 
-        ifetch_req->resetMin();
-        ifetch_pkt->reset();
-        Fault fault = setupFetchPacket(ifetch_pkt);
+        Fault fault = setupFetchRequest(ifetch_req);
 
         if (fault == NoFault) {
-            Tick icache_complete = icachePort.sendAtomic(ifetch_pkt);
+            ifetch_pkt->reinitFromRequest();
+
+            Tick icache_latency = icachePort.sendAtomic(ifetch_pkt);
             // ifetch_req is initialized to read the instruction directly
             // into the CPU object's inst field.
 
@@ -425,20 +409,15 @@ AtomicSimpleCPU::tick()
             fault = curStaticInst->execute(this, traceData);
             postExecute();
 
-            if (traceData) {
-                traceData->finalize();
-            }
-
             if (simulate_stalls) {
-                // This calculation assumes that the icache and dcache
-                // access latencies are always a multiple of the CPU's
-                // cycle time.  If not, the next tick event may get
-                // scheduled at a non-integer multiple of the CPU
-                // cycle time.
-                Tick icache_stall = icache_complete - curTick - cycles(1);
+                Tick icache_stall = icache_latency - cycles(1);
                 Tick dcache_stall =
-                    dcache_access ? dcache_complete - curTick - cycles(1) : 0;
-                latency += icache_stall + dcache_stall;
+                    dcache_access ? dcache_latency - cycles(1) : 0;
+                Tick stall_cycles = (icache_stall + dcache_stall) / cycles(1);
+                if (cycles(stall_cycles) < (icache_stall + dcache_stall))
+                    latency += cycles(stall_cycles+1);
+                else
+                    latency += cycles(stall_cycles);
             }
 
         }