CPU: Get rid of the now unnecessary getInst/setInst family of functions.
[gem5.git] / src / cpu / ozone / lw_lsq_impl.hh
index effb21728c0205d5fe2fb38472e722dcab69dcba..c714c5d382c32c6caeeeefa9acde40902a510a35 100644 (file)
  * Authors: Kevin Lim
  */
 
-#include "config/use_checker.hh"
-
-#include "arch/isa_traits.hh"
+#include "arch/faults.hh"
 #include "base/str.hh"
+#include "config/the_isa.hh"
+#include "config/use_checker.hh"
 #include "cpu/ozone/lw_lsq.hh"
 #include "cpu/checker/cpu.hh"
 
@@ -55,9 +55,9 @@ OzoneLWLSQ<Impl>::WritebackEvent::process()
 
 template<class Impl>
 const char *
-OzoneLWLSQ<Impl>::WritebackEvent::description()
+OzoneLWLSQ<Impl>::WritebackEvent::description() const
 {
-    return "Store writeback event";
+    return "Store writeback";
 }
 
 template <class Impl>
@@ -72,7 +72,7 @@ template <class Impl>
 void
 OzoneLWLSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt)
 {
-    panic("O3CPU doesn't expect recvFunctional callback!");
+    warn("O3CPU doesn't update things on a recvFunctional");
 }
 
 template <class Impl>
@@ -121,7 +121,7 @@ OzoneLWLSQ<Impl>::completeDataAccess(PacketPtr pkt)
         }
 
         if (inst->isStore()) {
-            completeStore(state->idx);
+            completeStore(inst);
         }
     }
 
@@ -131,8 +131,9 @@ OzoneLWLSQ<Impl>::completeDataAccess(PacketPtr pkt)
 
 template <class Impl>
 OzoneLWLSQ<Impl>::OzoneLWLSQ()
-    : loads(0), stores(0), storesToWB(0), stalled(false), isLoadBlocked(false),
-      loadBlockedHandled(false)
+    : switchedOut(false), dcachePort(this), loads(0), stores(0),
+      storesToWB(0), storesInFlight(0), stalled(false), isStoreBlocked(false),
+      isLoadBlocked(false), loadBlockedHandled(false)
 {
 }
 
@@ -168,20 +169,25 @@ OzoneLWLSQ<Impl>::name() const
     return "lsqunit";
 }
 
+template<class Impl>
+void
+OzoneLWLSQ<Impl>::regStats()
+{
+    lsqMemOrderViolation
+        .name(name() + ".memOrderViolation")
+        .desc("Number of memory ordering violations");
+}
+
 template<class Impl>
 void
 OzoneLWLSQ<Impl>::setCPU(OzoneCPU *cpu_ptr)
 {
     cpu = cpu_ptr;
-    dcachePort = new DcachePort(cpu, this);
-
-    Port *mem_dport = mem->getPort("");
-    dcachePort->setPeer(mem_dport);
-    mem_dport->setPeer(dcachePort);
+    dcachePort.setName(this->name() + "-dport");
 
 #if USE_CHECKER
     if (cpu->checker) {
-        cpu->checker->setDcachePort(dcachePort);
+        cpu->checker->setDcachePort(&dcachePort);
     }
 #endif
 }
