port.hh revision 14183
19651SAndreas.Sandberg@ARM.com/*
29651SAndreas.Sandberg@ARM.com * Copyright (c) 2011-2012,2015,2017 ARM Limited
39651SAndreas.Sandberg@ARM.com * All rights reserved
49651SAndreas.Sandberg@ARM.com *
59651SAndreas.Sandberg@ARM.com * The license below extends only to copyright in the software and shall
69651SAndreas.Sandberg@ARM.com * not be construed as granting a license to any other intellectual
79651SAndreas.Sandberg@ARM.com * property including but not limited to intellectual property relating
89651SAndreas.Sandberg@ARM.com * to a hardware implementation of the functionality of the software
99651SAndreas.Sandberg@ARM.com * licensed hereunder.  You may use the software subject to the license
109651SAndreas.Sandberg@ARM.com * terms below provided that you ensure that this notice is replicated
119651SAndreas.Sandberg@ARM.com * unmodified and in its entirety in all distributions of the software,
129651SAndreas.Sandberg@ARM.com * modified or unmodified, in source code or in binary form.
139651SAndreas.Sandberg@ARM.com *
149651SAndreas.Sandberg@ARM.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
159651SAndreas.Sandberg@ARM.com * All rights reserved.
169651SAndreas.Sandberg@ARM.com *
179651SAndreas.Sandberg@ARM.com * Redistribution and use in source and binary forms, with or without
189651SAndreas.Sandberg@ARM.com * modification, are permitted provided that the following conditions are
199651SAndreas.Sandberg@ARM.com * met: redistributions of source code must retain the above copyright
209651SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer;
219651SAndreas.Sandberg@ARM.com * redistributions in binary form must reproduce the above copyright
229651SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer in the
239651SAndreas.Sandberg@ARM.com * documentation and/or other materials provided with the distribution;
249651SAndreas.Sandberg@ARM.com * neither the name of the copyright holders nor the names of its
259651SAndreas.Sandberg@ARM.com * contributors may be used to endorse or promote products derived from
269651SAndreas.Sandberg@ARM.com * this software without specific prior written permission.
279651SAndreas.Sandberg@ARM.com *
289651SAndreas.Sandberg@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
299651SAndreas.Sandberg@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
309651SAndreas.Sandberg@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
319651SAndreas.Sandberg@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
329651SAndreas.Sandberg@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
339651SAndreas.Sandberg@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
349651SAndreas.Sandberg@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
359651SAndreas.Sandberg@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
369651SAndreas.Sandberg@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
379651SAndreas.Sandberg@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
389651SAndreas.Sandberg@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
399651SAndreas.Sandberg@ARM.com *
409651SAndreas.Sandberg@ARM.com * Authors: Ron Dreslinski
419651SAndreas.Sandberg@ARM.com *          Andreas Hansson
429651SAndreas.Sandberg@ARM.com *          William Wang
439651SAndreas.Sandberg@ARM.com */
449651SAndreas.Sandberg@ARM.com
459651SAndreas.Sandberg@ARM.com/**
469651SAndreas.Sandberg@ARM.com * @file
479651SAndreas.Sandberg@ARM.com * Port Object Declaration.
489651SAndreas.Sandberg@ARM.com */
499651SAndreas.Sandberg@ARM.com
509651SAndreas.Sandberg@ARM.com#ifndef __MEM_PORT_HH__
519651SAndreas.Sandberg@ARM.com#define __MEM_PORT_HH__
529651SAndreas.Sandberg@ARM.com
539651SAndreas.Sandberg@ARM.com#include "base/addr_range.hh"
549651SAndreas.Sandberg@ARM.com#include "mem/atomic_protocol.hh"
559651SAndreas.Sandberg@ARM.com#include "mem/functional_protocol.hh"
569651SAndreas.Sandberg@ARM.com#include "mem/packet.hh"
579651SAndreas.Sandberg@ARM.com#include "mem/timing_protocol.hh"
589651SAndreas.Sandberg@ARM.com#include "sim/port.hh"
599651SAndreas.Sandberg@ARM.com
609651SAndreas.Sandberg@ARM.comclass SimObject;
619651SAndreas.Sandberg@ARM.com
629651SAndreas.Sandberg@ARM.com/** Forward declaration */
639651SAndreas.Sandberg@ARM.comclass BaseSlavePort;
649651SAndreas.Sandberg@ARM.com
659651SAndreas.Sandberg@ARM.com/**
669651SAndreas.Sandberg@ARM.com * A BaseMasterPort is a protocol-agnostic master port, responsible
679651SAndreas.Sandberg@ARM.com * only for the structural connection to a slave port. The final
689651SAndreas.Sandberg@ARM.com * master port that inherits from the base class must override the
699651SAndreas.Sandberg@ARM.com * bind member function for the specific slave port class.
709651SAndreas.Sandberg@ARM.com */
719651SAndreas.Sandberg@ARM.comclass BaseMasterPort : public Port
729651SAndreas.Sandberg@ARM.com{
739651SAndreas.Sandberg@ARM.com  protected:
749651SAndreas.Sandberg@ARM.com    BaseSlavePort *_baseSlavePort;
759652SAndreas.Sandberg@ARM.com
769652SAndreas.Sandberg@ARM.com    BaseMasterPort(const std::string &name, PortID id=InvalidPortID);
779651SAndreas.Sandberg@ARM.com    virtual ~BaseMasterPort();
789651SAndreas.Sandberg@ARM.com
799651SAndreas.Sandberg@ARM.com  public:
809651SAndreas.Sandberg@ARM.com    BaseSlavePort& getSlavePort() const;
819651SAndreas.Sandberg@ARM.com};
829651SAndreas.Sandberg@ARM.com
839651SAndreas.Sandberg@ARM.com/**
849651SAndreas.Sandberg@ARM.com * A BaseSlavePort is a protocol-agnostic slave port, responsible
859651SAndreas.Sandberg@ARM.com * only for the structural connection to a master port.
869651SAndreas.Sandberg@ARM.com */
879651SAndreas.Sandberg@ARM.comclass BaseSlavePort : public Port
889651SAndreas.Sandberg@ARM.com{
899651SAndreas.Sandberg@ARM.com  protected:
909651SAndreas.Sandberg@ARM.com    BaseMasterPort *_baseMasterPort;
919651SAndreas.Sandberg@ARM.com
929651SAndreas.Sandberg@ARM.com    BaseSlavePort(const std::string &name, PortID id=InvalidPortID);
939651SAndreas.Sandberg@ARM.com    virtual ~BaseSlavePort();
949651SAndreas.Sandberg@ARM.com
959651SAndreas.Sandberg@ARM.com  public:
969651SAndreas.Sandberg@ARM.com    BaseMasterPort& getMasterPort() const;
979651SAndreas.Sandberg@ARM.com};
989651SAndreas.Sandberg@ARM.com
999651SAndreas.Sandberg@ARM.com/** Forward declaration */
1009651SAndreas.Sandberg@ARM.comclass SlavePort;
1019651SAndreas.Sandberg@ARM.com
1029651SAndreas.Sandberg@ARM.com/**
1039651SAndreas.Sandberg@ARM.com * A MasterPort is a specialisation of a BaseMasterPort, which
1049651SAndreas.Sandberg@ARM.com * implements the default protocol for the three different level of
1059651SAndreas.Sandberg@ARM.com * transport functions. In addition to the basic functionality of
1069651SAndreas.Sandberg@ARM.com * sending packets, it also has functions to receive range changes or
1079651SAndreas.Sandberg@ARM.com * determine if the port is snooping or not.
1089651SAndreas.Sandberg@ARM.com *
1099651SAndreas.Sandberg@ARM.com * The three protocols are atomic, timing, and functional, each with its own
1109651SAndreas.Sandberg@ARM.com * header file.
1119651SAndreas.Sandberg@ARM.com */
1129651SAndreas.Sandberg@ARM.comclass MasterPort : public BaseMasterPort, public AtomicRequestProtocol,
1139651SAndreas.Sandberg@ARM.com    public TimingRequestProtocol, public FunctionalRequestProtocol
1149651SAndreas.Sandberg@ARM.com{
1159651SAndreas.Sandberg@ARM.com    friend class SlavePort;
1169651SAndreas.Sandberg@ARM.com
1179651SAndreas.Sandberg@ARM.com  private:
1189651SAndreas.Sandberg@ARM.com    SlavePort *_slavePort;
1199651SAndreas.Sandberg@ARM.com
1209651SAndreas.Sandberg@ARM.com  protected:
1219651SAndreas.Sandberg@ARM.com    SimObject &owner;
1229651SAndreas.Sandberg@ARM.com
1239651SAndreas.Sandberg@ARM.com  public:
1249651SAndreas.Sandberg@ARM.com    MasterPort(const std::string& name, SimObject* _owner,
1259651SAndreas.Sandberg@ARM.com               PortID id=InvalidPortID);
1269651SAndreas.Sandberg@ARM.com    virtual ~MasterPort();
1279651SAndreas.Sandberg@ARM.com
1289651SAndreas.Sandberg@ARM.com    /**
1299651SAndreas.Sandberg@ARM.com     * Bind this master port to a slave port. This also does the
1309651SAndreas.Sandberg@ARM.com     * mirror action and binds the slave port to the master port.
1319651SAndreas.Sandberg@ARM.com     */
1329651SAndreas.Sandberg@ARM.com    void bind(Port &peer) override;
1339651SAndreas.Sandberg@ARM.com
1349651SAndreas.Sandberg@ARM.com    /**
1359651SAndreas.Sandberg@ARM.com     * Unbind this master port and the associated slave port.
1369651SAndreas.Sandberg@ARM.com     */
1379651SAndreas.Sandberg@ARM.com    void unbind() override;
1389651SAndreas.Sandberg@ARM.com
1399651SAndreas.Sandberg@ARM.com    /**
1409651SAndreas.Sandberg@ARM.com     * Determine if this master port is snooping or not. The default
1419651SAndreas.Sandberg@ARM.com     * implementation returns false and thus tells the neighbour we
1429651SAndreas.Sandberg@ARM.com     * are not snooping. Any master port that wants to receive snoop
1439651SAndreas.Sandberg@ARM.com     * requests (e.g. a cache connected to a bus) has to override this
1449651SAndreas.Sandberg@ARM.com     * function.
1459651SAndreas.Sandberg@ARM.com     *
1469651SAndreas.Sandberg@ARM.com     * @return true if the port should be considered a snooper
1479651SAndreas.Sandberg@ARM.com     */
1489651SAndreas.Sandberg@ARM.com    virtual bool isSnooping() const { return false; }
1499651SAndreas.Sandberg@ARM.com
1509651SAndreas.Sandberg@ARM.com    /**
1519651SAndreas.Sandberg@ARM.com     * Get the address ranges of the connected slave port.
1529651SAndreas.Sandberg@ARM.com     */
1539651SAndreas.Sandberg@ARM.com    AddrRangeList getAddrRanges() const;
1549651SAndreas.Sandberg@ARM.com
1559651SAndreas.Sandberg@ARM.com    /**
1569651SAndreas.Sandberg@ARM.com     * Inject a PrintReq for the given address to print the state of
1579651SAndreas.Sandberg@ARM.com     * that address throughout the memory system.  For debugging.
1589651SAndreas.Sandberg@ARM.com     */
1599651SAndreas.Sandberg@ARM.com    void printAddr(Addr a);
1609651SAndreas.Sandberg@ARM.com
1619651SAndreas.Sandberg@ARM.com  public:
1629651SAndreas.Sandberg@ARM.com    /* The atomic protocol. */
1639651SAndreas.Sandberg@ARM.com
1649651SAndreas.Sandberg@ARM.com    /**
1659651SAndreas.Sandberg@ARM.com     * Send an atomic request packet, where the data is moved and the
1669651SAndreas.Sandberg@ARM.com     * state is updated in zero time, without interleaving with other
1679651SAndreas.Sandberg@ARM.com     * memory accesses.
1689651SAndreas.Sandberg@ARM.com     *
1699651SAndreas.Sandberg@ARM.com     * @param pkt Packet to send.
1709651SAndreas.Sandberg@ARM.com     *
1719651SAndreas.Sandberg@ARM.com     * @return Estimated latency of access.
1729651SAndreas.Sandberg@ARM.com     */
1739651SAndreas.Sandberg@ARM.com    Tick sendAtomic(PacketPtr pkt);
1749651SAndreas.Sandberg@ARM.com
1759651SAndreas.Sandberg@ARM.com    /**
1769651SAndreas.Sandberg@ARM.com     * Send an atomic request packet like above, but also request a backdoor
1779651SAndreas.Sandberg@ARM.com     * to the data being accessed.
1789651SAndreas.Sandberg@ARM.com     *
1799651SAndreas.Sandberg@ARM.com     * @param pkt Packet to send.
1809651SAndreas.Sandberg@ARM.com     * @param backdoor Can be set to a back door pointer by the target to let
1819651SAndreas.Sandberg@ARM.com     *        caller have direct access to the requested data.
1829651SAndreas.Sandberg@ARM.com     *
1839651SAndreas.Sandberg@ARM.com     * @return Estimated latency of access.
1849651SAndreas.Sandberg@ARM.com     */
1859651SAndreas.Sandberg@ARM.com    Tick sendAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor);
1869651SAndreas.Sandberg@ARM.com
1879651SAndreas.Sandberg@ARM.com  public:
1889651SAndreas.Sandberg@ARM.com    /* The functional protocol. */
1899651SAndreas.Sandberg@ARM.com
1909651SAndreas.Sandberg@ARM.com    /**
1919651SAndreas.Sandberg@ARM.com     * Send a functional request packet, where the data is instantly
1929651SAndreas.Sandberg@ARM.com     * updated everywhere in the memory system, without affecting the
1939651SAndreas.Sandberg@ARM.com     * current state of any block or moving the block.
1949651SAndreas.Sandberg@ARM.com     *
1959651SAndreas.Sandberg@ARM.com     * @param pkt Packet to send.
1969651SAndreas.Sandberg@ARM.com     */
1979651SAndreas.Sandberg@ARM.com    void sendFunctional(PacketPtr pkt) const;
1989651SAndreas.Sandberg@ARM.com
1999651SAndreas.Sandberg@ARM.com  public:
2009651SAndreas.Sandberg@ARM.com    /* The timing protocol. */
2019651SAndreas.Sandberg@ARM.com
2029651SAndreas.Sandberg@ARM.com    /**
2039651SAndreas.Sandberg@ARM.com     * Attempt to send a timing request to the slave port by calling
2049651SAndreas.Sandberg@ARM.com     * its corresponding receive function. If the send does not
2059651SAndreas.Sandberg@ARM.com     * succeed, as indicated by the return value, then the sender must
2069651SAndreas.Sandberg@ARM.com     * wait for a recvReqRetry at which point it can re-issue a
2079651SAndreas.Sandberg@ARM.com     * sendTimingReq.
2089651SAndreas.Sandberg@ARM.com     *
2099652SAndreas.Sandberg@ARM.com     * @param pkt Packet to send.
2109652SAndreas.Sandberg@ARM.com     *
2119652SAndreas.Sandberg@ARM.com     * @return If the send was succesful or not.
2129651SAndreas.Sandberg@ARM.com    */
2139651SAndreas.Sandberg@ARM.com    bool sendTimingReq(PacketPtr pkt);
2149651SAndreas.Sandberg@ARM.com
2159651SAndreas.Sandberg@ARM.com    /**
2169651SAndreas.Sandberg@ARM.com     * Check if the slave can handle a timing request.
2179651SAndreas.Sandberg@ARM.com     *
2189651SAndreas.Sandberg@ARM.com     * If the send cannot be handled at the moment, as indicated by
2199651SAndreas.Sandberg@ARM.com     * the return value, then the sender will receive a recvReqRetry
2209651SAndreas.Sandberg@ARM.com     * at which point it can re-issue a sendTimingReq.
2219651SAndreas.Sandberg@ARM.com     *
2229651SAndreas.Sandberg@ARM.com     * @param pkt Packet to send.
2239651SAndreas.Sandberg@ARM.com     *
2249652SAndreas.Sandberg@ARM.com     * @return If the send was succesful or not.
2259651SAndreas.Sandberg@ARM.com     */
2269651SAndreas.Sandberg@ARM.com    bool tryTiming(PacketPtr pkt) const;
2279651SAndreas.Sandberg@ARM.com
2289651SAndreas.Sandberg@ARM.com    /**
2299651SAndreas.Sandberg@ARM.com     * Attempt to send a timing snoop response packet to the slave
2309651SAndreas.Sandberg@ARM.com     * port by calling its corresponding receive function. If the send
2319651SAndreas.Sandberg@ARM.com     * does not succeed, as indicated by the return value, then the
2329651SAndreas.Sandberg@ARM.com     * sender must wait for a recvRetrySnoop at which point it can
2339651SAndreas.Sandberg@ARM.com     * re-issue a sendTimingSnoopResp.
2349651SAndreas.Sandberg@ARM.com     *
2359651SAndreas.Sandberg@ARM.com     * @param pkt Packet to send.
2369651SAndreas.Sandberg@ARM.com     */
2379651SAndreas.Sandberg@ARM.com    bool sendTimingSnoopResp(PacketPtr pkt);
2389651SAndreas.Sandberg@ARM.com
2399651SAndreas.Sandberg@ARM.com    /**
2409651SAndreas.Sandberg@ARM.com     * Send a retry to the slave port that previously attempted a
2419651SAndreas.Sandberg@ARM.com     * sendTimingResp to this master port and failed. Note that this
2429651SAndreas.Sandberg@ARM.com     * is virtual so that the "fake" snoop response port in the
2439651SAndreas.Sandberg@ARM.com     * coherent crossbar can override the behaviour.
2449651SAndreas.Sandberg@ARM.com     */
2459651SAndreas.Sandberg@ARM.com    virtual void sendRetryResp();
2469651SAndreas.Sandberg@ARM.com
2479651SAndreas.Sandberg@ARM.com  protected:
2489651SAndreas.Sandberg@ARM.com    /**
2499651SAndreas.Sandberg@ARM.com     * Called to receive an address range change from the peer slave
2509651SAndreas.Sandberg@ARM.com     * port. The default implementation ignores the change and does
2519651SAndreas.Sandberg@ARM.com     * nothing. Override this function in a derived class if the owner
2529651SAndreas.Sandberg@ARM.com     * needs to be aware of the address ranges, e.g. in an
2539651SAndreas.Sandberg@ARM.com     * interconnect component like a bus.
2549651SAndreas.Sandberg@ARM.com     */
2559651SAndreas.Sandberg@ARM.com    virtual void recvRangeChange() { }
2569651SAndreas.Sandberg@ARM.com
2579651SAndreas.Sandberg@ARM.com    /**
2589651SAndreas.Sandberg@ARM.com     * Default implementations.
2599651SAndreas.Sandberg@ARM.com     */
2609651SAndreas.Sandberg@ARM.com    Tick
2619651SAndreas.Sandberg@ARM.com    recvAtomicSnoop(PacketPtr pkt) override
2629651SAndreas.Sandberg@ARM.com    {
2639651SAndreas.Sandberg@ARM.com        panic("%s was not expecting an atomic snoop request\n", name());
2649651SAndreas.Sandberg@ARM.com        return 0;
2659651SAndreas.Sandberg@ARM.com    }
2669651SAndreas.Sandberg@ARM.com
2679651SAndreas.Sandberg@ARM.com    void
2689651SAndreas.Sandberg@ARM.com    recvFunctionalSnoop(PacketPtr pkt) override
2699651SAndreas.Sandberg@ARM.com    {
2709652SAndreas.Sandberg@ARM.com        panic("%s was not expecting a functional snoop request\n", name());
2719652SAndreas.Sandberg@ARM.com    }
2729652SAndreas.Sandberg@ARM.com
2739652SAndreas.Sandberg@ARM.com    void
2749652SAndreas.Sandberg@ARM.com    recvTimingSnoopReq(PacketPtr pkt) override
2759652SAndreas.Sandberg@ARM.com    {
2769651SAndreas.Sandberg@ARM.com        panic("%s was not expecting a timing snoop request.\n", name());
2779651SAndreas.Sandberg@ARM.com    }
2789651SAndreas.Sandberg@ARM.com
2799651SAndreas.Sandberg@ARM.com    void
2809651SAndreas.Sandberg@ARM.com    recvRetrySnoopResp() override
2819651SAndreas.Sandberg@ARM.com    {
2829651SAndreas.Sandberg@ARM.com        panic("%s was not expecting a snoop retry.\n", name());
2839651SAndreas.Sandberg@ARM.com    }
2849651SAndreas.Sandberg@ARM.com};
2859651SAndreas.Sandberg@ARM.com
2869651SAndreas.Sandberg@ARM.com/**
2879651SAndreas.Sandberg@ARM.com * A SlavePort is a specialisation of a port. In addition to the
2889651SAndreas.Sandberg@ARM.com * basic functionality of sending packets to its master peer, it also
2899651SAndreas.Sandberg@ARM.com * has functions specific to a slave, e.g. to send range changes
2909651SAndreas.Sandberg@ARM.com * and get the address ranges that the port responds to.
2919651SAndreas.Sandberg@ARM.com *
2929651SAndreas.Sandberg@ARM.com * The three protocols are atomic, timing, and functional, each with its own
2939651SAndreas.Sandberg@ARM.com * header file.
2949651SAndreas.Sandberg@ARM.com */
2959651SAndreas.Sandberg@ARM.comclass SlavePort : public BaseSlavePort, public AtomicResponseProtocol,
2969651SAndreas.Sandberg@ARM.com    public TimingResponseProtocol, public FunctionalResponseProtocol
2979651SAndreas.Sandberg@ARM.com{
2989651SAndreas.Sandberg@ARM.com    friend class MasterPort;
2999652SAndreas.Sandberg@ARM.com
3009652SAndreas.Sandberg@ARM.com  private:
3019652SAndreas.Sandberg@ARM.com    MasterPort* _masterPort;
3029651SAndreas.Sandberg@ARM.com    bool defaultBackdoorWarned;
3039651SAndreas.Sandberg@ARM.com
3049651SAndreas.Sandberg@ARM.com  protected:
3059651SAndreas.Sandberg@ARM.com    SimObject& owner;
3069651SAndreas.Sandberg@ARM.com
3079651SAndreas.Sandberg@ARM.com  public:
3089651SAndreas.Sandberg@ARM.com    SlavePort(const std::string& name, SimObject* _owner,
3099651SAndreas.Sandberg@ARM.com              PortID id=InvalidPortID);
3109651SAndreas.Sandberg@ARM.com    virtual ~SlavePort();
3119651SAndreas.Sandberg@ARM.com
3129651SAndreas.Sandberg@ARM.com    /**
3139651SAndreas.Sandberg@ARM.com     * Find out if the peer master port is snooping or not.
3149651SAndreas.Sandberg@ARM.com     *
3159651SAndreas.Sandberg@ARM.com     * @return true if the peer master port is snooping
3169651SAndreas.Sandberg@ARM.com     */
3179651SAndreas.Sandberg@ARM.com    bool isSnooping() const { return _masterPort->isSnooping(); }
3189651SAndreas.Sandberg@ARM.com
3199651SAndreas.Sandberg@ARM.com    /**
3209651SAndreas.Sandberg@ARM.com     * Called by the owner to send a range change
3219651SAndreas.Sandberg@ARM.com     */
3229651SAndreas.Sandberg@ARM.com    void
3239651SAndreas.Sandberg@ARM.com    sendRangeChange() const
3249651SAndreas.Sandberg@ARM.com    {
3259651SAndreas.Sandberg@ARM.com        fatal_if(!_masterPort,
3269651SAndreas.Sandberg@ARM.com                "%s cannot sendRangeChange() without master port.", name());
3279651SAndreas.Sandberg@ARM.com        _masterPort->recvRangeChange();
3289651SAndreas.Sandberg@ARM.com    }
3299651SAndreas.Sandberg@ARM.com
3309651SAndreas.Sandberg@ARM.com    /**
3319651SAndreas.Sandberg@ARM.com     * Get a list of the non-overlapping address ranges the owner is
3329651SAndreas.Sandberg@ARM.com     * responsible for. All slave ports must override this function
3339651SAndreas.Sandberg@ARM.com     * and return a populated list with at least one item.
3349651SAndreas.Sandberg@ARM.com     *
3359651SAndreas.Sandberg@ARM.com     * @return a list of ranges responded to
3369651SAndreas.Sandberg@ARM.com     */
3379651SAndreas.Sandberg@ARM.com    virtual AddrRangeList getAddrRanges() const = 0;
3389651SAndreas.Sandberg@ARM.com
3399651SAndreas.Sandberg@ARM.com    /**
3409651SAndreas.Sandberg@ARM.com     * We let the master port do the work, so these don't do anything.
3419651SAndreas.Sandberg@ARM.com     */
3429651SAndreas.Sandberg@ARM.com    void unbind() override {}
3439651SAndreas.Sandberg@ARM.com    void bind(Port &peer) override {}
3449651SAndreas.Sandberg@ARM.com
3459651SAndreas.Sandberg@ARM.com  public:
3469651SAndreas.Sandberg@ARM.com    /* The atomic protocol. */
3479651SAndreas.Sandberg@ARM.com
3489651SAndreas.Sandberg@ARM.com    /**
3499651SAndreas.Sandberg@ARM.com     * Send an atomic snoop request packet, where the data is moved
3509651SAndreas.Sandberg@ARM.com     * and the state is updated in zero time, without interleaving
3519651SAndreas.Sandberg@ARM.com     * with other memory accesses.
3529651SAndreas.Sandberg@ARM.com     *
3539651SAndreas.Sandberg@ARM.com     * @param pkt Snoop packet to send.
3549651SAndreas.Sandberg@ARM.com     *
3559651SAndreas.Sandberg@ARM.com     * @return Estimated latency of access.
3569651SAndreas.Sandberg@ARM.com     */
3579651SAndreas.Sandberg@ARM.com    Tick
3589651SAndreas.Sandberg@ARM.com    sendAtomicSnoop(PacketPtr pkt)
3599651SAndreas.Sandberg@ARM.com    {
3609651SAndreas.Sandberg@ARM.com        return AtomicResponseProtocol::sendSnoop(_masterPort, pkt);
3619651SAndreas.Sandberg@ARM.com    }
3629651SAndreas.Sandberg@ARM.com
3639651SAndreas.Sandberg@ARM.com  public:
3649651SAndreas.Sandberg@ARM.com    /* The functional protocol. */
3659651SAndreas.Sandberg@ARM.com
3669651SAndreas.Sandberg@ARM.com    /**
3679651SAndreas.Sandberg@ARM.com     * Send a functional snoop request packet, where the data is
3689651SAndreas.Sandberg@ARM.com     * instantly updated everywhere in the memory system, without
3699651SAndreas.Sandberg@ARM.com     * affecting the current state of any block or moving the block.
3709651SAndreas.Sandberg@ARM.com     *
3719651SAndreas.Sandberg@ARM.com     * @param pkt Snoop packet to send.
3729651SAndreas.Sandberg@ARM.com     */
3739651SAndreas.Sandberg@ARM.com    void
3749651SAndreas.Sandberg@ARM.com    sendFunctionalSnoop(PacketPtr pkt) const
3759651SAndreas.Sandberg@ARM.com    {
3769651SAndreas.Sandberg@ARM.com        FunctionalResponseProtocol::sendSnoop(_masterPort, pkt);
3779651SAndreas.Sandberg@ARM.com    }
3789651SAndreas.Sandberg@ARM.com
3799651SAndreas.Sandberg@ARM.com  public:
3809652SAndreas.Sandberg@ARM.com    /* The timing protocol. */
3819652SAndreas.Sandberg@ARM.com
3829652SAndreas.Sandberg@ARM.com    /**
3839652SAndreas.Sandberg@ARM.com     * Attempt to send a timing response to the master port by calling
3849652SAndreas.Sandberg@ARM.com     * its corresponding receive function. If the send does not
3859652SAndreas.Sandberg@ARM.com     * succeed, as indicated by the return value, then the sender must
3869652SAndreas.Sandberg@ARM.com     * wait for a recvRespRetry at which point it can re-issue a
3879652SAndreas.Sandberg@ARM.com     * sendTimingResp.
3889652SAndreas.Sandberg@ARM.com     *
3899651SAndreas.Sandberg@ARM.com     * @param pkt Packet to send.
3909651SAndreas.Sandberg@ARM.com     *
3919651SAndreas.Sandberg@ARM.com     * @return If the send was succesful or not.
3929651SAndreas.Sandberg@ARM.com    */
3939651SAndreas.Sandberg@ARM.com    bool
3949651SAndreas.Sandberg@ARM.com    sendTimingResp(PacketPtr pkt)
3959651SAndreas.Sandberg@ARM.com    {
3969651SAndreas.Sandberg@ARM.com        return TimingResponseProtocol::sendResp(_masterPort, pkt);
3979651SAndreas.Sandberg@ARM.com    }
3989651SAndreas.Sandberg@ARM.com
3999651SAndreas.Sandberg@ARM.com    /**
4009651SAndreas.Sandberg@ARM.com     * Attempt to send a timing snoop request packet to the master port
4019651SAndreas.Sandberg@ARM.com     * by calling its corresponding receive function. Snoop requests
4029651SAndreas.Sandberg@ARM.com     * always succeed and hence no return value is needed.
4039651SAndreas.Sandberg@ARM.com     *
4049651SAndreas.Sandberg@ARM.com     * @param pkt Packet to send.
4059651SAndreas.Sandberg@ARM.com     */
4069651SAndreas.Sandberg@ARM.com    void
4079651SAndreas.Sandberg@ARM.com    sendTimingSnoopReq(PacketPtr pkt)
4089651SAndreas.Sandberg@ARM.com    {
4099651SAndreas.Sandberg@ARM.com        TimingResponseProtocol::sendSnoopReq(_masterPort, pkt);
4109651SAndreas.Sandberg@ARM.com    }
4119651SAndreas.Sandberg@ARM.com
4129651SAndreas.Sandberg@ARM.com    /**
4139651SAndreas.Sandberg@ARM.com     * Send a retry to the master port that previously attempted a
4149651SAndreas.Sandberg@ARM.com     * sendTimingReq to this slave port and failed.
4159651SAndreas.Sandberg@ARM.com     */
4169651SAndreas.Sandberg@ARM.com    void
4179651SAndreas.Sandberg@ARM.com    sendRetryReq()
4189651SAndreas.Sandberg@ARM.com    {
4199651SAndreas.Sandberg@ARM.com        TimingResponseProtocol::sendRetryReq(_masterPort);
4209651SAndreas.Sandberg@ARM.com    }
4219651SAndreas.Sandberg@ARM.com
4229651SAndreas.Sandberg@ARM.com    /**
4239651SAndreas.Sandberg@ARM.com     * Send a retry to the master port that previously attempted a
4249651SAndreas.Sandberg@ARM.com     * sendTimingSnoopResp to this slave port and failed.
4259651SAndreas.Sandberg@ARM.com     */
4269651SAndreas.Sandberg@ARM.com    void
4279651SAndreas.Sandberg@ARM.com    sendRetrySnoopResp()
4289651SAndreas.Sandberg@ARM.com    {
4299651SAndreas.Sandberg@ARM.com        TimingResponseProtocol::sendRetrySnoopResp(_masterPort);
4309651SAndreas.Sandberg@ARM.com    }
4319651SAndreas.Sandberg@ARM.com
4329651SAndreas.Sandberg@ARM.com  protected:
4339651SAndreas.Sandberg@ARM.com    /**
4349651SAndreas.Sandberg@ARM.com     * Called by the master port to unbind. Should never be called
4359651SAndreas.Sandberg@ARM.com     * directly.
4369651SAndreas.Sandberg@ARM.com     */
4379651SAndreas.Sandberg@ARM.com    void slaveUnbind();
4389652SAndreas.Sandberg@ARM.com
4399652SAndreas.Sandberg@ARM.com    /**
4409652SAndreas.Sandberg@ARM.com     * Called by the master port to bind. Should never be called
4419652SAndreas.Sandberg@ARM.com     * directly.
4429652SAndreas.Sandberg@ARM.com     */
4439652SAndreas.Sandberg@ARM.com    void slaveBind(MasterPort& master_port);
4449652SAndreas.Sandberg@ARM.com
4459651SAndreas.Sandberg@ARM.com    /**
4469651SAndreas.Sandberg@ARM.com     * Default implementations.
4479651SAndreas.Sandberg@ARM.com     */
4489651SAndreas.Sandberg@ARM.com    Tick recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor) override;
4499651SAndreas.Sandberg@ARM.com
4509651SAndreas.Sandberg@ARM.com    bool
4519651SAndreas.Sandberg@ARM.com    tryTiming(PacketPtr pkt) override
4529651SAndreas.Sandberg@ARM.com    {
4539651SAndreas.Sandberg@ARM.com        panic("%s was not expecting a %s\n", name(), __func__);
4549651SAndreas.Sandberg@ARM.com    }
4559651SAndreas.Sandberg@ARM.com
4569651SAndreas.Sandberg@ARM.com    bool
4579651SAndreas.Sandberg@ARM.com    recvTimingSnoopResp(PacketPtr pkt) override
4589651SAndreas.Sandberg@ARM.com    {
4599651SAndreas.Sandberg@ARM.com        panic("%s was not expecting a timing snoop response\n", name());
4609651SAndreas.Sandberg@ARM.com    }
4619651SAndreas.Sandberg@ARM.com};
4629651SAndreas.Sandberg@ARM.com
4639651SAndreas.Sandberg@ARM.cominline Tick
4649651SAndreas.Sandberg@ARM.comMasterPort::sendAtomic(PacketPtr pkt)
4659651SAndreas.Sandberg@ARM.com{
4669651SAndreas.Sandberg@ARM.com    return AtomicRequestProtocol::send(_slavePort, pkt);
4679651SAndreas.Sandberg@ARM.com}
4689651SAndreas.Sandberg@ARM.com
4699651SAndreas.Sandberg@ARM.cominline Tick
4709651SAndreas.Sandberg@ARM.comMasterPort::sendAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor)
4719651SAndreas.Sandberg@ARM.com{
4729651SAndreas.Sandberg@ARM.com    return AtomicRequestProtocol::sendBackdoor(_slavePort, pkt, backdoor);
4739651SAndreas.Sandberg@ARM.com}
4749651SAndreas.Sandberg@ARM.com
4759651SAndreas.Sandberg@ARM.cominline void
4769651SAndreas.Sandberg@ARM.comMasterPort::sendFunctional(PacketPtr pkt) const
4779651SAndreas.Sandberg@ARM.com{
4789651SAndreas.Sandberg@ARM.com    return FunctionalRequestProtocol::send(_slavePort, pkt);
4799651SAndreas.Sandberg@ARM.com}
4809651SAndreas.Sandberg@ARM.com
4819651SAndreas.Sandberg@ARM.cominline bool
4829651SAndreas.Sandberg@ARM.comMasterPort::sendTimingReq(PacketPtr pkt)
4839651SAndreas.Sandberg@ARM.com{
4849651SAndreas.Sandberg@ARM.com    return TimingRequestProtocol::sendReq(_slavePort, pkt);
4859651SAndreas.Sandberg@ARM.com}
4869651SAndreas.Sandberg@ARM.com
4879651SAndreas.Sandberg@ARM.cominline bool
4889651SAndreas.Sandberg@ARM.comMasterPort::tryTiming(PacketPtr pkt) const
4899651SAndreas.Sandberg@ARM.com{
4909651SAndreas.Sandberg@ARM.com    return TimingRequestProtocol::trySend(_slavePort, pkt);
4919651SAndreas.Sandberg@ARM.com}
4929651SAndreas.Sandberg@ARM.com
4939651SAndreas.Sandberg@ARM.cominline bool
4949651SAndreas.Sandberg@ARM.comMasterPort::sendTimingSnoopResp(PacketPtr pkt)
4959651SAndreas.Sandberg@ARM.com{
4969651SAndreas.Sandberg@ARM.com    return TimingRequestProtocol::sendSnoopResp(_slavePort, pkt);
4979651SAndreas.Sandberg@ARM.com}
4989651SAndreas.Sandberg@ARM.com
4999651SAndreas.Sandberg@ARM.cominline void
5009651SAndreas.Sandberg@ARM.comMasterPort::sendRetryResp()
5019651SAndreas.Sandberg@ARM.com{
5029651SAndreas.Sandberg@ARM.com    TimingRequestProtocol::sendRetryResp(_slavePort);
5039651SAndreas.Sandberg@ARM.com}
5049651SAndreas.Sandberg@ARM.com
5059651SAndreas.Sandberg@ARM.com#endif //__MEM_PORT_HH__
5069651SAndreas.Sandberg@ARM.com