bridge.hh revision 10405
12568SN/A/*
29786Sandreas.hansson@arm.com * Copyright (c) 2011-2013 ARM Limited
38713Sandreas.hansson@arm.com * All rights reserved
48713Sandreas.hansson@arm.com *
58713Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall
68713Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual
78713Sandreas.hansson@arm.com * property including but not limited to intellectual property relating
88713Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software
98713Sandreas.hansson@arm.com * licensed hereunder.  You may use the software subject to the license
108713Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated
118713Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software,
128713Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form.
138713Sandreas.hansson@arm.com *
142568SN/A * Copyright (c) 2006 The Regents of The University of Michigan
152568SN/A * All rights reserved.
162568SN/A *
172568SN/A * Redistribution and use in source and binary forms, with or without
182568SN/A * modification, are permitted provided that the following conditions are
192568SN/A * met: redistributions of source code must retain the above copyright
202568SN/A * notice, this list of conditions and the following disclaimer;
212568SN/A * redistributions in binary form must reproduce the above copyright
222568SN/A * notice, this list of conditions and the following disclaimer in the
232568SN/A * documentation and/or other materials provided with the distribution;
242568SN/A * neither the name of the copyright holders nor the names of its
252568SN/A * contributors may be used to endorse or promote products derived from
262568SN/A * this software without specific prior written permission.
272568SN/A *
282568SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292568SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302568SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312568SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322568SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332568SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342568SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352568SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
362568SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372568SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382568SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392665Ssaidi@eecs.umich.edu *
402665Ssaidi@eecs.umich.edu * Authors: Ali Saidi
412665Ssaidi@eecs.umich.edu *          Steve Reinhardt
428713Sandreas.hansson@arm.com *          Andreas Hansson
432568SN/A */
442568SN/A
452568SN/A/**
462982Sstever@eecs.umich.edu * @file
4710405Sandreas.hansson@arm.com * Declaration of a memory-mapped bridge that connects a master
488713Sandreas.hansson@arm.com * and a slave through a request and response queue.
492568SN/A */
502568SN/A
512568SN/A#ifndef __MEM_BRIDGE_HH__
522568SN/A#define __MEM_BRIDGE_HH__
532568SN/A
549786Sandreas.hansson@arm.com#include <deque>
552568SN/A
566215Snate@binkert.org#include "base/types.hh"
572568SN/A#include "mem/mem_object.hh"
584762Snate@binkert.org#include "params/Bridge.hh"
592568SN/A
608713Sandreas.hansson@arm.com/**
6110405Sandreas.hansson@arm.com * A bridge is used to interface two different crossbars (or in general a
628713Sandreas.hansson@arm.com * memory-mapped master and slave), with buffering for requests and
638713Sandreas.hansson@arm.com * responses. The bridge has a fixed delay for packets passing through
648713Sandreas.hansson@arm.com * it and responds to a fixed set of address ranges.
658713Sandreas.hansson@arm.com *
668713Sandreas.hansson@arm.com * The bridge comprises a slave port and a master port, that buffer
678713Sandreas.hansson@arm.com * outgoing responses and requests respectively. Buffer space is
688713Sandreas.hansson@arm.com * reserved when a request arrives, also reserving response space
699164Sandreas.hansson@arm.com * before forwarding the request. If there is no space present, then
709164Sandreas.hansson@arm.com * the bridge will delay accepting the packet until space becomes
719164Sandreas.hansson@arm.com * available.
728713Sandreas.hansson@arm.com */
732568SN/Aclass Bridge : public MemObject
742568SN/A{
752568SN/A  protected:
768713Sandreas.hansson@arm.com
778713Sandreas.hansson@arm.com    /**
789029Sandreas.hansson@arm.com     * A bridge request state stores packets along with their sender
799029Sandreas.hansson@arm.com     * state and original source. It has enough information to also
809029Sandreas.hansson@arm.com     * restore the response once it comes back to the bridge.
818713Sandreas.hansson@arm.com     */
829044SAli.Saidi@ARM.com    class RequestState : public Packet::SenderState
839029Sandreas.hansson@arm.com    {
848713Sandreas.hansson@arm.com
858713Sandreas.hansson@arm.com      public:
869029Sandreas.hansson@arm.com
879786Sandreas.hansson@arm.com        const PortID origSrc;
888713Sandreas.hansson@arm.com
899542Sandreas.hansson@arm.com        RequestState(PortID orig_src) : origSrc(orig_src)
909029Sandreas.hansson@arm.com        { }
918713Sandreas.hansson@arm.com
928713Sandreas.hansson@arm.com    };
938713Sandreas.hansson@arm.com
949029Sandreas.hansson@arm.com    /**
959164Sandreas.hansson@arm.com     * A deferred packet stores a packet along with its scheduled
969164Sandreas.hansson@arm.com     * transmission time
979029Sandreas.hansson@arm.com     */
989164Sandreas.hansson@arm.com    class DeferredPacket
999029Sandreas.hansson@arm.com    {
1009029Sandreas.hansson@arm.com
1019029Sandreas.hansson@arm.com      public:
1029029Sandreas.hansson@arm.com
1039786Sandreas.hansson@arm.com        const Tick tick;
1049786Sandreas.hansson@arm.com        const PacketPtr pkt;
1059029Sandreas.hansson@arm.com
1069164Sandreas.hansson@arm.com        DeferredPacket(PacketPtr _pkt, Tick _tick) : tick(_tick), pkt(_pkt)
1079029Sandreas.hansson@arm.com        { }
1089029Sandreas.hansson@arm.com    };
1099029Sandreas.hansson@arm.com
1108713Sandreas.hansson@arm.com    // Forward declaration to allow the slave port to have a pointer
1118713Sandreas.hansson@arm.com    class BridgeMasterPort;
1128713Sandreas.hansson@arm.com
1138713Sandreas.hansson@arm.com    /**
1148713Sandreas.hansson@arm.com     * The port on the side that receives requests and sends
1158713Sandreas.hansson@arm.com     * responses. The slave port has a set of address ranges that it
1168713Sandreas.hansson@arm.com     * is responsible for. The slave port also has a buffer for the
1178713Sandreas.hansson@arm.com     * responses not yet sent.
1188713Sandreas.hansson@arm.com     */
1198922Swilliam.wang@arm.com    class BridgeSlavePort : public SlavePort
1202568SN/A    {
1218713Sandreas.hansson@arm.com
1228713Sandreas.hansson@arm.com      private:
1238713Sandreas.hansson@arm.com
1249164Sandreas.hansson@arm.com        /** The bridge to which this port belongs. */
1259164Sandreas.hansson@arm.com        Bridge& bridge;
1262568SN/A
1272643Sstever@eecs.umich.edu        /**
12810405Sandreas.hansson@arm.com         * Master port on the other side of the bridge.
1292643Sstever@eecs.umich.edu         */
1308851Sandreas.hansson@arm.com        BridgeMasterPort& masterPort;
1318713Sandreas.hansson@arm.com
1328713Sandreas.hansson@arm.com        /** Minimum request delay though this bridge. */
1339786Sandreas.hansson@arm.com        const Cycles delay;
1348713Sandreas.hansson@arm.com
1358713Sandreas.hansson@arm.com        /** Address ranges to pass through the bridge */
1369786Sandreas.hansson@arm.com        const AddrRangeList ranges;
1378713Sandreas.hansson@arm.com
1388713Sandreas.hansson@arm.com        /**
1398713Sandreas.hansson@arm.com         * Response packet queue. Response packets are held in this
1408713Sandreas.hansson@arm.com         * queue for a specified delay to model the processing delay
1419786Sandreas.hansson@arm.com         * of the bridge. We use a deque as we need to iterate over
1429786Sandreas.hansson@arm.com         * the items for functional accesses.
1438713Sandreas.hansson@arm.com         */
1449786Sandreas.hansson@arm.com        std::deque<DeferredPacket> transmitList;
1458713Sandreas.hansson@arm.com
1468713Sandreas.hansson@arm.com        /** Counter to track the outstanding responses. */
1478713Sandreas.hansson@arm.com        unsigned int outstandingResponses;
1488713Sandreas.hansson@arm.com
1499164Sandreas.hansson@arm.com        /** If we should send a retry when space becomes available. */
1509164Sandreas.hansson@arm.com        bool retryReq;
1518713Sandreas.hansson@arm.com
1528713Sandreas.hansson@arm.com        /** Max queue size for reserved responses. */
1538713Sandreas.hansson@arm.com        unsigned int respQueueLimit;
1548713Sandreas.hansson@arm.com
1558713Sandreas.hansson@arm.com        /**
1568713Sandreas.hansson@arm.com         * Is this side blocked from accepting new response packets.
1578713Sandreas.hansson@arm.com         *
1588713Sandreas.hansson@arm.com         * @return true if the reserved space has reached the set limit
1598713Sandreas.hansson@arm.com         */
1609786Sandreas.hansson@arm.com        bool respQueueFull() const;
1618713Sandreas.hansson@arm.com
1628713Sandreas.hansson@arm.com        /**
1638713Sandreas.hansson@arm.com         * Handle send event, scheduled when the packet at the head of
1648713Sandreas.hansson@arm.com         * the response queue is ready to transmit (for timing
1658713Sandreas.hansson@arm.com         * accesses only).
1668713Sandreas.hansson@arm.com         */
1679164Sandreas.hansson@arm.com        void trySendTiming();
1688713Sandreas.hansson@arm.com
1698713Sandreas.hansson@arm.com        /** Send event for the response queue. */
1709164Sandreas.hansson@arm.com        EventWrapper<BridgeSlavePort,
1719164Sandreas.hansson@arm.com                     &BridgeSlavePort::trySendTiming> sendEvent;
1728713Sandreas.hansson@arm.com
1738713Sandreas.hansson@arm.com      public:
1748713Sandreas.hansson@arm.com
1758713Sandreas.hansson@arm.com        /**
1768713Sandreas.hansson@arm.com         * Constructor for the BridgeSlavePort.
1778713Sandreas.hansson@arm.com         *
1788713Sandreas.hansson@arm.com         * @param _name the port name including the owner
1798713Sandreas.hansson@arm.com         * @param _bridge the structural owner
1808713Sandreas.hansson@arm.com         * @param _masterPort the master port on the other side of the bridge
1819180Sandreas.hansson@arm.com         * @param _delay the delay in cycles from receiving to sending
1828713Sandreas.hansson@arm.com         * @param _resp_limit the size of the response queue
1838713Sandreas.hansson@arm.com         * @param _ranges a number of address ranges to forward
1848713Sandreas.hansson@arm.com         */
1859164Sandreas.hansson@arm.com        BridgeSlavePort(const std::string& _name, Bridge& _bridge,
1869180Sandreas.hansson@arm.com                        BridgeMasterPort& _masterPort, Cycles _delay,
1879235Sandreas.hansson@arm.com                        int _resp_limit, std::vector<AddrRange> _ranges);
1888713Sandreas.hansson@arm.com
1898713Sandreas.hansson@arm.com        /**
1908713Sandreas.hansson@arm.com         * Queue a response packet to be sent out later and also schedule
1918713Sandreas.hansson@arm.com         * a send if necessary.
1928713Sandreas.hansson@arm.com         *
1938713Sandreas.hansson@arm.com         * @param pkt a response to send out after a delay
1949164Sandreas.hansson@arm.com         * @param when tick when response packet should be sent
1958713Sandreas.hansson@arm.com         */
1969164Sandreas.hansson@arm.com        void schedTimingResp(PacketPtr pkt, Tick when);
1979164Sandreas.hansson@arm.com
1989164Sandreas.hansson@arm.com        /**
1999164Sandreas.hansson@arm.com         * Retry any stalled request that we have failed to accept at
2009164Sandreas.hansson@arm.com         * an earlier point in time. This call will do nothing if no
2019164Sandreas.hansson@arm.com         * request is waiting.
2029164Sandreas.hansson@arm.com         */
2039164Sandreas.hansson@arm.com        void retryStalledReq();
2048713Sandreas.hansson@arm.com
2058713Sandreas.hansson@arm.com      protected:
2068713Sandreas.hansson@arm.com
2078713Sandreas.hansson@arm.com        /** When receiving a timing request from the peer port,
2088713Sandreas.hansson@arm.com            pass it to the bridge. */
2099164Sandreas.hansson@arm.com        bool recvTimingReq(PacketPtr pkt);
2108713Sandreas.hansson@arm.com
2118713Sandreas.hansson@arm.com        /** When receiving a retry request from the peer port,
2128713Sandreas.hansson@arm.com            pass it to the bridge. */
2139164Sandreas.hansson@arm.com        void recvRetry();
2148713Sandreas.hansson@arm.com
2158713Sandreas.hansson@arm.com        /** When receiving a Atomic requestfrom the peer port,
2168713Sandreas.hansson@arm.com            pass it to the bridge. */
2179164Sandreas.hansson@arm.com        Tick recvAtomic(PacketPtr pkt);
2188713Sandreas.hansson@arm.com
2198713Sandreas.hansson@arm.com        /** When receiving a Functional request from the peer port,
2208713Sandreas.hansson@arm.com            pass it to the bridge. */
2219164Sandreas.hansson@arm.com        void recvFunctional(PacketPtr pkt);
2228713Sandreas.hansson@arm.com
2238713Sandreas.hansson@arm.com        /** When receiving a address range request the peer port,
2248713Sandreas.hansson@arm.com            pass it to the bridge. */
2259164Sandreas.hansson@arm.com        AddrRangeList getAddrRanges() const;
2268713Sandreas.hansson@arm.com    };
2278713Sandreas.hansson@arm.com
2288713Sandreas.hansson@arm.com
2298713Sandreas.hansson@arm.com    /**
2308713Sandreas.hansson@arm.com     * Port on the side that forwards requests and receives
2318713Sandreas.hansson@arm.com     * responses. The master port has a buffer for the requests not
2328713Sandreas.hansson@arm.com     * yet sent.
2338713Sandreas.hansson@arm.com     */
2348922Swilliam.wang@arm.com    class BridgeMasterPort : public MasterPort
2358713Sandreas.hansson@arm.com    {
2368713Sandreas.hansson@arm.com
2378713Sandreas.hansson@arm.com      private:
2388713Sandreas.hansson@arm.com
2399164Sandreas.hansson@arm.com        /** The bridge to which this port belongs. */
2409164Sandreas.hansson@arm.com        Bridge& bridge;
2418713Sandreas.hansson@arm.com
2428713Sandreas.hansson@arm.com        /**
24310405Sandreas.hansson@arm.com         * The slave port on the other side of the bridge.
2448713Sandreas.hansson@arm.com         */
2458851Sandreas.hansson@arm.com        BridgeSlavePort& slavePort;
2462643Sstever@eecs.umich.edu
2472643Sstever@eecs.umich.edu        /** Minimum delay though this bridge. */
2489786Sandreas.hansson@arm.com        const Cycles delay;
2492643Sstever@eecs.umich.edu
2508713Sandreas.hansson@arm.com        /**
2518713Sandreas.hansson@arm.com         * Request packet queue. Request packets are held in this
2528713Sandreas.hansson@arm.com         * queue for a specified delay to model the processing delay
2539786Sandreas.hansson@arm.com         * of the bridge.  We use a deque as we need to iterate over
2549786Sandreas.hansson@arm.com         * the items for functional accesses.
2558713Sandreas.hansson@arm.com         */
2569786Sandreas.hansson@arm.com        std::deque<DeferredPacket> transmitList;
2574435Ssaidi@eecs.umich.edu
2588713Sandreas.hansson@arm.com        /** Max queue size for request packets */
2599786Sandreas.hansson@arm.com        const unsigned int reqQueueLimit;
2604433Ssaidi@eecs.umich.edu
2612643Sstever@eecs.umich.edu        /**
2622643Sstever@eecs.umich.edu         * Handle send event, scheduled when the packet at the head of
2632643Sstever@eecs.umich.edu         * the outbound queue is ready to transmit (for timing
2642643Sstever@eecs.umich.edu         * accesses only).
2652643Sstever@eecs.umich.edu         */
2669164Sandreas.hansson@arm.com        void trySendTiming();
2672643Sstever@eecs.umich.edu
2688713Sandreas.hansson@arm.com        /** Send event for the request queue. */
2699164Sandreas.hansson@arm.com        EventWrapper<BridgeMasterPort,
2709164Sandreas.hansson@arm.com                     &BridgeMasterPort::trySendTiming> sendEvent;
2712568SN/A
2722568SN/A      public:
2738713Sandreas.hansson@arm.com
2748713Sandreas.hansson@arm.com        /**
2758713Sandreas.hansson@arm.com         * Constructor for the BridgeMasterPort.
2768713Sandreas.hansson@arm.com         *
2778713Sandreas.hansson@arm.com         * @param _name the port name including the owner
2788713Sandreas.hansson@arm.com         * @param _bridge the structural owner
2798713Sandreas.hansson@arm.com         * @param _slavePort the slave port on the other side of the bridge
2809180Sandreas.hansson@arm.com         * @param _delay the delay in cycles from receiving to sending
2818713Sandreas.hansson@arm.com         * @param _req_limit the size of the request queue
2828713Sandreas.hansson@arm.com         */
2839164Sandreas.hansson@arm.com        BridgeMasterPort(const std::string& _name, Bridge& _bridge,
2849180Sandreas.hansson@arm.com                         BridgeSlavePort& _slavePort, Cycles _delay,
2858713Sandreas.hansson@arm.com                         int _req_limit);
2868713Sandreas.hansson@arm.com
2878713Sandreas.hansson@arm.com        /**
2888713Sandreas.hansson@arm.com         * Is this side blocked from accepting new request packets.
2898713Sandreas.hansson@arm.com         *
2908713Sandreas.hansson@arm.com         * @return true if the occupied space has reached the set limit
2918713Sandreas.hansson@arm.com         */
2929786Sandreas.hansson@arm.com        bool reqQueueFull() const;
2938713Sandreas.hansson@arm.com
2948713Sandreas.hansson@arm.com        /**
2958713Sandreas.hansson@arm.com         * Queue a request packet to be sent out later and also schedule
2968713Sandreas.hansson@arm.com         * a send if necessary.
2978713Sandreas.hansson@arm.com         *
2988713Sandreas.hansson@arm.com         * @param pkt a request to send out after a delay
2999164Sandreas.hansson@arm.com         * @param when tick when response packet should be sent
3008713Sandreas.hansson@arm.com         */
3019164Sandreas.hansson@arm.com        void schedTimingReq(PacketPtr pkt, Tick when);
3028713Sandreas.hansson@arm.com
3038713Sandreas.hansson@arm.com        /**
3048713Sandreas.hansson@arm.com         * Check a functional request against the packets in our
3058713Sandreas.hansson@arm.com         * request queue.
3068713Sandreas.hansson@arm.com         *
3078713Sandreas.hansson@arm.com         * @param pkt packet to check against
3088713Sandreas.hansson@arm.com         *
3098713Sandreas.hansson@arm.com         * @return true if we find a match
3108713Sandreas.hansson@arm.com         */
3118713Sandreas.hansson@arm.com        bool checkFunctional(PacketPtr pkt);
3122568SN/A
3132568SN/A      protected:
3142568SN/A
3152643Sstever@eecs.umich.edu        /** When receiving a timing request from the peer port,
3162643Sstever@eecs.umich.edu            pass it to the bridge. */
3179164Sandreas.hansson@arm.com        bool recvTimingResp(PacketPtr pkt);
3182568SN/A
3192643Sstever@eecs.umich.edu        /** When receiving a retry request from the peer port,
3202568SN/A            pass it to the bridge. */
3219164Sandreas.hansson@arm.com        void recvRetry();
3222568SN/A    };
3232568SN/A
3248713Sandreas.hansson@arm.com    /** Slave port of the bridge. */
3258713Sandreas.hansson@arm.com    BridgeSlavePort slavePort;
3268713Sandreas.hansson@arm.com
3278713Sandreas.hansson@arm.com    /** Master port of the bridge. */
3288713Sandreas.hansson@arm.com    BridgeMasterPort masterPort;
3292568SN/A
3302568SN/A  public:
3312568SN/A
3329294Sandreas.hansson@arm.com    virtual BaseMasterPort& getMasterPort(const std::string& if_name,
3339294Sandreas.hansson@arm.com                                          PortID idx = InvalidPortID);
3349294Sandreas.hansson@arm.com    virtual BaseSlavePort& getSlavePort(const std::string& if_name,
3359294Sandreas.hansson@arm.com                                        PortID idx = InvalidPortID);
3362568SN/A
3372568SN/A    virtual void init();
3382568SN/A
3399164Sandreas.hansson@arm.com    typedef BridgeParams Params;
3409164Sandreas.hansson@arm.com
3414435Ssaidi@eecs.umich.edu    Bridge(Params *p);
3422568SN/A};
3432568SN/A
34410405Sandreas.hansson@arm.com#endif //__MEM_BRIDGE_HH__
345