bridge.hh revision 8949:3fa1ee293096
12292SN/A/*
22689Sktlim@umich.edu * Copyright (c) 2011-2012 ARM Limited
32292SN/A * All rights reserved
42292SN/A *
52292SN/A * The license below extends only to copyright in the software and shall
62292SN/A * not be construed as granting a license to any other intellectual
72292SN/A * property including but not limited to intellectual property relating
82292SN/A * to a hardware implementation of the functionality of the software
92292SN/A * licensed hereunder.  You may use the software subject to the license
102292SN/A * terms below provided that you ensure that this notice is replicated
112292SN/A * unmodified and in its entirety in all distributions of the software,
122292SN/A * modified or unmodified, in source code or in binary form.
132292SN/A *
142292SN/A * Copyright (c) 2006 The Regents of The University of Michigan
152292SN/A * All rights reserved.
162292SN/A *
172292SN/A * Redistribution and use in source and binary forms, with or without
182292SN/A * modification, are permitted provided that the following conditions are
192292SN/A * met: redistributions of source code must retain the above copyright
202292SN/A * notice, this list of conditions and the following disclaimer;
212292SN/A * redistributions in binary form must reproduce the above copyright
222292SN/A * notice, this list of conditions and the following disclaimer in the
232292SN/A * documentation and/or other materials provided with the distribution;
242292SN/A * neither the name of the copyright holders nor the names of its
252292SN/A * contributors may be used to endorse or promote products derived from
262292SN/A * this software without specific prior written permission.
272689Sktlim@umich.edu *
282689Sktlim@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302292SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312292SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332292SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342292SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352292SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
362292SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372292SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382292SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
398229Snate@binkert.org *
405034Smilesck@eecs.umich.edu * Authors: Ali Saidi
412292SN/A *          Steve Reinhardt
422292SN/A *          Andreas Hansson
432292SN/A */
442292SN/A
452292SN/A/**
462292SN/A * @file
472292SN/A * Declaration of a memory-mapped bus bridge that connects a master
482292SN/A * and a slave through a request and response queue.
492292SN/A */
502292SN/A
512292SN/A#ifndef __MEM_BRIDGE_HH__
522292SN/A#define __MEM_BRIDGE_HH__
532292SN/A
542292SN/A#include <list>
552292SN/A#include <queue>
562292SN/A#include <string>
572292SN/A
582292SN/A#include "base/fast_alloc.hh"
592292SN/A#include "base/types.hh"
602292SN/A#include "mem/mem_object.hh"
612292SN/A#include "mem/packet.hh"
629184Sandreas.hansson@arm.com#include "mem/port.hh"
632292SN/A#include "params/Bridge.hh"
649184Sandreas.hansson@arm.com#include "sim/eventq.hh"
652292SN/A
662292SN/A/**
672292SN/A * A bridge is used to interface two different busses (or in general a
682292SN/A * memory-mapped master and slave), with buffering for requests and
692292SN/A * responses. The bridge has a fixed delay for packets passing through
702292SN/A * it and responds to a fixed set of address ranges.
712292SN/A *
722292SN/A * The bridge comprises a slave port and a master port, that buffer
732292SN/A * outgoing responses and requests respectively. Buffer space is
742292SN/A * reserved when a request arrives, also reserving response space
752292SN/A * before forwarding the request. An incoming request is always
762292SN/A * accepted (recvTiming returns true), but is potentially NACKed if
772292SN/A * there is no request space or response space.
782292SN/A */
792292SN/Aclass Bridge : public MemObject
802292SN/A{
812292SN/A  protected:
822292SN/A
832292SN/A    /**
842292SN/A     * A packet buffer stores packets along with their sender state
852292SN/A     * and scheduled time for transmission.
862292SN/A     */
872292SN/A    class PacketBuffer : public Packet::SenderState, public FastAlloc {
882292SN/A
892292SN/A      public:
902292SN/A        Tick ready;
912292SN/A        PacketPtr pkt;
922292SN/A        bool nackedHere;
932292SN/A        Packet::SenderState *origSenderState;
942292SN/A        Packet::NodeID origSrc;
952292SN/A        bool expectResponse;
962292SN/A
972292SN/A        PacketBuffer(PacketPtr _pkt, Tick t, bool nack = false)
982292SN/A            : ready(t), pkt(_pkt), nackedHere(nack),
992292SN/A              origSenderState(_pkt->senderState),
1002292SN/A              origSrc(nack ? _pkt->getDest() : _pkt->getSrc() ),
1012292SN/A              expectResponse(_pkt->needsResponse() && !nack)
1022292SN/A
1032292SN/A        {
1042292SN/A            if (!pkt->isResponse() && !nack)
1052292SN/A                pkt->senderState = this;
1062292SN/A        }
1072292SN/A
1082292SN/A        void fixResponse(PacketPtr pkt)
1092292SN/A        {
1102292SN/A            assert(pkt->senderState == this);
1112292SN/A            pkt->setDest(origSrc);
1122292SN/A            pkt->senderState = origSenderState;
1132292SN/A        }
1142292SN/A    };
1152292SN/A
1162292SN/A    // Forward declaration to allow the slave port to have a pointer
1172292SN/A    class BridgeMasterPort;
1182292SN/A
1195034Smilesck@eecs.umich.edu    /**
1202292SN/A     * The port on the side that receives requests and sends
1215034Smilesck@eecs.umich.edu     * responses. The slave port has a set of address ranges that it
1222292SN/A     * is responsible for. The slave port also has a buffer for the
1232292SN/A     * responses not yet sent.
1242292SN/A     */
1252292SN/A    class BridgeSlavePort : public SlavePort
1262292SN/A    {
1279184Sandreas.hansson@arm.com
1282292SN/A      private:
1292292SN/A
1302292SN/A        /** A pointer to the bridge to which this port belongs. */
1312292SN/A        Bridge *bridge;
1322292SN/A
1332292SN/A        /**
1342292SN/A         * Master port on the other side of the bridge
1352292SN/A         * (connected to the other bus).
1362292SN/A         */
1372292SN/A        BridgeMasterPort& masterPort;
1382292SN/A
1392327SN/A        /** Minimum request delay though this bridge. */
1402292SN/A        Tick delay;
1412292SN/A
1422292SN/A        /** Min delay to respond with a nack. */
1432292SN/A        Tick nackDelay;
1442292SN/A
1452292SN/A        /** Address ranges to pass through the bridge */
1462292SN/A        AddrRangeList ranges;
1472292SN/A
1482292SN/A        /**
1492292SN/A         * Response packet queue. Response packets are held in this
1502292SN/A         * queue for a specified delay to model the processing delay
1519184Sandreas.hansson@arm.com         * of the bridge.
1522292SN/A         */
1532292SN/A        std::list<PacketBuffer*> responseQueue;
1542292SN/A
1552292SN/A        /** Counter to track the outstanding responses. */
1569184Sandreas.hansson@arm.com        unsigned int outstandingResponses;
1572292SN/A
1582292SN/A        /** If we're waiting for a retry to happen. */
1592307SN/A        bool inRetry;
1602348SN/A
1612307SN/A        /** Max queue size for reserved responses. */
1622348SN/A        unsigned int respQueueLimit;
1632348SN/A
1648737Skoansin.tan@gmail.com        /**
1652292SN/A         * Is this side blocked from accepting new response packets.
1662292SN/A         *
1672292SN/A         * @return true if the reserved space has reached the set limit
168         */
169        bool respQueueFull();
170
171        /**
172         * Turn the request packet into a NACK response and put it in
173         * the response queue and schedule its transmission.
174         *
175         * @param pkt the request packet to NACK
176         */
177        void nackRequest(PacketPtr pkt);
178
179        /**
180         * Handle send event, scheduled when the packet at the head of
181         * the response queue is ready to transmit (for timing
182         * accesses only).
183         */
184        void trySend();
185
186        /**
187         * Private class for scheduling sending of responses from the
188         * response queue.
189         */
190        class SendEvent : public Event
191        {
192            BridgeSlavePort& port;
193
194          public:
195            SendEvent(BridgeSlavePort& p) : port(p) {}
196            virtual void process() { port.trySend(); }
197            virtual const char *description() const { return "bridge send"; }
198        };
199
200        /** Send event for the response queue. */
201        SendEvent sendEvent;
202
203      public:
204
205        /**
206         * Constructor for the BridgeSlavePort.
207         *
208         * @param _name the port name including the owner
209         * @param _bridge the structural owner
210         * @param _masterPort the master port on the other side of the bridge
211         * @param _delay the delay from seeing a response to sending it
212         * @param _nack_delay the delay from a NACK to sending the response
213         * @param _resp_limit the size of the response queue
214         * @param _ranges a number of address ranges to forward
215         */
216        BridgeSlavePort(const std::string &_name, Bridge *_bridge,
217                        BridgeMasterPort& _masterPort, int _delay,
218                        int _nack_delay, int _resp_limit,
219                        std::vector<Range<Addr> > _ranges);
220
221        /**
222         * Queue a response packet to be sent out later and also schedule
223         * a send if necessary.
224         *
225         * @param pkt a response to send out after a delay
226         */
227        void queueForSendTiming(PacketPtr pkt);
228
229      protected:
230
231        /** When receiving a timing request from the peer port,
232            pass it to the bridge. */
233        virtual bool recvTiming(PacketPtr pkt);
234
235        /** When receiving a retry request from the peer port,
236            pass it to the bridge. */
237        virtual void recvRetry();
238
239        /** When receiving a Atomic requestfrom the peer port,
240            pass it to the bridge. */
241        virtual Tick recvAtomic(PacketPtr pkt);
242
243        /** When receiving a Functional request from the peer port,
244            pass it to the bridge. */
245        virtual void recvFunctional(PacketPtr pkt);
246
247        /** When receiving a address range request the peer port,
248            pass it to the bridge. */
249        virtual AddrRangeList getAddrRanges();
250    };
251
252
253    /**
254     * Port on the side that forwards requests and receives
255     * responses. The master port has a buffer for the requests not
256     * yet sent.
257     */
258    class BridgeMasterPort : public MasterPort
259    {
260
261      private:
262
263        /** A pointer to the bridge to which this port belongs. */
264        Bridge* bridge;
265
266        /**
267         * Pointer to the slave port on the other side of the bridge
268         * (connected to the other bus).
269         */
270        BridgeSlavePort& slavePort;
271
272        /** Minimum delay though this bridge. */
273        Tick delay;
274
275        /**
276         * Request packet queue. Request packets are held in this
277         * queue for a specified delay to model the processing delay
278         * of the bridge.
279         */
280        std::list<PacketBuffer*> requestQueue;
281
282        /** If we're waiting for a retry to happen. */
283        bool inRetry;
284
285        /** Max queue size for request packets */
286        unsigned int reqQueueLimit;
287
288        /**
289         * Handle send event, scheduled when the packet at the head of
290         * the outbound queue is ready to transmit (for timing
291         * accesses only).
292         */
293        void trySend();
294
295        /**
296         * Private class for scheduling sending of requests from the
297         * request queue.
298         */
299        class SendEvent : public Event
300        {
301            BridgeMasterPort& port;
302
303          public:
304            SendEvent(BridgeMasterPort& p) : port(p) {}
305            virtual void process() { port.trySend(); }
306            virtual const char *description() const { return "bridge send"; }
307        };
308
309        /** Send event for the request queue. */
310        SendEvent sendEvent;
311
312      public:
313
314        /**
315         * Constructor for the BridgeMasterPort.
316         *
317         * @param _name the port name including the owner
318         * @param _bridge the structural owner
319         * @param _slavePort the slave port on the other side of the bridge
320         * @param _delay the delay from seeing a request to sending it
321         * @param _req_limit the size of the request queue
322         */
323        BridgeMasterPort(const std::string &_name, Bridge *_bridge,
324                         BridgeSlavePort& _slavePort, int _delay,
325                         int _req_limit);
326
327        /**
328         * Is this side blocked from accepting new request packets.
329         *
330         * @return true if the occupied space has reached the set limit
331         */
332        bool reqQueueFull();
333
334        /**
335         * Queue a request packet to be sent out later and also schedule
336         * a send if necessary.
337         *
338         * @param pkt a request to send out after a delay
339         */
340        void queueForSendTiming(PacketPtr pkt);
341
342        /**
343         * Check a functional request against the packets in our
344         * request queue.
345         *
346         * @param pkt packet to check against
347         *
348         * @return true if we find a match
349         */
350        bool checkFunctional(PacketPtr pkt);
351
352      protected:
353
354        /** When receiving a timing request from the peer port,
355            pass it to the bridge. */
356        virtual bool recvTiming(PacketPtr pkt);
357
358        /** When receiving a retry request from the peer port,
359            pass it to the bridge. */
360        virtual void recvRetry();
361    };
362
363    /** Slave port of the bridge. */
364    BridgeSlavePort slavePort;
365
366    /** Master port of the bridge. */
367    BridgeMasterPort masterPort;
368
369    /** If this bridge should acknowledge writes. */
370    bool ackWrites;
371
372  public:
373    typedef BridgeParams Params;
374
375  protected:
376    Params *_params;
377
378  public:
379    const Params *params() const { return _params; }
380
381    virtual MasterPort& getMasterPort(const std::string& if_name,
382                                      int idx = -1);
383    virtual SlavePort& getSlavePort(const std::string& if_name, int idx = -1);
384
385    virtual void init();
386
387    Bridge(Params *p);
388};
389
390#endif //__MEM_BUS_HH__
391