/*
- * Copyright (c) 2011-2014 ARM Limited
+ * Copyright (c) 2011-2015 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* 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:
/** 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:
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.
*/
/** 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); }
};
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) { }
* 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.
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.
*/
- m5::hash_set<RequestPtr> outstandingSnoop;
+ std::unordered_set<RequestPtr> outstandingSnoop;
/**
* 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;
+
+ /**
+ * 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);
/** 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
* @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.*/
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);
}
/**
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.*/
virtual ~CoherentXBar();
- unsigned int drain(DrainManager *dm);
-
virtual void regStats();
};