Replace tests of LOCKED/UNCACHEABLE flags with isLocked()/isUncacheable().
[gem5.git] / src / cpu / ozone / lw_lsq_impl.hh
index 88e9c218f78be1b8de209e3bfe82a3cd4996afa9..9d17b027fc96cc0e7facf83d704ce5566e734d7e 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "config/use_checker.hh"
 
-#include "arch/isa_traits.hh"
+#include "arch/faults.hh"
 #include "base/str.hh"
 #include "cpu/ozone/lw_lsq.hh"
 #include "cpu/checker/cpu.hh"
@@ -121,7 +121,7 @@ OzoneLWLSQ<Impl>::completeDataAccess(PacketPtr pkt)
         }
 
         if (inst->isStore()) {
-            completeStore(state->idx);
+            completeStore(inst);
         }
     }
 
@@ -132,7 +132,7 @@ OzoneLWLSQ<Impl>::completeDataAccess(PacketPtr pkt)
 template <class Impl>
 OzoneLWLSQ<Impl>::OzoneLWLSQ()
     : switchedOut(false), dcachePort(this), loads(0), stores(0),
-      storesToWB(0), stalled(false), isStoreBlocked(false),
+      storesToWB(0), storesInFlight(0), stalled(false), isStoreBlocked(false),
       isLoadBlocked(false), loadBlockedHandled(false)
 {
 }
@@ -171,6 +171,15 @@ 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)
@@ -321,7 +330,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.
@@ -385,6 +394,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);
@@ -461,6 +473,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();
             }
@@ -553,8 +566,8 @@ OzoneLWLSQ<Impl>::writebackStores()
 
         if ((*sq_it).size == 0 && !(*sq_it).completed) {
             sq_it--;
-            completeStore(inst->sqIdx);
-
+            removeStore(inst->sqIdx);
+            completeStore(inst);
             continue;
         }
 
@@ -592,8 +605,8 @@ OzoneLWLSQ<Impl>::writebackStores()
                 inst->seqNum);
 
         // @todo: Remove this SC hack once the memory system handles it.
-        if (req->getFlags() & LOCKED) {
-            if (req->getFlags() & UNCACHEABLE) {
+        if (req->isLocked()) {
+            if (req->isUncacheable()) {
                 req->setScResult(2);
             } else {
                 if (cpu->lockFlag) {
@@ -626,6 +639,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);
@@ -648,7 +663,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->isLocked()) {
                     wb = new typename BackEnd::LdWritebackEvent(inst,
                                                             be);
                     store_event->wbEvent = wb;
@@ -675,7 +690,7 @@ OzoneLWLSQ<Impl>::writebackStores()
 //                DPRINTF(Activity, "Active st accessing mem hit [sn:%lli]\n",
 //                        inst->seqNum);
 
-                if (req->flags & LOCKED) {
+                if (req->isLocked()) {
                     // Stx_C does not generate a system port
                     // transaction in the 21264, but that might be
                     // hard to accomplish in this model.
@@ -687,6 +702,8 @@ OzoneLWLSQ<Impl>::writebackStores()
                 }
                 sq_it--;
             }
+            ++storesInFlight;
+//            removeStore(inst->sqIdx);
         } else {
             panic("Must HAVE DCACHE!!!!!\n");
         }
@@ -704,7 +721,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();
@@ -881,7 +898,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());
@@ -891,8 +908,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] "
@@ -910,6 +925,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();
@@ -935,9 +957,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>