inorder/alpha-isa: create eaComp object visible to StaticInst through ISA
[gem5.git] / src / cpu / simple / atomic.cc
index 17f93c8829742528d848a17dfdf12734f9c11f5a..045b80c80fd659a92f7a7a3884e11f696df8b7f1 100644 (file)
@@ -153,7 +153,7 @@ AtomicSimpleCPU::DcachePort::setPeer(Port *port)
 }
 
 AtomicSimpleCPU::AtomicSimpleCPU(AtomicSimpleCPUParams *p)
-    : BaseSimpleCPU(p), tickEvent(this), width(p->width),
+    : BaseSimpleCPU(p), tickEvent(this), width(p->width), locked(false),
       simulate_data_stalls(p->simulate_data_stalls),
       simulate_inst_stalls(p->simulate_inst_stalls),
       icachePort(name() + "-iport", this), dcachePort(name() + "-iport", this),
@@ -176,6 +176,7 @@ AtomicSimpleCPU::serialize(ostream &os)
 {
     SimObject::State so_state = SimObject::getState();
     SERIALIZE_ENUM(so_state);
+    SERIALIZE_SCALAR(locked);
     BaseSimpleCPU::serialize(os);
     nameOut(os, csprintf("%s.tickEvent", name()));
     tickEvent.serialize(os);
@@ -186,6 +187,7 @@ AtomicSimpleCPU::unserialize(Checkpoint *cp, const string &section)
 {
     SimObject::State so_state;
     UNSERIALIZE_ENUM(so_state);
+    UNSERIALIZE_SCALAR(locked);
     BaseSimpleCPU::unserialize(cp, section);
     tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
 }
@@ -271,6 +273,9 @@ AtomicSimpleCPU::suspendContext(int thread_num)
     assert(thread_num == 0);
     assert(thread);
 
+    if (_status == Idle)
+        return;
+
     assert(_status == Running);
 
     // tick event may not be scheduled if this gets called from inside
@@ -314,12 +319,12 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags)
         req->setVirt(0, addr, dataSize, flags, thread->readPC());
 
         // translate to physical address
-        Fault fault = thread->dtb->translateAtomic(req, tc, false);
+        Fault fault = thread->dtb->translateAtomic(req, tc, BaseTLB::Read);
 
         // Now do the access.
         if (fault == NoFault) {
             Packet pkt = Packet(req,
-                    req->isLocked() ? MemCmd::LoadLockedReq : MemCmd::ReadReq,
+                    req->isLLSC() ? MemCmd::LoadLockedReq : MemCmd::ReadReq,
                     Packet::Broadcast);
             pkt.dataStatic(dataPtr);
 
@@ -335,7 +340,7 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags)
 
             assert(!pkt.isError());
 
-            if (req->isLocked()) {
+            if (req->isLLSC()) {
                 TheISA::handleLockedRead(thread, req);
             }
         }
@@ -354,6 +359,10 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags)
             if (traceData) {
                 traceData->setData(data);
             }
+            if (req->isLocked() && fault == NoFault) {
+                assert(!locked);
+                locked = true;
+            }
             return fault;
         }
 
@@ -452,14 +461,14 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
         req->setVirt(0, addr, dataSize, flags, thread->readPC());
 
         // translate to physical address
-        Fault fault = thread->dtb->translateAtomic(req, tc, true);
+        Fault fault = thread->dtb->translateAtomic(req, tc, BaseTLB::Write);
 
         // Now do the access.
         if (fault == NoFault) {
             MemCmd cmd = MemCmd::WriteReq; // default
             bool do_access = true;  // flag to suppress cache access
 
-            if (req->isLocked()) {
+            if (req->isLLSC()) {
                 cmd = MemCmd::StoreCondReq;
                 do_access = TheISA::handleLockedWrite(thread, req);
             } else if (req->isSwap()) {
@@ -515,6 +524,10 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
             if (traceData) {
                 traceData->setData(gtoh(data));
             }
+            if (req->isLocked() && fault == NoFault) {
+                assert(locked);
+                locked = false;
+            }
             return fault;
         }
 
@@ -596,7 +609,7 @@ AtomicSimpleCPU::tick()
 
     Tick latency = 0;
 
-    for (int i = 0; i < width; ++i) {
+    for (int i = 0; i < width || locked; ++i) {
         numCycles++;
 
         if (!curStaticInst || !curStaticInst->isDelayedCommit())
@@ -609,7 +622,8 @@ AtomicSimpleCPU::tick()
         bool fromRom = isRomMicroPC(thread->readMicroPC());
         if (!fromRom && !curMacroStaticInst) {
             setupFetchRequest(&ifetch_req);
-            fault = thread->itb->translateAtomic(&ifetch_req, tc);
+            fault = thread->itb->translateAtomic(&ifetch_req, tc,
+                                                 BaseTLB::Execute);
         }
 
         if (fault == NoFault) {