49,50c49,52
< public:
< enum Side
---
> protected:
> /** Decleration of the buses port type, one will be instantiated for each
> of the interfaces connecting to the bus. */
> class BridgePort : public Port
52,54c54,55
< SideA,
< SideB
< };
---
> /** A pointer to the bridge to which this port belongs. */
> Bridge *bridge;
56,59c57,61
< protected:
< /** Function called by the port when the bus is recieving a Timing
< transaction.*/
< bool recvTiming(Packet *pkt, Side id);
---
> /**
> * Pointer to the port on the other side of the bridge
> * (connected to the other bus).
> */
> BridgePort *otherPort;
61,63c63,64
< /** Function called by the port when the bus is recieving a Atomic
< transaction.*/
< Tick recvAtomic(Packet *pkt, Side id);
---
> /** Minimum delay though this bridge. */
> Tick delay;
65,67c66
< /** Function called by the port when the bus is recieving a Functional
< transaction.*/
< void recvFunctional(Packet *pkt, Side id);
---
> class PacketBuffer : public Packet::SenderState {
69,70c68,73
< /** Function called by the port when the bus is recieving a status change.*/
< void recvStatusChange(Port::Status status, Side id);
---
> public:
> Tick ready;
> Packet *pkt;
> Packet::SenderState *origSenderState;
> short origSrc;
> bool expectResponse;
72,77c75,81
< /** Process address range request.
< * @param resp addresses that we can respond to
< * @param snoop addresses that we would like to snoop
< * @param id ide of the busport that made the request.
< */
< void addressRanges(AddrRangeList &resp, AddrRangeList &snoop, Side id);
---
> PacketBuffer(Packet *_pkt, Tick t)
> : ready(t), pkt(_pkt),
> origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()),
> expectResponse(_pkt->needsResponse())
> {
> pkt->senderState = this;
> }
78a83,89
> void fixResponse(Packet *pkt)
> {
> assert(pkt->senderState == this);
> pkt->setDest(origSrc);
> pkt->senderState = origSenderState;
> }
> };
80,82c91,96
< /** Event that the SendEvent calls when it fires. This code must reschedule
< * the send event as required. */
< void timerEvent();
---
> /**
> * Outbound packet queue. Packets are held in this queue for a
> * specified delay to model the processing delay of the
> * bridge.
> */
> std::list<PacketBuffer*> sendQueue;
84,89c98
< /** Decleration of the buses port type, one will be instantiated for each
< of the interfaces connecting to the bus. */
< class BridgePort : public Port
< {
< /** A pointer to the bus to which this port belongs. */
< Bridge *bridge;
---
> int outstandingResponses;
91,92c100,101
< /** A id to keep track of the intercafe ID this port is connected to. */
< Bridge::Side side;
---
> /** Max queue size for outbound packets */
> int queueLimit;
93a103,133
> /**
> * Is this side blocked from accepting outbound packets?
> */
> bool queueFull() { return (sendQueue.size() == queueLimit); }
>
> bool queueForSendTiming(Packet *pkt);
>
> void finishSend(PacketBuffer *buf);
>
> /**
> * Handle send event, scheduled when the packet at the head of
> * the outbound queue is ready to transmit (for timing
> * accesses only).
> */
> void trySend();
>
> class SendEvent : public Event
> {
> BridgePort *port;
>
> public:
> SendEvent(BridgePort *p)
> : Event(&mainEventQueue), port(p) {}
>
> virtual void process() { port->trySend(); }
>
> virtual const char *description() { return "bridge send event"; }
> };
>
> SendEvent sendEvent;
>
97,99c137,139
< BridgePort(Bridge *_bridge, Side _side)
< : Port(""), bridge(_bridge), side(_side)
< { }
---
> BridgePort(const std::string &_name,
> Bridge *_bridge, BridgePort *_otherPort,
> int _delay, int _queueLimit);
101,102d140
< int numQueued() { return outbound.size(); }
<
104,105d141
< /** Data this is waiting to be transmitted. */
< std::list<std::pair<Packet*, Tick> > outbound;
107,110c143
< void sendPkt(Packet *pkt);
< void sendPkt(std::pair<Packet*, Tick> p);
<
< /** When reciving a timing request from the peer port,
---
> /** When receiving a timing request from the peer port,
112,113c145
< virtual bool recvTiming(Packet *pkt)
< { return bridge->recvTiming(pkt, side); }
---
> virtual bool recvTiming(Packet *pkt);
115c147
< /** When reciving a retry request from the peer port,
---
> /** When receiving a retry request from the peer port,
119c151
< /** When reciving a Atomic requestfrom the peer port,
---
> /** When receiving a Atomic requestfrom the peer port,
121,122c153
< virtual Tick recvAtomic(Packet *pkt)
< { return bridge->recvAtomic(pkt, side); }
---
> virtual Tick recvAtomic(Packet *pkt);
124c155
< /** When reciving a Functional request from the peer port,
---
> /** When receiving a Functional request from the peer port,
126,127c157
< virtual void recvFunctional(Packet *pkt)
< { bridge->recvFunctional(pkt, side); }
---
> virtual void recvFunctional(Packet *pkt);
129c159
< /** When reciving a status changefrom the peer port,
---
> /** When receiving a status changefrom the peer port,
131,132c161
< virtual void recvStatusChange(Status status)
< { bridge->recvStatusChange(status, side); }
---
> virtual void recvStatusChange(Status status);
134c163
< /** When reciving a address range request the peer port,
---
> /** When receiving a address range request the peer port,
136,139c165,166
< virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop)
< { bridge->addressRanges(resp, snoop, side); }
<
< friend class Bridge;
---
> virtual void getDeviceAddressRanges(AddrRangeList &resp,
> AddrRangeList &snoop);
142,144c169
< class SendEvent : public Event
< {
< Bridge *bridge;
---
> BridgePort portA, portB;
146,175d170
< SendEvent(Bridge *b)
< : Event(&mainEventQueue), bridge(b) {}
<
< virtual void process() { bridge->timerEvent(); }
<
< virtual const char *description() { return "bridge delay event"; }
< friend class Bridge;
< };
<
< SendEvent sendEvent;
<
< /** Sides of the bus bridges. */
< BridgePort* sideA;
< BridgePort* sideB;
<
< /** inbound queues on both sides. */
< std::list<std::pair<Packet*, Tick> > inboundA;
< std::list<std::pair<Packet*, Tick> > inboundB;
<
< /** The size of the queue for data coming into side a */
< int queueSizeA;
< int queueSizeB;
<
< /* if the side is blocked or not. */
< bool blockedA;
< bool blockedB;
<
< /** Miminum delay though this bridge. */
< Tick delay;
<
182,196c177
< virtual Port *getPort(const std::string &if_name)
< {
< if (if_name == "side_a") {
< if (sideA != NULL)
< panic("bridge side a already connected to.");
< sideA = new BridgePort(this, SideA);
< return sideA;
< } else if (if_name == "side_b") {
< if (sideB != NULL)
< panic("bridge side b already connected to.");
< sideB = new BridgePort(this, SideB);
< return sideB;
< } else
< return NULL;
< }
---
> virtual Port *getPort(const std::string &if_name);
200,211c181
< Bridge(const std::string &n, int qsa, int qsb, Tick _delay, int write_ack)
< : MemObject(n), sendEvent(this), sideA(NULL), sideB(NULL),
< queueSizeA(qsa), queueSizeB(qsb), blockedA(false), blockedB(false),
< delay(_delay), ackWrites(write_ack)
< {}
<
< /** Check if the port should block/unblock after recieving/sending a packet.
< * */
< void blockCheck(Side id);
<
< friend class Bridge::SendEvent;
<
---
> Bridge(const std::string &n, int qsa, int qsb, Tick _delay, int write_ack);