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"
5713892Sgabeblack@google.com#include "mem/port.hh"
584762Snate@binkert.org#include "params/Bridge.hh"
5913892Sgabeblack@google.com#include "sim/clocked_object.hh"
602568SN/A
618713Sandreas.hansson@arm.com/**
6210405Sandreas.hansson@arm.com * A bridge is used to interface two different crossbars (or in general a
638713Sandreas.hansson@arm.com * memory-mapped master and slave), with buffering for requests and
648713Sandreas.hansson@arm.com * responses. The bridge has a fixed delay for packets passing through
658713Sandreas.hansson@arm.com * it and responds to a fixed set of address ranges.
668713Sandreas.hansson@arm.com *
678713Sandreas.hansson@arm.com * The bridge comprises a slave port and a master port, that buffer
688713Sandreas.hansson@arm.com * outgoing responses and requests respectively. Buffer space is
698713Sandreas.hansson@arm.com * reserved when a request arrives, also reserving response space
709164Sandreas.hansson@arm.com * before forwarding the request. If there is no space present, then
719164Sandreas.hansson@arm.com * the bridge will delay accepting the packet until space becomes
729164Sandreas.hansson@arm.com * available.
738713Sandreas.hansson@arm.com */
7413892Sgabeblack@google.comclass Bridge : public ClockedObject
752568SN/A{
762568SN/A  protected:
778713Sandreas.hansson@arm.com
788713Sandreas.hansson@arm.com    /**
799164Sandreas.hansson@arm.com     * A deferred packet stores a packet along with its scheduled
809164Sandreas.hansson@arm.com     * transmission time
819029Sandreas.hansson@arm.com     */
829164Sandreas.hansson@arm.com    class DeferredPacket
839029Sandreas.hansson@arm.com    {
849029Sandreas.hansson@arm.com
859029Sandreas.hansson@arm.com      public:
869029Sandreas.hansson@arm.com
879786Sandreas.hansson@arm.com        const Tick tick;
889786Sandreas.hansson@arm.com        const PacketPtr pkt;
899029Sandreas.hansson@arm.com
909164Sandreas.hansson@arm.com        DeferredPacket(PacketPtr _pkt, Tick _tick) : tick(_tick), pkt(_pkt)
919029Sandreas.hansson@arm.com        { }
929029Sandreas.hansson@arm.com    };
939029Sandreas.hansson@arm.com
948713Sandreas.hansson@arm.com    // Forward declaration to allow the slave port to have a pointer
958713Sandreas.hansson@arm.com    class BridgeMasterPort;
968713Sandreas.hansson@arm.com
978713Sandreas.hansson@arm.com    /**
988713Sandreas.hansson@arm.com     * The port on the side that receives requests and sends
998713Sandreas.hansson@arm.com     * responses. The slave port has a set of address ranges that it
1008713Sandreas.hansson@arm.com     * is responsible for. The slave port also has a buffer for the
1018713Sandreas.hansson@arm.com     * responses not yet sent.
1028713Sandreas.hansson@arm.com     */
1038922Swilliam.wang@arm.com    class BridgeSlavePort : public SlavePort
1042568SN/A    {
1058713Sandreas.hansson@arm.com
1068713Sandreas.hansson@arm.com      private:
1078713Sandreas.hansson@arm.com
1089164Sandreas.hansson@arm.com        /** The bridge to which this port belongs. */
1099164Sandreas.hansson@arm.com        Bridge& bridge;
1102568SN/A
1112643Sstever@eecs.umich.edu        /**
11210405Sandreas.hansson@arm.com         * Master port on the other side of the bridge.
1132643Sstever@eecs.umich.edu         */
1148851Sandreas.hansson@arm.com        BridgeMasterPort& masterPort;
1158713Sandreas.hansson@arm.com
1168713Sandreas.hansson@arm.com        /** Minimum request delay though this bridge. */
1179786Sandreas.hansson@arm.com        const Cycles delay;
1188713Sandreas.hansson@arm.com
1198713Sandreas.hansson@arm.com        /** Address ranges to pass through the bridge */
1209786Sandreas.hansson@arm.com        const AddrRangeList ranges;
1218713Sandreas.hansson@arm.com
1228713Sandreas.hansson@arm.com        /**
1238713Sandreas.hansson@arm.com         * Response packet queue. Response packets are held in this
1248713Sandreas.hansson@arm.com         * queue for a specified delay to model the processing delay
1259786Sandreas.hansson@arm.com         * of the bridge. We use a deque as we need to iterate over
1269786Sandreas.hansson@arm.com         * the items for functional accesses.
1278713Sandreas.hansson@arm.com         */
1289786Sandreas.hansson@arm.com        std::deque<DeferredPacket> transmitList;
1298713Sandreas.hansson@arm.com
1308713Sandreas.hansson@arm.com        /** Counter to track the outstanding responses. */
1318713Sandreas.hansson@arm.com        unsigned int outstandingResponses;
1328713Sandreas.hansson@arm.com
1339164Sandreas.hansson@arm.com        /** If we should send a retry when space becomes available. */
1349164Sandreas.hansson@arm.com        bool retryReq;
1358713Sandreas.hansson@arm.com
1368713Sandreas.hansson@arm.com        /** Max queue size for reserved responses. */
1378713Sandreas.hansson@arm.com        unsigned int respQueueLimit;
1388713Sandreas.hansson@arm.com
1398713Sandreas.hansson@arm.com        /**
14011192Sandreas.hansson@arm.com         * Upstream caches need this packet until true is returned, so
14111192Sandreas.hansson@arm.com         * hold it for deletion until a subsequent call
14211192Sandreas.hansson@arm.com         */
14311192Sandreas.hansson@arm.com        std::unique_ptr<Packet> pendingDelete;
14411192Sandreas.hansson@arm.com
14511192Sandreas.hansson@arm.com        /**
1468713Sandreas.hansson@arm.com         * Is this side blocked from accepting new response packets.
1478713Sandreas.hansson@arm.com         *
1488713Sandreas.hansson@arm.com         * @return true if the reserved space has reached the set limit
1498713Sandreas.hansson@arm.com         */
1509786Sandreas.hansson@arm.com        bool respQueueFull() const;
1518713Sandreas.hansson@arm.com
1528713Sandreas.hansson@arm.com        /**
1538713Sandreas.hansson@arm.com         * Handle send event, scheduled when the packet at the head of
1548713Sandreas.hansson@arm.com         * the response queue is ready to transmit (for timing
1558713Sandreas.hansson@arm.com         * accesses only).
1568713Sandreas.hansson@arm.com         */
1579164Sandreas.hansson@arm.com        void trySendTiming();
1588713Sandreas.hansson@arm.com
1598713Sandreas.hansson@arm.com        /** Send event for the response queue. */
16012084Sspwilson2@wisc.edu        EventFunctionWrapper sendEvent;
1618713Sandreas.hansson@arm.com
1628713Sandreas.hansson@arm.com      public:
1638713Sandreas.hansson@arm.com
1648713Sandreas.hansson@arm.com        /**
1658713Sandreas.hansson@arm.com         * Constructor for the BridgeSlavePort.
1668713Sandreas.hansson@arm.com         *
1678713Sandreas.hansson@arm.com         * @param _name the port name including the owner
1688713Sandreas.hansson@arm.com         * @param _bridge the structural owner
1698713Sandreas.hansson@arm.com         * @param _masterPort the master port on the other side of the bridge
1709180Sandreas.hansson@arm.com         * @param _delay the delay in cycles from receiving to sending
1718713Sandreas.hansson@arm.com         * @param _resp_limit the size of the response queue
1728713Sandreas.hansson@arm.com         * @param _ranges a number of address ranges to forward
1738713Sandreas.hansson@arm.com         */
1749164Sandreas.hansson@arm.com        BridgeSlavePort(const std::string& _name, Bridge& _bridge,
1759180Sandreas.hansson@arm.com                        BridgeMasterPort& _masterPort, Cycles _delay,
1769235Sandreas.hansson@arm.com                        int _resp_limit, std::vector<AddrRange> _ranges);
1778713Sandreas.hansson@arm.com
1788713Sandreas.hansson@arm.com        /**
1798713Sandreas.hansson@arm.com         * Queue a response packet to be sent out later and also schedule
1808713Sandreas.hansson@arm.com         * a send if necessary.
1818713Sandreas.hansson@arm.com         *
1828713Sandreas.hansson@arm.com         * @param pkt a response to send out after a delay
1839164Sandreas.hansson@arm.com         * @param when tick when response packet should be sent
1848713Sandreas.hansson@arm.com         */
1859164Sandreas.hansson@arm.com        void schedTimingResp(PacketPtr pkt, Tick when);
1869164Sandreas.hansson@arm.com
1879164Sandreas.hansson@arm.com        /**
1889164Sandreas.hansson@arm.com         * Retry any stalled request that we have failed to accept at
1899164Sandreas.hansson@arm.com         * an earlier point in time. This call will do nothing if no
1909164Sandreas.hansson@arm.com         * request is waiting.
1919164Sandreas.hansson@arm.com         */
1929164Sandreas.hansson@arm.com        void retryStalledReq();
1938713Sandreas.hansson@arm.com
1948713Sandreas.hansson@arm.com      protected:
1958713Sandreas.hansson@arm.com
1968713Sandreas.hansson@arm.com        /** When receiving a timing request from the peer port,
1978713Sandreas.hansson@arm.com            pass it to the bridge. */
1989164Sandreas.hansson@arm.com        bool recvTimingReq(PacketPtr pkt);
1998713Sandreas.hansson@arm.com
2008713Sandreas.hansson@arm.com        /** When receiving a retry request from the peer port,
2018713Sandreas.hansson@arm.com            pass it to the bridge. */
20210713Sandreas.hansson@arm.com        void recvRespRetry();
2038713Sandreas.hansson@arm.com
2048713Sandreas.hansson@arm.com        /** When receiving a Atomic requestfrom the peer port,
2058713Sandreas.hansson@arm.com            pass it to the bridge. */
2069164Sandreas.hansson@arm.com        Tick recvAtomic(PacketPtr pkt);
2078713Sandreas.hansson@arm.com
2088713Sandreas.hansson@arm.com        /** When receiving a Functional request from the peer port,
2098713Sandreas.hansson@arm.com            pass it to the bridge. */
2109164Sandreas.hansson@arm.com        void recvFunctional(PacketPtr pkt);
2118713Sandreas.hansson@arm.com
2128713Sandreas.hansson@arm.com        /** When receiving a address range request the peer port,
2138713Sandreas.hansson@arm.com            pass it to the bridge. */
2149164Sandreas.hansson@arm.com        AddrRangeList getAddrRanges() const;
2158713Sandreas.hansson@arm.com    };
2168713Sandreas.hansson@arm.com
2178713Sandreas.hansson@arm.com
2188713Sandreas.hansson@arm.com    /**
2198713Sandreas.hansson@arm.com     * Port on the side that forwards requests and receives
2208713Sandreas.hansson@arm.com     * responses. The master port has a buffer for the requests not
2218713Sandreas.hansson@arm.com     * yet sent.
2228713Sandreas.hansson@arm.com     */
2238922Swilliam.wang@arm.com    class BridgeMasterPort : public MasterPort
2248713Sandreas.hansson@arm.com    {
2258713Sandreas.hansson@arm.com
2268713Sandreas.hansson@arm.com      private:
2278713Sandreas.hansson@arm.com
2289164Sandreas.hansson@arm.com        /** The bridge to which this port belongs. */
2299164Sandreas.hansson@arm.com        Bridge& bridge;
2308713Sandreas.hansson@arm.com
2318713Sandreas.hansson@arm.com        /**
23210405Sandreas.hansson@arm.com         * The slave port on the other side of the bridge.
2338713Sandreas.hansson@arm.com         */
2348851Sandreas.hansson@arm.com        BridgeSlavePort& slavePort;
2352643Sstever@eecs.umich.edu
2362643Sstever@eecs.umich.edu        /** Minimum delay though this bridge. */
2379786Sandreas.hansson@arm.com        const Cycles delay;
2382643Sstever@eecs.umich.edu
2398713Sandreas.hansson@arm.com        /**
2408713Sandreas.hansson@arm.com         * Request packet queue. Request packets are held in this
2418713Sandreas.hansson@arm.com         * queue for a specified delay to model the processing delay
2429786Sandreas.hansson@arm.com         * of the bridge.  We use a deque as we need to iterate over
2439786Sandreas.hansson@arm.com         * the items for functional accesses.
2448713Sandreas.hansson@arm.com         */
2459786Sandreas.hansson@arm.com        std::deque<DeferredPacket> transmitList;
2464435Ssaidi@eecs.umich.edu
2478713Sandreas.hansson@arm.com        /** Max queue size for request packets */
2489786Sandreas.hansson@arm.com        const unsigned int reqQueueLimit;
2494433Ssaidi@eecs.umich.edu
2502643Sstever@eecs.umich.edu        /**
2512643Sstever@eecs.umich.edu         * Handle send event, scheduled when the packet at the head of
2522643Sstever@eecs.umich.edu         * the outbound queue is ready to transmit (for timing
2532643Sstever@eecs.umich.edu         * accesses only).
2542643Sstever@eecs.umich.edu         */
2559164Sandreas.hansson@arm.com        void trySendTiming();
2562643Sstever@eecs.umich.edu
2578713Sandreas.hansson@arm.com        /** Send event for the request queue. */
25812084Sspwilson2@wisc.edu        EventFunctionWrapper sendEvent;
2592568SN/A
2602568SN/A      public:
2618713Sandreas.hansson@arm.com
2628713Sandreas.hansson@arm.com        /**
2638713Sandreas.hansson@arm.com         * Constructor for the BridgeMasterPort.
2648713Sandreas.hansson@arm.com         *
2658713Sandreas.hansson@arm.com         * @param _name the port name including the owner
2668713Sandreas.hansson@arm.com         * @param _bridge the structural owner
2678713Sandreas.hansson@arm.com         * @param _slavePort the slave port on the other side of the bridge
2689180Sandreas.hansson@arm.com         * @param _delay the delay in cycles from receiving to sending
2698713Sandreas.hansson@arm.com         * @param _req_limit the size of the request queue
2708713Sandreas.hansson@arm.com         */
2719164Sandreas.hansson@arm.com        BridgeMasterPort(const std::string& _name, Bridge& _bridge,
2729180Sandreas.hansson@arm.com                         BridgeSlavePort& _slavePort, Cycles _delay,
2738713Sandreas.hansson@arm.com                         int _req_limit);
2748713Sandreas.hansson@arm.com
2758713Sandreas.hansson@arm.com        /**
2768713Sandreas.hansson@arm.com         * Is this side blocked from accepting new request packets.
2778713Sandreas.hansson@arm.com         *
2788713Sandreas.hansson@arm.com         * @return true if the occupied space has reached the set limit
2798713Sandreas.hansson@arm.com         */
2809786Sandreas.hansson@arm.com        bool reqQueueFull() const;
2818713Sandreas.hansson@arm.com
2828713Sandreas.hansson@arm.com        /**
2838713Sandreas.hansson@arm.com         * Queue a request packet to be sent out later and also schedule
2848713Sandreas.hansson@arm.com         * a send if necessary.
2858713Sandreas.hansson@arm.com         *
2868713Sandreas.hansson@arm.com         * @param pkt a request to send out after a delay
2879164Sandreas.hansson@arm.com         * @param when tick when response packet should be sent
2888713Sandreas.hansson@arm.com         */
2899164Sandreas.hansson@arm.com        void schedTimingReq(PacketPtr pkt, Tick when);
2908713Sandreas.hansson@arm.com
2918713Sandreas.hansson@arm.com        /**
2928713Sandreas.hansson@arm.com         * Check a functional request against the packets in our
2938713Sandreas.hansson@arm.com         * request queue.
2948713Sandreas.hansson@arm.com         *
2958713Sandreas.hansson@arm.com         * @param pkt packet to check against
2968713Sandreas.hansson@arm.com         *
2978713Sandreas.hansson@arm.com         * @return true if we find a match
2988713Sandreas.hansson@arm.com         */
29912823Srmk35@cl.cam.ac.uk        bool trySatisfyFunctional(PacketPtr pkt);
3002568SN/A
3012568SN/A      protected:
3022568SN/A
3032643Sstever@eecs.umich.edu        /** When receiving a timing request from the peer port,
3042643Sstever@eecs.umich.edu            pass it to the bridge. */
3059164Sandreas.hansson@arm.com        bool recvTimingResp(PacketPtr pkt);
3062568SN/A
3072643Sstever@eecs.umich.edu        /** When receiving a retry request from the peer port,
3082568SN/A            pass it to the bridge. */
30910713Sandreas.hansson@arm.com        void recvReqRetry();
3102568SN/A    };
3112568SN/A
3128713Sandreas.hansson@arm.com    /** Slave port of the bridge. */
3138713Sandreas.hansson@arm.com    BridgeSlavePort slavePort;
3148713Sandreas.hansson@arm.com
3158713Sandreas.hansson@arm.com    /** Master port of the bridge. */
3168713Sandreas.hansson@arm.com    BridgeMasterPort masterPort;
3172568SN/A
3182568SN/A  public:
3192568SN/A
32013784Sgabeblack@google.com    Port &getPort(const std::string &if_name,
32113784Sgabeblack@google.com                  PortID idx=InvalidPortID) override;
3222568SN/A
32313799SAndrea.Mondelli@ucf.edu    void init() override;
3242568SN/A
3259164Sandreas.hansson@arm.com    typedef BridgeParams Params;
3269164Sandreas.hansson@arm.com
3274435Ssaidi@eecs.umich.edu    Bridge(Params *p);
3282568SN/A};
3292568SN/A
33010405Sandreas.hansson@arm.com#endif //__MEM_BRIDGE_HH__
331