@@ -322,7 +328,7 @@ unsigned
 OzoneLWLSQ<Impl>::numFreeEntries()
 {
     unsigned free_lq_entries = LQEntries - loads;
-    unsigned free_sq_entries = SQEntries - stores;
+    unsigned free_sq_entries = SQEntries - (stores + storesInFlight);
 
     // Both the LQ and SQ entries have an extra dummy entry to differentiate
     // empty/full conditions.  Subtract 1 from the free entries.
@@ -386,6 +392,9 @@ OzoneLWLSQ<Impl>::executeLoad(DynInstPtr &inst)
     // Actually probably want the oldest faulting load
     if (load_fault != NoFault) {
         DPRINTF(OzoneLSQ, "Load [sn:%lli] has a fault\n", inst->seqNum);
+        if (!(inst->req->isUncacheable() && !inst->isAtCommit())) {
+            inst->setExecuted();
+        }
         // Maybe just set it as can commit here, although that might cause
         // some other problems with sending traps to the ROB too quickly.
         be->instToCommit(inst);
@@ -462,6 +471,7 @@ OzoneLWLSQ<Impl>::executeStore(DynInstPtr &store_inst)
                 // A load incorrectly passed this store.  Squash and refetch.
                 // For now return a fault to show that it was unsuccessful.
                 memDepViolator = (*lq_it);
+                ++lsqMemOrderViolation;
 
                 return TheISA::genMachineCheckFault();
             }
@@ -554,8 +564,8 @@ OzoneLWLSQ<Impl>::writebackStores()
 
         if ((*sq_it).size == 0 && !(*sq_it).completed) {
             sq_it--;
-            completeStore(inst->sqIdx);
-
+            removeStore(inst->sqIdx);
+            completeStore(inst);
             continue;
         }
 
@@ -577,7 +587,10 @@ OzoneLWLSQ<Impl>::writebackStores()
         memcpy(inst->memData, (uint8_t *)&(*sq_it).data,
                req->getSize());
 
-        PacketPtr data_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
+        MemCmd command =
+            req->isSwap() ? MemCmd::SwapReq :
+            (req->isLLSC() ? MemCmd::WriteReq : MemCmd::StoreCondReq);
+        PacketPtr data_pkt = new Packet(req, command, Packet::Broadcast);
         data_pkt->dataStatic(inst->memData);
 
         LSQSenderState *state = new LSQSenderState;
@@ -593,14 +606,14 @@ OzoneLWLSQ<Impl>::writebackStores()
                 inst->seqNum);
 
         // @todo: Remove this SC hack once the memory system handles it.
