mem: write streaming support via WriteInvalidate promotion
[gem5.git] / src / mem / cache / mshr.hh
index fdb0485cb5d61f9e772ee1e6a7076e973c8ddbbb..65357b9e6debf2e668155ec31210db11240e9092 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2012-2013 ARM Limited
+ * All rights reserved.
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2002-2005 The Regents of The University of Michigan
  * All rights reserved.
  *
@@ -47,28 +59,59 @@ class MSHRQueue;
 /**
  * Miss Status and handling Register. This class keeps all the information
  * needed to handle a cache miss including a list of target requests.
+ * @sa  \ref gem5MemorySystem "gem5 Memory System"
  */
 class MSHR : public Packet::SenderState, public Printable
 {
 
+    /**
+     * Consider the MSHRQueue a friend to avoid making everything public
+     */
+    friend class MSHRQueue;
+
+  private:
+
+    /** Cycle when ready to issue */
+    Tick readyTime;
+
+    /** True if the request is uncacheable */
+    bool _isUncacheable;
+
+    /** Flag set by downstream caches */
+    bool downstreamPending;
+
+    /** Will we have a dirty copy after this request? */
+    bool pendingDirty;
+
+    /** Did we snoop an invalidate while waiting for data? */
+    bool postInvalidate;
+
+    /** Did we snoop a read while waiting for data? */
+    bool postDowngrade;
+
   public:
 
     class Target {
       public:
+
+        enum Source {
+            FromCPU,
+            FromSnoop,
+            FromPrefetcher
+        };
+
         Tick recvTime;  //!< Time when request was received (for stats)
         Tick readyTime; //!< Time when request is ready to be serviced
         Counter order;  //!< Global order (for memory consistency mgmt)
         PacketPtr pkt;  //!< Pending request packet.
-        bool cpuSide;   //!< Did request come from cpu side or mem side?
+        Source source;  //!< Did request come from cpu, memory, or prefetcher?
         bool markedPending; //!< Did we mark upstream MSHR
                             //!<  as downstreamPending?
 
-        bool isCpuSide() const { return cpuSide; }
-
         Target(PacketPtr _pkt, Tick _readyTime, Counter _order,
-               bool _cpuSide, bool _markedPending)
-            : recvTime(curTick), readyTime(_readyTime), order(_order),
-              pkt(_pkt), cpuSide(_cpuSide), markedPending(_markedPending)
+               Source _source, bool _markedPending)
+            : recvTime(curTick()), readyTime(_readyTime), order(_order),
+              pkt(_pkt), source(_source), markedPending(_markedPending)
         {}
     };
 
@@ -85,7 +128,7 @@ class MSHR : public Packet::SenderState, public Printable
         void resetFlags() { needsExclusive = hasUpgrade = false; }
         bool isReset()    { return !needsExclusive && !hasUpgrade; }
         void add(PacketPtr pkt, Tick readyTime, Counter order,
-                 bool cpuSide, bool markPending);
+                 Target::Source source, bool markPending);
         void replaceUpgrades();
         void clearDownstreamPending();
         bool checkFunctional(PacketPtr pkt);
@@ -103,9 +146,6 @@ class MSHR : public Packet::SenderState, public Printable
     /** Pointer to queue containing this MSHR. */
     MSHRQueue *queue;
 
-    /** Cycle when ready to issue */
-    Tick readyTime;
-
     /** Order number assigned by the miss queue. */
     Counter order;
 
@@ -115,28 +155,39 @@ class MSHR : public Packet::SenderState, public Printable
     /** Size of the request. */
     int size;
 
+    /** True if the request targets the secure memory space. */
+    bool isSecure;
+
     /** True if the request has been sent to the bus. */
     bool inService;
 
