mem-cache: Create an address aware TempCacheBlk
[gem5.git] / src / mem / coherent_xbar.hh
index fd4dd1cca37a9a87792789933ce2019facb6880f..79777b99879efdb130d04bd592f5aeb4d642317e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2014 ARM Limited
+ * Copyright (c) 2011-2015, 2017 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -51,7 +51,9 @@
 #ifndef __MEM_COHERENT_XBAR_HH__
 #define __MEM_COHERENT_XBAR_HH__
 
-#include "base/hashmap.hh"
+#include <unordered_map>
+#include <unordered_set>
+
 #include "mem/snoop_filter.hh"
 #include "mem/xbar.hh"
 #include "params/CoherentXBar.hh"
@@ -76,19 +78,16 @@ class CoherentXBar : public BaseXBar
      * Declare the layers of this crossbar, one vector for requests,
      * one for responses, and one for snoop responses
      */
-    typedef Layer<SlavePort,MasterPort> ReqLayer;
-    typedef Layer<MasterPort,SlavePort> RespLayer;
-    typedef Layer<SlavePort,MasterPort> SnoopLayer;
     std::vector<ReqLayer*> reqLayers;
     std::vector<RespLayer*> respLayers;
-    std::vector<SnoopLayer*> snoopLayers;
+    std::vector<SnoopRespLayer*> snoopLayers;
 
     /**
      * Declaration of the coherent crossbar slave port type, one will
      * be instantiated for each of the master ports connecting to the
      * crossbar.
      */
-    class CoherentXBarSlavePort : public SlavePort
+    class CoherentXBarSlavePort : public QueuedSlavePort
     {
 
       private:
@@ -96,11 +95,15 @@ class CoherentXBar : public BaseXBar
         /** A reference to the crossbar to which this port belongs. */
         CoherentXBar &xbar;
 
+        /** A normal packet queue used to store responses. */
+        RespPacketQueue queue;
+
       public:
 
         CoherentXBarSlavePort(const std::string &_name,
                              CoherentXBar &_xbar, PortID _id)
-            : SlavePort(_name, &_xbar, _id), xbar(_xbar)
+            : QueuedSlavePort(_name, &_xbar, queue, _id), xbar(_xbar),
+              queue(_xbar, *this)
         { }
 
       protected:
@@ -129,12 +132,6 @@ class CoherentXBar : public BaseXBar
         virtual void recvFunctional(PacketPtr pkt)
         { xbar.recvFunctional(pkt, id); }
 
-        /**
-         * When receiving a retry, pass it to the crossbar.
-         */
-        virtual void recvRetry()
-        { panic("Crossbar slave ports should never retry.\n"); }
-
         /**
          * Return the union of all adress ranges seen by this crossbar.
          */
@@ -203,8 +200,8 @@ class CoherentXBar : public BaseXBar
 
         /** When reciving a retry from the peer port (at id),
             pass it to the crossbar. */
-        virtual void recvRetry()
-        { xbar.recvRetry(id); }
+        virtual void recvReqRetry()
+        { xbar.recvReqRetry(id); }
 
     };
 
@@ -219,14 +216,14 @@ class CoherentXBar : public BaseXBar
       private:
 
         /** The port which we mirror internally. */
-        SlavePort& slavePort;
+        QueuedSlavePort& slavePort;
 
       public:
 
         /**
          * Create a snoop response port that mirrors a given slave port.
          */
-        SnoopRespPort(SlavePort& slave_port, CoherentXBar& _xbar) :
+        SnoopRespPort(QueuedSlavePort& slave_port, CoherentXBar& _xbar) :
             MasterPort(slave_port.name() + ".snoopRespPort", &_xbar),
             slavePort(slave_port) { }
 
@@ -234,14 +231,15 @@ class CoherentXBar : public BaseXBar
          * Override the sending of retries and pass them on through
          * the mirrored slave port.
          */
