merge: style.py fix
[gem5.git] / src / cpu / ozone / lw_lsq.hh
index e0c1901345dd08407f339331463bfa2f17c754d6..ba40e9ce1c459e59d012d148ab3f5cb100b10074 100644 (file)
@@ -37,7 +37,7 @@
 #include <algorithm>
 
 #include "arch/faults.hh"
-#include "arch/isa_traits.hh"
+#include "arch/types.hh"
 #include "config/full_system.hh"
 #include "base/hashmap.hh"
 #include "cpu/inst_seq.hh"
@@ -84,6 +84,8 @@ class OzoneLWLSQ {
     /** Returns the name of the LSQ unit. */
     std::string name() const;
 
+    void regStats();
+
     /** Sets the CPU pointer. */
     void setCPU(OzoneCPU *cpu_ptr);
 
@@ -91,8 +93,7 @@ class OzoneLWLSQ {
     void setBE(BackEnd *be_ptr)
     { be = be_ptr; }
 
-    /** Sets the page table pointer. */
-//    void setPageTable(PageTable *pt_ptr);
+    Port *getDcachePort() { return &dcachePort; }
 
     /** Ticks the LSQ unit, which in this case only resets the number of
      * used cache ports.
@@ -180,7 +181,7 @@ class OzoneLWLSQ {
     int numLoads() { return loads; }
 
     /** Returns the number of stores in the SQ. */
-    int numStores() { return stores; }
+    int numStores() { return stores + storesInFlight; }
 
     /** Returns if either the LQ or SQ is full. */
     bool isFull() { return lqFull() || sqFull(); }
@@ -189,7 +190,7 @@ class OzoneLWLSQ {
     bool lqFull() { return loads >= (LQEntries - 1); }
 
     /** Returns if the SQ is full. */
-    bool sqFull() { return stores >= (SQEntries - 1); }
+    bool sqFull() { return (stores + storesInFlight) >= (SQEntries - 1); }
 
     /** Debugging function to dump instructions in the LSQ. */
     void dumpInsts();
@@ -221,10 +222,12 @@ class OzoneLWLSQ {
     void writeback(DynInstPtr &inst, PacketPtr pkt);
 
     /** Handles completing the send of a store to memory. */
-    void storePostSend(Packet *pkt, DynInstPtr &inst);
+    void storePostSend(PacketPtr pkt, DynInstPtr &inst);
 
     /** Completes the store at the specified index. */
-    void completeStore(int store_idx);
+    void completeStore(DynInstPtr &inst);
+
+    void removeStore(int store_idx);
 
     /** Handles doing the retry. */
     void recvRetry();
@@ -236,18 +239,14 @@ class OzoneLWLSQ {
     /** Pointer to the back-end stage. */
     BackEnd *be;
 
-    MemObject *mem;
-
     class DcachePort : public Port
     {
       protected:
-        OzoneCPU *cpu;
-
         OzoneLWLSQ *lsq;
 
       public:
-        DcachePort(OzoneCPU *_cpu, OzoneLWLSQ *_lsq)
-            : Port(_lsq->name() + "-dport"), cpu(_cpu), lsq(_lsq)
+        DcachePort(OzoneLWLSQ *_lsq)
+            : lsq(_lsq)
         { }
 
       protected:
@@ -258,19 +257,16 @@ class OzoneLWLSQ {
         virtual void recvStatusChange(Status status);
 
         virtual void getDeviceAddressRanges(AddrRangeList &resp,
-                                            AddrRangeList &snoop)
-        { resp.clear(); snoop.clear(); }
+                                            bool &snoop)
+        { resp.clear(); snoop = true; }
 
         virtual bool recvTiming(PacketPtr pkt);
 
         virtual void recvRetry();
     };
 
-    /** Pointer to the D-cache. */
-    DcachePort *dcachePort;
-
-    /** Pointer to the page table. */
-//    PageTable *pTable;
+    /** D-cache port. */
+    DcachePort dcachePort;
 
   public:
     struct SQEntry {
@@ -400,6 +396,10 @@ class OzoneLWLSQ {
 
     int storesToWB;
 
+  public:
+    int storesInFlight;
+
+  private:
     /// @todo Consider moving to a more advanced model with write vs read ports
     /** The number of cache ports available each cycle. */
     int cachePorts;
@@ -409,6 +409,9 @@ class OzoneLWLSQ {
 
     //list<InstSeqNum> mshrSeqNums;
 
+    /** Tota number of memory ordering violations. */
+    Stats::Scalar<> lsqMemOrderViolation;
+
      //Stats::Scalar<> dcacheStallCycles;
     Counter lastDcacheStall;
 
@@ -502,7 +505,7 @@ OzoneLWLSQ<Impl>::read(RequestPtr req, T &data, int load_idx)
     // at the head of the LSQ and are ready to commit (at the head of the ROB
     // too).
     // @todo: Fix uncached accesses.
-    if (req->getFlags() & UNCACHEABLE &&
+    if (req->isUncacheable() &&
         (inst != loadQueue.back() || !inst->isAtCommit())) {
         DPRINTF(OzoneLSQ, "[sn:%lli] Uncached load and not head of "
                 "commit/LSQ!\n",
@@ -531,7 +534,7 @@ OzoneLWLSQ<Impl>::read(RequestPtr req, T &data, int load_idx)
 
         store_size = (*sq_it).size;
 
-        if (store_size == 0) {
+        if (store_size == 0 || (*sq_it).committed) {
             sq_it++;
             continue;
         }
@@ -629,7 +632,11 @@ OzoneLWLSQ<Impl>::read(RequestPtr req, T &data, int load_idx)
     DPRINTF(OzoneLSQ, "Doing timing access for inst PC %#x\n",
             inst->readPC());
 
-    PacketPtr data_pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast);
+    PacketPtr data_pkt =
+        new Packet(req,
+                   (req->isLocked() ?
+                    MemCmd::LoadLockedReq : Packet::ReadReq),
+                   Packet::Broadcast);
     data_pkt->dataStatic(inst->memData);
 
     LSQSenderState *state = new LSQSenderState;
@@ -639,7 +646,7 @@ OzoneLWLSQ<Impl>::read(RequestPtr req, T &data, int load_idx)
     data_pkt->senderState = state;
 
     // if we have a cache, do cache access too
-    if (!dcachePort->sendTiming(data_pkt)) {
+    if (!dcachePort.sendTiming(data_pkt)) {
         // There's an older load that's already going to squash.
         if (isLoadBlocked && blockedLoadSeqNum < inst->seqNum)
             return NoFault;
@@ -654,14 +661,8 @@ OzoneLWLSQ<Impl>::read(RequestPtr req, T &data, int load_idx)
         return NoFault;
     }
 
-    if (data_pkt->result != Packet::Success) {
-        DPRINTF(OzoneLSQ, "OzoneLSQ: D-cache miss!\n");
-        DPRINTF(Activity, "Activity: ld accessing mem miss [sn:%lli]\n",
-                inst->seqNum);
-    } else {
-        DPRINTF(OzoneLSQ, "OzoneLSQ: D-cache hit!\n");
-        DPRINTF(Activity, "Activity: ld accessing mem hit [sn:%lli]\n",
-                inst->seqNum);
+    if (req->isLocked()) {
+        cpu->lockFlag = true;
     }
 
     return NoFault;