-    /** True if we will be putting the returned block in the cache */
-    bool isCacheFill;
+    /** True if the request is just a simple forward from an upper level */
+    bool isForward;
+
+    /** The pending* and post* flags are only valid if inService is
+     *  true.  Using the accessor functions lets us detect if these
+     *  flags are accessed improperly.
+     */
 
     /** True if we need to get an exclusive copy of the block. */
-    bool needsExclusive() const { return targets->needsExclusive; }
+    bool needsExclusive() const { return targets.needsExclusive; }
 
-    /** True if the request is uncacheable */
-    bool _isUncacheable;
+    bool isPendingDirty() const {
+        assert(inService); return pendingDirty;
+    }
 
-    bool downstreamPending;
+    bool hasPostInvalidate() const {
+        assert(inService); return postInvalidate;
+    }
 
-    bool pendingInvalidate;
-    bool pendingShared;
+    bool hasPostDowngrade() const {
+        assert(inService); return postDowngrade;
+    }
 
     /** Thread number of the miss. */
-    short threadNum;
-    /** The number of currently allocated targets. */
-    short ntargets;
+    ThreadID threadNum;
 
+  private:
 
     /** Data buffer (if needed).  Currently used only for pending
      * upgrade handling. */
@@ -154,15 +205,14 @@ class MSHR : public Packet::SenderState, public Printable
      */
     Iterator allocIter;
 
-private:
     /** List of all requests that match the address */
-    TargetList *targets;
+    TargetList targets;
 
-    TargetList *deferredTargets;
+    TargetList deferredTargets;
 
-public:
+  public:
 
-    bool isUncacheable() { return _isUncacheable; }
+    bool isUncacheable() const { return _isUncacheable; }
 
     /**
      * Allocate a miss to this MSHR.
@@ -175,7 +225,7 @@ public:
     void allocate(Addr addr, int size, PacketPtr pkt,
                   Tick when, Counter _order);
 
-    bool markInService();
+    bool markInService(PacketPtr pkt);
 
     void clearDownstreamPending();
 
@@ -193,48 +243,44 @@ public:
 
     /** A simple constructor. */
     MSHR();
-    /** A simple destructor. */
-    ~MSHR();
 
     /**
      * Returns the current number of allocated targets.
      * @return The current number of allocated targets.
      */
-    int getNumTargets() { return ntargets; }
-
-    /**
-     * Returns a pointer to the target list.
-     * @return a pointer to the target list.
-     */
-    TargetList *getTargetList() { return targets; }
+    int getNumTargets() const
+    { return targets.size() + deferredTargets.size(); }
 
     /**
      * Returns true if there are targets left.
      * @return true if there are targets
      */
-    bool hasTargets() { return !targets->empty(); }
+    bool hasTargets() const { return !targets.empty(); }
 
     /**
      * Returns a reference to the first target.
      * @return A pointer to the first target.
      */
-    Target *getTarget() { assert(hasTargets());  return &targets->front(); }
+    Target *getTarget()
+    {
+        assert(hasTargets());
+        return &targets.front();
+    }
 
     /**
      * Pop first target.
      */
     void popTarget()
     {
-        --ntargets;
-        targets->pop_front();
+        targets.pop_front();
     }
 
-    bool isSimpleForward()
+    bool isForwardNoResponse() const
     {
         if (getNumTargets() != 1)
             return false;
-        Target *tgt = getTarget();
-        return tgt->isCpuSide() && !tgt->pkt->needsResponse();
+        const Target *tgt = &targets.front();
+        return tgt->source == Target::FromCPU && !tgt->pkt->needsResponse();
     }
 
     bool promoteDeferredTargets();
@@ -249,6 +295,13 @@ public:
     void print(std::ostream &os,
                int verbosity = 0,
                const std::string &prefix = "") const;
+    /**
+     * A no-args wrapper of print(std::ostream...)  meant to be
+     * invoked from DPRINTFs avoiding string overheads in fast mode
+     *
+     * @return string with mshr fields + [deferred]targets
+     */
+    std::string print() const;
 };
 
 #endif //__MSHR_HH__