-        void sendRetry() {
-            slavePort.sendRetry();
+        void sendRetryResp() {
+            // forward it as a snoop response retry
+            slavePort.sendRetrySnoopResp();
         }
 
         /**
          * Provided as necessary.
          */
-        void recvRetry() { panic("SnoopRespPort should never see retry\n"); }
+        void recvReqRetry() { panic("SnoopRespPort should never see retry\n"); }
 
         /**
          * Provided as necessary.
@@ -256,14 +254,21 @@ class CoherentXBar : public BaseXBar
 
     std::vector<SnoopRespPort*> snoopRespPorts;
 
-    std::vector<SlavePort*> snoopPorts;
+    std::vector<QueuedSlavePort*> snoopPorts;
+
+    /**
+     * Store the outstanding requests that we are expecting snoop
+     * responses from so we can determine which snoop responses we
+     * generated and which ones were merely forwarded.
+     */
+    std::unordered_set<RequestPtr> outstandingSnoop;
 
     /**
-     * Store the outstanding requests so we can determine which ones
-     * we generated and which ones were merely forwarded. This is used
-     * in the coherent crossbar when coherency responses come back.
+     * Store the outstanding cache maintenance that we are expecting
+     * snoop responses from so we can determine when we received all
+     * snoop responses and if any of the agents satisfied the request.
      */
-    m5::hash_set<RequestPtr> outstandingReq;
+    std::unordered_map<PacketId, PacketPtr> outstandingCMO;
 
     /**
      * Keep a pointer to the system to be allow to querying memory system
@@ -275,6 +280,21 @@ class CoherentXBar : public BaseXBar
       * broadcast needed for probes.  NULL denotes an absent filter. */
     SnoopFilter *snoopFilter;
 
+    /** Cycles of snoop response latency.*/
+    const Cycles snoopResponseLatency;
+
+    /** Is this crossbar the point of coherency? **/
+    const bool pointOfCoherency;
+
+    /** Is this crossbar the point of unification? **/
+    const bool pointOfUnification;
+
+    /**
+     * Upstream caches need this packet until true is returned, so
+     * hold it for deletion until a subsequent call
+     */
+    std::unique_ptr<Packet> pendingDelete;
+
     /** Function called by the port when the crossbar is recieving a Timing
       request packet.*/
     bool recvTimingReq(PacketPtr pkt, PortID slave_port_id);
@@ -293,7 +313,7 @@ class CoherentXBar : public BaseXBar
 
     /** Timing function called by port when it is once again able to process
      * requests. */
-    void recvRetry(PortID master_port_id);
+    void recvReqRetry(PortID master_port_id);
 
     /**
      * Forward a timing packet to our snoopers, potentially excluding
@@ -317,7 +337,7 @@ class CoherentXBar : public BaseXBar
      * @param dests Vector of destination ports for the forwarded pkt
      */
     void forwardTiming(PacketPtr pkt, PortID exclude_slave_port_id,
-                       const std::vector<SlavePort*>& dests);
+                       const std::vector<QueuedSlavePort*>& dests);
 
     /** Function called by the port when the crossbar is recieving a Atomic
       transaction.*/
@@ -340,7 +360,8 @@ class CoherentXBar : public BaseXBar
     std::pair<MemCmd, Tick> forwardAtomic(PacketPtr pkt,
                                           PortID exclude_slave_port_id)
     {
-        return forwardAtomic(pkt, exclude_slave_port_id, InvalidPortID, snoopPorts);
+        return forwardAtomic(pkt, exclude_slave_port_id, InvalidPortID,
+                             snoopPorts);
     }
 
     /**
@@ -358,7 +379,8 @@ class CoherentXBar : public BaseXBar
     std::pair<MemCmd, Tick> forwardAtomic(PacketPtr pkt,
                                           PortID exclude_slave_port_id,
                                           PortID source_master_port_id,
-                                          const std::vector<SlavePort*>& dests);
+                                          const std::vector<QueuedSlavePort*>&
+                                          dests);
 
     /** Function called by the port when the crossbar is recieving a Functional
         transaction.*/
@@ -378,7 +400,37 @@ class CoherentXBar : public BaseXBar
      */
     void forwardFunctional(PacketPtr pkt, PortID exclude_slave_port_id);
 
+    /**
+     * Determine if the crossbar should sink the packet, as opposed to
+     * forwarding it, or responding.
+     */
+    bool sinkPacket(const PacketPtr pkt) const;
+
+    /**
+     * Determine if the crossbar should forward the packet, as opposed to
+     * responding to it.
+     */
+    bool forwardPacket(const PacketPtr pkt);
+
+    /**
+     * Determine if the packet's destination is the memory below
+     *
+     * The memory below is the destination for a cache mainteance
+     * operation to the Point of Coherence/Unification if this is the
+     * Point of Coherence/Unification.
+     *
+     * @param pkt The processed packet
+     *
+     * @return Whether the memory below is the destination for the packet
+     */
+    bool isDestination(const PacketPtr pkt) const
+    {
+        return (pkt->req->isToPOC() && pointOfCoherency) ||
+            (pkt->req->isToPOU() && pointOfUnification);
+    }
+
     Stats::Scalar snoops;
+    Stats::Scalar snoopTraffic;
     Stats::Distribution snoopFanout;
 
   public:
@@ -389,8 +441,6 @@ class CoherentXBar : public BaseXBar
 
     virtual ~CoherentXBar();
 
-    unsigned int drain(DrainManager *dm);
-
     virtual void regStats();
 };