1a2,13
> * Copyright (c) 2011 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.
> *
29a42
> * Andreas Hansson
34c47,48
< * Declaration of a simple bus bridge object with no buffering
---
> * Declaration of a memory-mapped bus bridge that connects a master
> * and a slave through a request and response queue.
51a66,78
> /**
> * A bridge is used to interface two different busses (or in general a
> * memory-mapped master and slave), with buffering for requests and
> * responses. The bridge has a fixed delay for packets passing through
> * it and responds to a fixed set of address ranges.
> *
> * The bridge comprises a slave port and a master port, that buffer
> * outgoing responses and requests respectively. Buffer space is
> * reserved when a request arrives, also reserving response space
> * before forwarding the request. An incoming request is always
> * accepted (recvTiming returns true), but is potentially NACKed if
> * there is no request space or response space.
> */
55,57c82,125
< /** Declaration of the buses port type, one will be instantiated for each
< of the interfaces connecting to the bus. */
< class BridgePort : public Port
---
>
> /**
> * A packet buffer stores packets along with their sender state
> * and scheduled time for transmission.
> */
> class PacketBuffer : public Packet::SenderState, public FastAlloc {
>
> public:
> Tick ready;
> PacketPtr pkt;
> bool nackedHere;
> Packet::SenderState *origSenderState;
> short origSrc;
> bool expectResponse;
>
> PacketBuffer(PacketPtr _pkt, Tick t, bool nack = false)
> : ready(t), pkt(_pkt), nackedHere(nack),
> origSenderState(_pkt->senderState),
> origSrc(nack ? _pkt->getDest() : _pkt->getSrc() ),
> expectResponse(_pkt->needsResponse() && !nack)
>
> {
> if (!pkt->isResponse() && !nack)
> pkt->senderState = this;
> }
>
> void fixResponse(PacketPtr pkt)
> {
> assert(pkt->senderState == this);
> pkt->setDest(origSrc);
> pkt->senderState = origSenderState;
> }
> };
>
> // Forward declaration to allow the slave port to have a pointer
> class BridgeMasterPort;
>
> /**
> * The port on the side that receives requests and sends
> * responses. The slave port has a set of address ranges that it
> * is responsible for. The slave port also has a buffer for the
> * responses not yet sent.
> */
> class BridgeSlavePort : public Port
58a127,129
>
> private:
>
63c134
< * Pointer to the port on the other side of the bridge
---
> * Pointer to the master port on the other side of the bridge
66c137
< BridgePort *otherPort;
---
> BridgeMasterPort* masterPort;
68c139
< /** Minimum delay though this bridge. */
---
> /** Minimum request delay though this bridge. */
71c142
< /** Min delay to respond to a nack. */
---
> /** Min delay to respond with a nack. */
74,75c145,146
< /** Pass ranges from one side of the bridge to the other? */
< std::vector<Range<Addr> > filterRanges;
---
> /** Address ranges to pass through the bridge */
> AddrRangeList ranges;
77c148,153
< class PacketBuffer : public Packet::SenderState, public FastAlloc {
---
> /**
> * Response packet queue. Response packets are held in this
> * queue for a specified delay to model the processing delay
> * of the bridge.
> */
> std::list<PacketBuffer*> responseQueue;
79,85c155,156
< public:
< Tick ready;
< PacketPtr pkt;
< bool nackedHere;
< Packet::SenderState *origSenderState;
< short origSrc;
< bool expectResponse;
---
> /** Counter to track the outstanding responses. */
> unsigned int outstandingResponses;
87,91c158,159
< PacketBuffer(PacketPtr _pkt, Tick t, bool nack = false)
< : ready(t), pkt(_pkt), nackedHere(nack),
< origSenderState(_pkt->senderState),
< origSrc(nack ? _pkt->getDest() : _pkt->getSrc() ),
< expectResponse(_pkt->needsResponse() && !nack)
---
> /** If we're waiting for a retry to happen. */
> bool inRetry;
93,96c161,162
< {
< if (!pkt->isResponse() && !nack)
< pkt->senderState = this;
< }
---
> /** Max queue size for reserved responses. */
> unsigned int respQueueLimit;
98,104c164,169
< void fixResponse(PacketPtr pkt)
< {
< assert(pkt->senderState == this);
< pkt->setDest(origSrc);
< pkt->senderState = origSenderState;
< }
< };
---
> /**
> * Is this side blocked from accepting new response packets.
> *
> * @return true if the reserved space has reached the set limit
> */
> bool respQueueFull();
107,109c172,175
< * Outbound packet queue. Packets are held in this queue for a
< * specified delay to model the processing delay of the
< * bridge.
---
> * Turn the request packet into a NACK response and put it in
> * the response queue and schedule its transmission.
> *
> * @param pkt the request packet to NACK
111c177
< std::list<PacketBuffer*> sendQueue;
---
> void nackRequest(PacketPtr pkt);
113,114c179,184
< int outstandingResponses;
< int queuedRequests;
---
> /**
> * Handle send event, scheduled when the packet at the head of
> * the response queue is ready to transmit (for timing
> * accesses only).
> */
> void trySend();
116,117c186,192
< /** If we're waiting for a retry to happen.*/
< bool inRetry;
---
> /**
> * Private class for scheduling sending of responses from the
> * response queue.
> */
> class SendEvent : public Event
> {
> BridgeSlavePort *port;
119,120c194,198
< /** Max queue size for outbound packets */
< int reqQueueLimit;
---
> public:
> SendEvent(BridgeSlavePort *p) : port(p) {}
> virtual void process() { port->trySend(); }
> virtual const char *description() const { return "bridge send"; }
> };
122,123c200,201
< /** Max queue size for reserved responses. */
< int respQueueLimit;
---
> /** Send event for the response queue. */
> SendEvent sendEvent;
124a203,204
> public:
>
126c206,214
< * Is this side blocked from accepting outbound packets?
---
> * Constructor for the BridgeSlavePort.
> *
> * @param _name the port name including the owner
> * @param _bridge the structural owner
> * @param _masterPort the master port on the other side of the bridge
> * @param _delay the delay from seeing a response to sending it
> * @param _nack_delay the delay from a NACK to sending the response
> * @param _resp_limit the size of the response queue
> * @param _ranges a number of address ranges to forward
128,129c216,219
< bool respQueueFull();
< bool reqQueueFull();
---
> BridgeSlavePort(const std::string &_name, Bridge *_bridge,
> BridgeMasterPort* _masterPort, int _delay,
> int _nack_delay, int _resp_limit,
> std::vector<Range<Addr> > _ranges);
130a221,226
> /**
> * Queue a response packet to be sent out later and also schedule
> * a send if necessary.
> *
> * @param pkt a response to send out after a delay
> */
133c229
< void finishSend(PacketBuffer *buf);
---
> protected:
135c231,233
< void nackRequest(PacketPtr pkt);
---
> /** When receiving a timing request from the peer port,
> pass it to the bridge. */
> virtual bool recvTiming(PacketPtr pkt);
136a235,246
> /** When receiving a retry request from the peer port,
> pass it to the bridge. */
> virtual void recvRetry();
>
> /** When receiving a Atomic requestfrom the peer port,
> pass it to the bridge. */
> virtual Tick recvAtomic(PacketPtr pkt);
>
> /** When receiving a Functional request from the peer port,
> pass it to the bridge. */
> virtual void recvFunctional(PacketPtr pkt);
>
137a248,293
> * When receiving a range change on the slave side do nothing.
> */
> virtual void recvRangeChange();
>
> /** When receiving a address range request the peer port,
> pass it to the bridge. */
> virtual AddrRangeList getAddrRanges();
> };
>
>
> /**
> * Port on the side that forwards requests and receives
> * responses. The master port has a buffer for the requests not
> * yet sent.
> */
> class BridgeMasterPort : public Port
> {
>
> private:
>
> /** A pointer to the bridge to which this port belongs. */
> Bridge* bridge;
>
> /**
> * Pointer to the slave port on the other side of the bridge
> * (connected to the other bus).
> */
> BridgeSlavePort* slavePort;
>
> /** Minimum delay though this bridge. */
> Tick delay;
>
> /**
> * Request packet queue. Request packets are held in this
> * queue for a specified delay to model the processing delay
> * of the bridge.
> */
> std::list<PacketBuffer*> requestQueue;
>
> /** If we're waiting for a retry to happen. */
> bool inRetry;
>
> /** Max queue size for request packets */
> unsigned int reqQueueLimit;
>
> /**
143a300,303
> /**
> * Private class for scheduling sending of requests from the
> * request queue.
> */
146c306
< BridgePort *port;
---
> BridgeMasterPort *port;
149c309
< SendEvent(BridgePort *p) : port(p) {}
---
> SendEvent(BridgeMasterPort *p) : port(p) {}
153a314
> /** Send event for the request queue. */
157,161d317
< /** Constructor for the BusPort.*/
< BridgePort(const std::string &_name, Bridge *_bridge,
< BridgePort *_otherPort, int _delay, int _nack_delay,
< int _req_limit, int _resp_limit,
< std::vector<Range<Addr> > filter_ranges);
162a319,356
> /**
> * Constructor for the BridgeMasterPort.
> *
> * @param _name the port name including the owner
> * @param _bridge the structural owner
> * @param _slavePort the slave port on the other side of the bridge
> * @param _delay the delay from seeing a request to sending it
> * @param _req_limit the size of the request queue
> */
> BridgeMasterPort(const std::string &_name, Bridge *_bridge,
> BridgeSlavePort* _slavePort, int _delay,
> int _req_limit);
>
> /**
> * Is this side blocked from accepting new request packets.
> *
> * @return true if the occupied space has reached the set limit
> */
> bool reqQueueFull();
>
> /**
> * Queue a request packet to be sent out later and also schedule
> * a send if necessary.
> *
> * @param pkt a request to send out after a delay
> */
> void queueForSendTiming(PacketPtr pkt);
>
> /**
> * Check a functional request against the packets in our
> * request queue.
> *
> * @param pkt packet to check against
> *
> * @return true if we find a match
> */
> bool checkFunctional(PacketPtr pkt);
>
185,188d378
<
< /** When receiving a address range request the peer port,
< pass it to the bridge. */
< virtual AddrRangeList getAddrRanges();
191c381,382
< BridgePort portA, portB;
---
> /** Slave port of the bridge. */
> BridgeSlavePort slavePort;
192a384,386
> /** Master port of the bridge. */
> BridgeMasterPort masterPort;
>