-        if (req->getFlags() & LOCKED) {
-            if (req->getFlags() & UNCACHEABLE) {
-                req->setScResult(2);
+        if (req->isLLSC()) {
+            if (req->isUncacheable()) {
+                req->setExtraData(2);
             } else {
                 if (cpu->lockFlag) {
-                    req->setScResult(1);
+                    req->setExtraData(1);
                 } else {
-                    req->setScResult(0);
+                    req->setExtraData(0);
                     // Hack: Instantly complete this store.
                     completeDataAccess(data_pkt);
                     --sq_it;
@@ -612,7 +625,7 @@ OzoneLWLSQ<Impl>::writebackStores()
             state->noWB = true;
         }
 
-        if (!dcachePort->sendTiming(data_pkt)) {
+        if (!dcachePort.sendTiming(data_pkt)) {
             // Need to handle becoming blocked on a store.
             isStoreBlocked = true;
             assert(retryPkt == NULL);
@@ -627,6 +640,8 @@ OzoneLWLSQ<Impl>::writebackStores()
                 inst->sqIdx,inst->readPC(),
                 req->paddr, *(req->data),
                 inst->seqNum);
+        DPRINTF(OzoneLSQ, "StoresInFlight: %i\n",
+                storesInFlight + 1);
 
         if (dcacheInterface) {
             assert(!req->completionEvent);
@@ -649,7 +664,7 @@ OzoneLWLSQ<Impl>::writebackStores()
             if (result != MA_HIT && dcacheInterface->doEvents()) {
                 store_event->miss = true;
                 typename BackEnd::LdWritebackEvent *wb = NULL;
-                if (req->flags & LOCKED) {
+                if (req->isLLSC()) {
                     wb = new typename BackEnd::LdWritebackEvent(inst,
                                                             be);
                     store_event->wbEvent = wb;
@@ -676,7 +691,7 @@ OzoneLWLSQ<Impl>::writebackStores()
 //                DPRINTF(Activity, "Active st accessing mem hit [sn:%lli]\n",
 //                        inst->seqNum);
 
-                if (req->flags & LOCKED) {
+                if (req->isLLSC()) {
                     // Stx_C does not generate a system port
                     // transaction in the 21264, but that might be
                     // hard to accomplish in this model.
@@ -688,6 +703,8 @@ OzoneLWLSQ<Impl>::writebackStores()
                 }
                 sq_it--;
             }
+            ++storesInFlight;
+//            removeStore(inst->sqIdx);
         } else {
             panic("Must HAVE DCACHE!!!!!\n");
         }
@@ -705,7 +722,7 @@ void
 OzoneLWLSQ<Impl>::squash(const InstSeqNum &squashed_num)
 {
     DPRINTF(OzoneLSQ, "Squashing until [sn:%lli]!"
-            "(Loads:%i Stores:%i)\n",squashed_num,loads,stores);
+            "(Loads:%i Stores:%i)\n",squashed_num,loads,stores+storesInFlight);
 
 
     LQIt lq_it = loadQueue.begin();
@@ -816,7 +833,7 @@ OzoneLWLSQ<Impl>::dumpInsts()
 
 template <class Impl>
 void
-OzoneLWLSQ<Impl>::storePostSend(Packet *pkt, DynInstPtr &inst)
+OzoneLWLSQ<Impl>::storePostSend(PacketPtr pkt, DynInstPtr &inst)
 {
     if (isStalled() &&
         inst->seqNum == stallingStoreIsn) {
@@ -839,24 +856,6 @@ OzoneLWLSQ<Impl>::storePostSend(Packet *pkt, DynInstPtr &inst)
         }
 #endif
     }
-
-    if (pkt->result != Packet::Success) {
-        DPRINTF(OzoneLSQ,"D-Cache Write Miss!\n");
-
-        DPRINTF(Activity, "Active st accessing mem miss [sn:%lli]\n",
-                inst->seqNum);
-
-        //mshrSeqNums.push_back(storeQueue[storeWBIdx].inst->seqNum);
-
-        //DPRINTF(OzoneLWLSQ, "Added MSHR. count = %i\n",mshrSeqNums.size());
-
-        // @todo: Increment stat here.
-    } else {
-        DPRINTF(OzoneLSQ,"D-Cache: Write Hit!\n");
-
-        DPRINTF(Activity, "Active st accessing mem hit [sn:%lli]\n",
-                inst->seqNum);
-    }
 }
 
 template <class Impl>
@@ -882,7 +881,7 @@ OzoneLWLSQ<Impl>::writeback(DynInstPtr &inst, PacketPtr pkt)
 
 template <class Impl>
 void
-OzoneLWLSQ<Impl>::completeStore(int store_idx)
+OzoneLWLSQ<Impl>::removeStore(int store_idx)
 {
     SQHashIt sq_hash_it = SQItHash.find(store_idx);
     assert(sq_hash_it != SQItHash.end());
@@ -892,8 +891,6 @@ OzoneLWLSQ<Impl>::completeStore(int store_idx)
     (*sq_it).completed = true;
     DynInstPtr inst = (*sq_it).inst;
 
-    --storesToWB;
-
     if (isStalled() &&
         inst->seqNum == stallingStoreIsn) {
         DPRINTF(OzoneLSQ, "Unstalling, stalling store [sn:%lli] "
@@ -911,6 +908,13 @@ OzoneLWLSQ<Impl>::completeStore(int store_idx)
     SQItHash.erase(sq_hash_it);
     SQIndices.push(inst->sqIdx);
     storeQueue.erase(sq_it);
+}
+
+template <class Impl>
+void
+OzoneLWLSQ<Impl>::completeStore(DynInstPtr &inst)
+{
+    --storesToWB;
     --stores;
 
     inst->setCompleted();
@@ -936,9 +940,14 @@ OzoneLWLSQ<Impl>::switchOut()
     switchedOut = true;
 
     // Clear the queue to free up resources
+    assert(stores == 0);
+    assert(storeQueue.empty());
+    assert(loads == 0);
+    assert(loadQueue.empty());
+    assert(storesInFlight == 0);
     storeQueue.clear();
     loadQueue.clear();
-    loads = stores = storesToWB = 0;
+    loads = stores = storesToWB = storesInFlight = 0;
 }
 
 template <class Impl>