/*
- * Copyright (c) 2011-2015 ARM Limited
+ * Copyright (c) 2011-2015, 2017 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
#ifndef __MEM_COHERENT_XBAR_HH__
#define __MEM_COHERENT_XBAR_HH__
+#include <unordered_map>
+#include <unordered_set>
+
#include "mem/snoop_filter.hh"
#include "mem/xbar.hh"
#include "params/CoherentXBar.hh"
protected:
- /**
- * When receiving a timing request, pass it to the crossbar.
- */
- virtual bool recvTimingReq(PacketPtr pkt)
- { return xbar.recvTimingReq(pkt, id); }
+ bool
+ recvTimingReq(PacketPtr pkt) override
+ {
+ return xbar.recvTimingReq(pkt, id);
+ }
- /**
- * When receiving a timing snoop response, pass it to the crossbar.
- */
- virtual bool recvTimingSnoopResp(PacketPtr pkt)
- { return xbar.recvTimingSnoopResp(pkt, id); }
+ bool
+ recvTimingSnoopResp(PacketPtr pkt) override
+ {
+ return xbar.recvTimingSnoopResp(pkt, id);
+ }
- /**
- * When receiving an atomic request, pass it to the crossbar.
- */
- virtual Tick recvAtomic(PacketPtr pkt)
- { return xbar.recvAtomic(pkt, id); }
+ Tick
+ recvAtomic(PacketPtr pkt) override
+ {
+ return xbar.recvAtomicBackdoor(pkt, id);
+ }
- /**
- * When receiving a functional request, pass it to the crossbar.
- */
- virtual void recvFunctional(PacketPtr pkt)
- { xbar.recvFunctional(pkt, id); }
+ Tick
+ recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor) override
+ {
+ return xbar.recvAtomicBackdoor(pkt, id, &backdoor);
+ }
- /**
- * Return the union of all adress ranges seen by this crossbar.
- */
- virtual AddrRangeList getAddrRanges() const
- { return xbar.getAddrRanges(); }
+ void
+ recvFunctional(PacketPtr pkt) override
+ {
+ xbar.recvFunctional(pkt, id);
+ }
+
+ AddrRangeList
+ getAddrRanges() const override
+ {
+ return xbar.getAddrRanges();
+ }
};
*
* @return a boolean that is true if this port is snooping
*/
- virtual bool isSnooping() const
- { return true; }
-
- /**
- * When receiving a timing response, pass it to the crossbar.
- */
- virtual bool recvTimingResp(PacketPtr pkt)
- { return xbar.recvTimingResp(pkt, id); }
+ bool isSnooping() const override { return true; }
- /**
- * When receiving a timing snoop request, pass it to the crossbar.
- */
- virtual void recvTimingSnoopReq(PacketPtr pkt)
- { return xbar.recvTimingSnoopReq(pkt, id); }
+ bool
+ recvTimingResp(PacketPtr pkt) override
+ {
+ return xbar.recvTimingResp(pkt, id);
+ }
- /**
- * When receiving an atomic snoop request, pass it to the crossbar.
- */
- virtual Tick recvAtomicSnoop(PacketPtr pkt)
- { return xbar.recvAtomicSnoop(pkt, id); }
+ void
+ recvTimingSnoopReq(PacketPtr pkt) override
+ {
+ return xbar.recvTimingSnoopReq(pkt, id);
+ }
- /**
- * When receiving a functional snoop request, pass it to the crossbar.
- */
- virtual void recvFunctionalSnoop(PacketPtr pkt)
- { xbar.recvFunctionalSnoop(pkt, id); }
+ Tick
+ recvAtomicSnoop(PacketPtr pkt) override
+ {
+ return xbar.recvAtomicSnoop(pkt, id);
+ }
- /** When reciving a range change from the peer port (at id),
- pass it to the crossbar. */
- virtual void recvRangeChange()
- { xbar.recvRangeChange(id); }
+ void
+ recvFunctionalSnoop(PacketPtr pkt) override
+ {
+ xbar.recvFunctionalSnoop(pkt, id);
+ }
- /** When reciving a retry from the peer port (at id),
- pass it to the crossbar. */
- virtual void recvReqRetry()
- { xbar.recvReqRetry(id); }
+ void recvRangeChange() override { xbar.recvRangeChange(id); }
+ void recvReqRetry() override { xbar.recvReqRetry(id); }
};
* Override the sending of retries and pass them on through
* the mirrored slave port.
*/
- void sendRetryResp() {
+ void
+ sendRetryResp() override
+ {
// forward it as a snoop response retry
slavePort.sendRetrySnoopResp();
}
- /**
- * Provided as necessary.
- */
- void recvReqRetry() { panic("SnoopRespPort should never see retry\n"); }
+ void
+ recvReqRetry() override
+ {
+ panic("SnoopRespPort should never see retry");
+ }
- /**
- * Provided as necessary.
- */
- bool recvTimingResp(PacketPtr pkt)
+ bool
+ recvTimingResp(PacketPtr pkt) override
{
- panic("SnoopRespPort should never see timing response\n");
- return false;
+ panic("SnoopRespPort should never see timing response");
}
};
* responses from so we can determine which snoop responses we
* generated and which ones were merely forwarded.
*/
- m5::hash_set<RequestPtr> outstandingSnoop;
+ std::unordered_set<RequestPtr> outstandingSnoop;
+
+ /**
+ * 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.
+ */
+ std::unordered_map<PacketId, PacketPtr> outstandingCMO;
/**
* Keep a pointer to the system to be allow to querying memory system
* broadcast needed for probes. NULL denotes an absent filter. */
SnoopFilter *snoopFilter;
- /** Cycles of snoop response latency.*/
const Cycles snoopResponseLatency;
+ const bool pointOfCoherency;
+ const bool pointOfUnification;
/**
- * @todo this is a temporary workaround until the 4-phase code is committed.
- * upstream caches need this packet until true is returned, so hold it for
- * deletion until a subsequent call
+ * Upstream caches need this packet until true is returned, so
+ * hold it for deletion until a subsequent call
*/
- std::vector<PacketPtr> pendingDelete;
+ 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);
-
- /** Function called by the port when the crossbar is recieving a Timing
- response packet.*/
bool recvTimingResp(PacketPtr pkt, PortID master_port_id);
-
- /** Function called by the port when the crossbar is recieving a timing
- snoop request.*/
void recvTimingSnoopReq(PacketPtr pkt, PortID master_port_id);
-
- /** Function called by the port when the crossbar is recieving a timing
- snoop response.*/
bool recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id);
-
- /** Timing function called by port when it is once again able to process
- * requests. */
void recvReqRetry(PortID master_port_id);
/**
* @param pkt Packet to forward
* @param exclude_slave_port_id Id of slave port to exclude
*/
- void forwardTiming(PacketPtr pkt, PortID exclude_slave_port_id) {
+ void
+ forwardTiming(PacketPtr pkt, PortID exclude_slave_port_id)
+ {
forwardTiming(pkt, exclude_slave_port_id, snoopPorts);
}
void forwardTiming(PacketPtr pkt, PortID exclude_slave_port_id,
const std::vector<QueuedSlavePort*>& dests);
- /** Function called by the port when the crossbar is recieving a Atomic
- transaction.*/
- Tick recvAtomic(PacketPtr pkt, PortID slave_port_id);
-
- /** Function called by the port when the crossbar is recieving an
- atomic snoop transaction.*/
+ Tick recvAtomicBackdoor(PacketPtr pkt, PortID slave_port_id,
+ MemBackdoorPtr *backdoor=nullptr);
Tick recvAtomicSnoop(PacketPtr pkt, PortID master_port_id);
/**
*
* @return a pair containing the snoop response and snoop latency
*/
- std::pair<MemCmd, Tick> forwardAtomic(PacketPtr pkt,
- PortID exclude_slave_port_id)
+ std::pair<MemCmd, Tick>
+ forwardAtomic(PacketPtr pkt, PortID exclude_slave_port_id)
{
return forwardAtomic(pkt, exclude_slave_port_id, InvalidPortID,
snoopPorts);
*/
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: