port.hh revision 12342
19651SAndreas.Sandberg@ARM.com/* 210858Sandreas.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 * 4011793Sbrandon.potter@amd.com * Authors: Ron Dreslinski 4111793Sbrandon.potter@amd.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__ 519760Sandreas@sandberg.pp.se#define __MEM_PORT_HH__ 529651SAndreas.Sandberg@ARM.com 539683Sandreas@sandberg.pp.se#include "base/addr_range.hh" 549753Sandreas@sandberg.pp.se#include "mem/packet.hh" 559651SAndreas.Sandberg@ARM.com 569651SAndreas.Sandberg@ARM.comclass MemObject; 579651SAndreas.Sandberg@ARM.com 589651SAndreas.Sandberg@ARM.com/** 599651SAndreas.Sandberg@ARM.com * Ports are used to interface memory objects to each other. A port is 609651SAndreas.Sandberg@ARM.com * either a master or a slave and the connected peer is always of the 619651SAndreas.Sandberg@ARM.com * opposite role. Each port has a name, an owner, and an identifier. 629651SAndreas.Sandberg@ARM.com */ 639651SAndreas.Sandberg@ARM.comclass Port 649651SAndreas.Sandberg@ARM.com{ 659651SAndreas.Sandberg@ARM.com 669651SAndreas.Sandberg@ARM.com private: 6711839SCurtis.Dunham@arm.com 689651SAndreas.Sandberg@ARM.com /** Descriptive name (for DPRINTF output) */ 699651SAndreas.Sandberg@ARM.com std::string portName; 709651SAndreas.Sandberg@ARM.com 7111399Sandreas.sandberg@arm.com protected: 729652SAndreas.Sandberg@ARM.com 739652SAndreas.Sandberg@ARM.com /** 749651SAndreas.Sandberg@ARM.com * A numeric identifier to distinguish ports in a vector, and set 759651SAndreas.Sandberg@ARM.com * to InvalidPortID in case this port is not part of a vector. 769651SAndreas.Sandberg@ARM.com */ 779651SAndreas.Sandberg@ARM.com const PortID id; 789892Sandreas@sandberg.pp.se 799655SAndreas.Sandberg@ARM.com /** A reference to the MemObject that owns this port. */ 809752Sandreas@sandberg.pp.se MemObject& owner; 819752Sandreas@sandberg.pp.se 829651SAndreas.Sandberg@ARM.com /** 839651SAndreas.Sandberg@ARM.com * Abstract base class for ports 849651SAndreas.Sandberg@ARM.com * 859651SAndreas.Sandberg@ARM.com * @param _name Port name including the owners name 869651SAndreas.Sandberg@ARM.com * @param _owner The MemObject that is the structural owner of this port 8710553Salexandru.dutu@amd.com * @param _id A port identifier for vector ports 8810553Salexandru.dutu@amd.com */ 8910553Salexandru.dutu@amd.com Port(const std::string& _name, MemObject& _owner, PortID _id); 9010553Salexandru.dutu@amd.com 9110553Salexandru.dutu@amd.com /** 9210553Salexandru.dutu@amd.com * Virtual destructor due to inheritance. 9310553Salexandru.dutu@amd.com */ 9410553Salexandru.dutu@amd.com virtual ~Port(); 959651SAndreas.Sandberg@ARM.com 969651SAndreas.Sandberg@ARM.com public: 979651SAndreas.Sandberg@ARM.com 989651SAndreas.Sandberg@ARM.com /** Return port name (for DPRINTF). */ 999651SAndreas.Sandberg@ARM.com const std::string name() const { return portName; } 1009651SAndreas.Sandberg@ARM.com 1019651SAndreas.Sandberg@ARM.com /** Get the port id. */ 1029651SAndreas.Sandberg@ARM.com PortID getId() const { return id; } 1039651SAndreas.Sandberg@ARM.com 1049651SAndreas.Sandberg@ARM.com}; 1059651SAndreas.Sandberg@ARM.com 1069651SAndreas.Sandberg@ARM.com/** Forward declaration */ 1079651SAndreas.Sandberg@ARM.comclass BaseSlavePort; 1089651SAndreas.Sandberg@ARM.com 1099651SAndreas.Sandberg@ARM.com/** 1109651SAndreas.Sandberg@ARM.com * A BaseMasterPort is a protocol-agnostic master port, responsible 1119651SAndreas.Sandberg@ARM.com * only for the structural connection to a slave port. The final 1129651SAndreas.Sandberg@ARM.com * master port that inherits from the base class must override the 1139651SAndreas.Sandberg@ARM.com * bind member function for the specific slave port class. 1149651SAndreas.Sandberg@ARM.com */ 1159651SAndreas.Sandberg@ARM.comclass BaseMasterPort : public Port 1169651SAndreas.Sandberg@ARM.com{ 1179651SAndreas.Sandberg@ARM.com 1189651SAndreas.Sandberg@ARM.com protected: 1199651SAndreas.Sandberg@ARM.com 1209651SAndreas.Sandberg@ARM.com BaseSlavePort* _baseSlavePort; 1219651SAndreas.Sandberg@ARM.com 1229651SAndreas.Sandberg@ARM.com BaseMasterPort(const std::string& name, MemObject* owner, 1239651SAndreas.Sandberg@ARM.com PortID id = InvalidPortID); 1249651SAndreas.Sandberg@ARM.com virtual ~BaseMasterPort(); 1259690Sandreas@sandberg.pp.se 1269690Sandreas@sandberg.pp.se public: 1279690Sandreas@sandberg.pp.se 12811363Sandreas@sandberg.pp.se virtual void bind(BaseSlavePort& slave_port) = 0; 1299651SAndreas.Sandberg@ARM.com virtual void unbind() = 0; 1309651SAndreas.Sandberg@ARM.com BaseSlavePort& getSlavePort() const; 1319651SAndreas.Sandberg@ARM.com bool isConnected() const; 1329651SAndreas.Sandberg@ARM.com 1339651SAndreas.Sandberg@ARM.com}; 1349651SAndreas.Sandberg@ARM.com 1359651SAndreas.Sandberg@ARM.com/** 1369651SAndreas.Sandberg@ARM.com * A BaseSlavePort is a protocol-agnostic slave port, responsible 1379651SAndreas.Sandberg@ARM.com * only for the structural connection to a master port. 1389651SAndreas.Sandberg@ARM.com */ 1399651SAndreas.Sandberg@ARM.comclass BaseSlavePort : public Port 1409651SAndreas.Sandberg@ARM.com{ 1419651SAndreas.Sandberg@ARM.com 1429651SAndreas.Sandberg@ARM.com protected: 1439651SAndreas.Sandberg@ARM.com 1449651SAndreas.Sandberg@ARM.com BaseMasterPort* _baseMasterPort; 1459651SAndreas.Sandberg@ARM.com 1469651SAndreas.Sandberg@ARM.com BaseSlavePort(const std::string& name, MemObject* owner, 1479651SAndreas.Sandberg@ARM.com PortID id = InvalidPortID); 1489651SAndreas.Sandberg@ARM.com virtual ~BaseSlavePort(); 1499651SAndreas.Sandberg@ARM.com 1509651SAndreas.Sandberg@ARM.com public: 1519651SAndreas.Sandberg@ARM.com 1529651SAndreas.Sandberg@ARM.com BaseMasterPort& getMasterPort() const; 1539651SAndreas.Sandberg@ARM.com bool isConnected() const; 1549690Sandreas@sandberg.pp.se 1559690Sandreas@sandberg.pp.se}; 1569690Sandreas@sandberg.pp.se 1579651SAndreas.Sandberg@ARM.com/** Forward declaration */ 1589651SAndreas.Sandberg@ARM.comclass SlavePort; 1599651SAndreas.Sandberg@ARM.com 1609651SAndreas.Sandberg@ARM.com/** 1619651SAndreas.Sandberg@ARM.com * A MasterPort is a specialisation of a BaseMasterPort, which 1629651SAndreas.Sandberg@ARM.com * implements the default protocol for the three different level of 1639732Sandreas@sandberg.pp.se * transport functions. In addition to the basic functionality of 1649732Sandreas@sandberg.pp.se * sending packets, it also has functions to receive range changes or 16510073Sandreas@sandberg.pp.se * determine if the port is snooping or not. 16610073Sandreas@sandberg.pp.se */ 16710073Sandreas@sandberg.pp.seclass MasterPort : public BaseMasterPort 16810073Sandreas@sandberg.pp.se{ 16910073Sandreas@sandberg.pp.se 17010073Sandreas@sandberg.pp.se friend class SlavePort; 17110073Sandreas@sandberg.pp.se 17211629Smichael.lebeane@amd.com private: 17311629Smichael.lebeane@amd.com 17411629Smichael.lebeane@amd.com SlavePort* _slavePort; 17511629Smichael.lebeane@amd.com 17611629Smichael.lebeane@amd.com public: 17711629Smichael.lebeane@amd.com 17811629Smichael.lebeane@amd.com MasterPort(const std::string& name, MemObject* owner, 17911629Smichael.lebeane@amd.com PortID id = InvalidPortID); 18011629Smichael.lebeane@amd.com virtual ~MasterPort(); 18111629Smichael.lebeane@amd.com 18211629Smichael.lebeane@amd.com /** 18311629Smichael.lebeane@amd.com * Bind this master port to a slave port. This also does the 18411629Smichael.lebeane@amd.com * mirror action and binds the slave port to the master port. 18511629Smichael.lebeane@amd.com */ 18611629Smichael.lebeane@amd.com void bind(BaseSlavePort& slave_port); 18711629Smichael.lebeane@amd.com 18811629Smichael.lebeane@amd.com /** 18911629Smichael.lebeane@amd.com * Unbind this master port and the associated slave port. 19011629Smichael.lebeane@amd.com */ 19111629Smichael.lebeane@amd.com void unbind(); 19211629Smichael.lebeane@amd.com 19311629Smichael.lebeane@amd.com /** 19411629Smichael.lebeane@amd.com * Send an atomic request packet, where the data is moved and the 19511629Smichael.lebeane@amd.com * state is updated in zero time, without interleaving with other 19611629Smichael.lebeane@amd.com * memory accesses. 19711629Smichael.lebeane@amd.com * 19811629Smichael.lebeane@amd.com * @param pkt Packet to send. 19911629Smichael.lebeane@amd.com * 20011629Smichael.lebeane@amd.com * @return Estimated latency of access. 20111629Smichael.lebeane@amd.com */ 20211629Smichael.lebeane@amd.com Tick sendAtomic(PacketPtr pkt); 20311629Smichael.lebeane@amd.com 20411629Smichael.lebeane@amd.com /** 20511629Smichael.lebeane@amd.com * Send a functional request packet, where the data is instantly 20611629Smichael.lebeane@amd.com * updated everywhere in the memory system, without affecting the 20711629Smichael.lebeane@amd.com * current state of any block or moving the block. 20811629Smichael.lebeane@amd.com * 20911629Smichael.lebeane@amd.com * @param pkt Packet to send. 21011629Smichael.lebeane@amd.com */ 21111629Smichael.lebeane@amd.com void sendFunctional(PacketPtr pkt); 21211629Smichael.lebeane@amd.com 21311629Smichael.lebeane@amd.com /** 21411629Smichael.lebeane@amd.com * Attempt to send a timing request to the slave port by calling 21511629Smichael.lebeane@amd.com * its corresponding receive function. If the send does not 21611629Smichael.lebeane@amd.com * succeed, as indicated by the return value, then the sender must 21711629Smichael.lebeane@amd.com * wait for a recvReqRetry at which point it can re-issue a 21811629Smichael.lebeane@amd.com * sendTimingReq. 21911629Smichael.lebeane@amd.com * 22011629Smichael.lebeane@amd.com * @param pkt Packet to send. 22111629Smichael.lebeane@amd.com * 22211629Smichael.lebeane@amd.com * @return If the send was succesful or not. 22311629Smichael.lebeane@amd.com */ 22411629Smichael.lebeane@amd.com bool sendTimingReq(PacketPtr pkt); 22511629Smichael.lebeane@amd.com 22611629Smichael.lebeane@amd.com /** 22711629Smichael.lebeane@amd.com * Check if the slave can handle a timing request. 22811629Smichael.lebeane@amd.com * 22911629Smichael.lebeane@amd.com * If the send cannot be handled at the moment, as indicated by 23011629Smichael.lebeane@amd.com * the return value, then the sender will receive a recvReqRetry 23111629Smichael.lebeane@amd.com * at which point it can re-issue a sendTimingReq. 23211629Smichael.lebeane@amd.com * 23311629Smichael.lebeane@amd.com * @param pkt Packet to send. 23411629Smichael.lebeane@amd.com * 23511629Smichael.lebeane@amd.com * @return If the send was succesful or not. 23611629Smichael.lebeane@amd.com */ 23711629Smichael.lebeane@amd.com bool tryTiming(PacketPtr pkt) const; 23811629Smichael.lebeane@amd.com 23911629Smichael.lebeane@amd.com /** 24011629Smichael.lebeane@amd.com * Attempt to send a timing snoop response packet to the slave 24111629Smichael.lebeane@amd.com * port by calling its corresponding receive function. If the send 24210073Sandreas@sandberg.pp.se * does not succeed, as indicated by the return value, then the 24310073Sandreas@sandberg.pp.se * sender must wait for a recvRetrySnoop at which point it can 24410073Sandreas@sandberg.pp.se * re-issue a sendTimingSnoopResp. 24510073Sandreas@sandberg.pp.se * 24610073Sandreas@sandberg.pp.se * @param pkt Packet to send. 24710073Sandreas@sandberg.pp.se */ 24810073Sandreas@sandberg.pp.se bool sendTimingSnoopResp(PacketPtr pkt); 24910073Sandreas@sandberg.pp.se 25010073Sandreas@sandberg.pp.se /** 25110073Sandreas@sandberg.pp.se * Send a retry to the slave port that previously attempted a 25210114Sandreas@sandberg.pp.se * sendTimingResp to this master port and failed. Note that this 25310114Sandreas@sandberg.pp.se * is virtual so that the "fake" snoop response port in the 25410098Sandreas@sandberg.pp.se * coherent crossbar can override the behaviour. 25510098Sandreas@sandberg.pp.se */ 25610098Sandreas@sandberg.pp.se virtual void sendRetryResp(); 25710098Sandreas@sandberg.pp.se 25810073Sandreas@sandberg.pp.se /** 25910073Sandreas@sandberg.pp.se * Determine if this master port is snooping or not. The default 26010073Sandreas@sandberg.pp.se * implementation returns false and thus tells the neighbour we 26110073Sandreas@sandberg.pp.se * are not snooping. Any master port that wants to receive snoop 26210114Sandreas@sandberg.pp.se * requests (e.g. a cache connected to a bus) has to override this 26310073Sandreas@sandberg.pp.se * function. 26410073Sandreas@sandberg.pp.se * 26510073Sandreas@sandberg.pp.se * @return true if the port should be considered a snooper 26610114Sandreas@sandberg.pp.se */ 26710073Sandreas@sandberg.pp.se virtual bool isSnooping() const { return false; } 26810073Sandreas@sandberg.pp.se 26910073Sandreas@sandberg.pp.se /** 2709651SAndreas.Sandberg@ARM.com * Get the address ranges of the connected slave port. 2719651SAndreas.Sandberg@ARM.com */ 2729651SAndreas.Sandberg@ARM.com AddrRangeList getAddrRanges() const; 2739651SAndreas.Sandberg@ARM.com 2749651SAndreas.Sandberg@ARM.com /** Inject a PrintReq for the given address to print the state of 2759651SAndreas.Sandberg@ARM.com * that address throughout the memory system. For debugging. 2769651SAndreas.Sandberg@ARM.com */ 2779651SAndreas.Sandberg@ARM.com void printAddr(Addr a); 2789651SAndreas.Sandberg@ARM.com 2799684Sandreas@sandberg.pp.se protected: 2809684Sandreas@sandberg.pp.se 2819684Sandreas@sandberg.pp.se /** 2829684Sandreas@sandberg.pp.se * Receive an atomic snoop request packet from the slave port. 2839684Sandreas@sandberg.pp.se */ 2849651SAndreas.Sandberg@ARM.com virtual Tick recvAtomicSnoop(PacketPtr pkt) 2859651SAndreas.Sandberg@ARM.com { 2869651SAndreas.Sandberg@ARM.com panic("%s was not expecting an atomic snoop request\n", name()); 2879651SAndreas.Sandberg@ARM.com return 0; 2889651SAndreas.Sandberg@ARM.com } 2899755Sandreas@sandberg.pp.se 2909755Sandreas@sandberg.pp.se /** 2919755Sandreas@sandberg.pp.se * Receive a functional snoop request packet from the slave port. 2929755Sandreas@sandberg.pp.se */ 2939755Sandreas@sandberg.pp.se virtual void recvFunctionalSnoop(PacketPtr pkt) 2949755Sandreas@sandberg.pp.se { 2959755Sandreas@sandberg.pp.se panic("%s was not expecting a functional snoop request\n", name()); 2969755Sandreas@sandberg.pp.se } 2979755Sandreas@sandberg.pp.se 2989755Sandreas@sandberg.pp.se /** 2999651SAndreas.Sandberg@ARM.com * Receive a timing response from the slave port. 3009651SAndreas.Sandberg@ARM.com */ 3019651SAndreas.Sandberg@ARM.com virtual bool recvTimingResp(PacketPtr pkt) = 0; 3029651SAndreas.Sandberg@ARM.com 3039651SAndreas.Sandberg@ARM.com /** 3049651SAndreas.Sandberg@ARM.com * Receive a timing snoop request from the slave port. 3059651SAndreas.Sandberg@ARM.com */ 3069651SAndreas.Sandberg@ARM.com virtual void recvTimingSnoopReq(PacketPtr pkt) 3079651SAndreas.Sandberg@ARM.com { 3089651SAndreas.Sandberg@ARM.com panic("%s was not expecting a timing snoop request\n", name()); 3099651SAndreas.Sandberg@ARM.com } 3109651SAndreas.Sandberg@ARM.com 3119651SAndreas.Sandberg@ARM.com /** 3129651SAndreas.Sandberg@ARM.com * Called by the slave port if sendTimingReq was called on this 3139651SAndreas.Sandberg@ARM.com * master port (causing recvTimingReq to be called on the slave 3149651SAndreas.Sandberg@ARM.com * port) and was unsuccesful. 3159651SAndreas.Sandberg@ARM.com */ 3169651SAndreas.Sandberg@ARM.com virtual void recvReqRetry() = 0; 3179651SAndreas.Sandberg@ARM.com 3189651SAndreas.Sandberg@ARM.com /** 3199651SAndreas.Sandberg@ARM.com * Called by the slave port if sendTimingSnoopResp was called on this 3209651SAndreas.Sandberg@ARM.com * master port (causing recvTimingSnoopResp to be called on the slave 3219651SAndreas.Sandberg@ARM.com * port) and was unsuccesful. 3229651SAndreas.Sandberg@ARM.com */ 3239651SAndreas.Sandberg@ARM.com virtual void recvRetrySnoopResp() 3249651SAndreas.Sandberg@ARM.com { 3259651SAndreas.Sandberg@ARM.com panic("%s was not expecting a snoop retry\n", name()); 3269651SAndreas.Sandberg@ARM.com } 3279651SAndreas.Sandberg@ARM.com 3289651SAndreas.Sandberg@ARM.com /** 3299651SAndreas.Sandberg@ARM.com * Called to receive an address range change from the peer slave 3309651SAndreas.Sandberg@ARM.com * port. The default implementation ignores the change and does 33110905Sandreas.sandberg@arm.com * nothing. Override this function in a derived class if the owner 3329651SAndreas.Sandberg@ARM.com * needs to be aware of the address ranges, e.g. in an 3339683Sandreas@sandberg.pp.se * interconnect component like a bus. 3349683Sandreas@sandberg.pp.se */ 3359683Sandreas@sandberg.pp.se virtual void recvRangeChange() { } 3369683Sandreas@sandberg.pp.se}; 3379683Sandreas@sandberg.pp.se 3389651SAndreas.Sandberg@ARM.com/** 3399651SAndreas.Sandberg@ARM.com * A SlavePort is a specialisation of a port. In addition to the 34010905Sandreas.sandberg@arm.com * basic functionality of sending packets to its master peer, it also 3419651SAndreas.Sandberg@ARM.com * has functions specific to a slave, e.g. to send range changes 3429651SAndreas.Sandberg@ARM.com * and get the address ranges that the port responds to. 3439651SAndreas.Sandberg@ARM.com */ 34410905Sandreas.sandberg@arm.comclass SlavePort : public BaseSlavePort 3459651SAndreas.Sandberg@ARM.com{ 3469683Sandreas@sandberg.pp.se 3479683Sandreas@sandberg.pp.se friend class MasterPort; 3489651SAndreas.Sandberg@ARM.com 3499651SAndreas.Sandberg@ARM.com private: 35010905Sandreas.sandberg@arm.com 3519652SAndreas.Sandberg@ARM.com MasterPort* _masterPort; 3529651SAndreas.Sandberg@ARM.com 3539651SAndreas.Sandberg@ARM.com public: 35410913Sandreas.sandberg@arm.com 35510913Sandreas.sandberg@arm.com SlavePort(const std::string& name, MemObject* owner, 3569651SAndreas.Sandberg@ARM.com PortID id = InvalidPortID); 3579651SAndreas.Sandberg@ARM.com virtual ~SlavePort(); 35810913Sandreas.sandberg@arm.com 3599651SAndreas.Sandberg@ARM.com /** 3609753Sandreas@sandberg.pp.se * Send an atomic snoop request packet, where the data is moved 3619753Sandreas@sandberg.pp.se * and the state is updated in zero time, without interleaving 3629753Sandreas@sandberg.pp.se * with other memory accesses. 3639753Sandreas@sandberg.pp.se * 3649753Sandreas@sandberg.pp.se * @param pkt Snoop packet to send. 3659753Sandreas@sandberg.pp.se * 3669753Sandreas@sandberg.pp.se * @return Estimated latency of access. 3679753Sandreas@sandberg.pp.se */ 36810913Sandreas.sandberg@arm.com Tick sendAtomicSnoop(PacketPtr pkt); 36910913Sandreas.sandberg@arm.com 3709651SAndreas.Sandberg@ARM.com /** 3719753Sandreas@sandberg.pp.se * Send a functional snoop request packet, where the data is 3729753Sandreas@sandberg.pp.se * instantly updated everywhere in the memory system, without 3739753Sandreas@sandberg.pp.se * affecting the current state of any block or moving the block. 3749753Sandreas@sandberg.pp.se * 3759753Sandreas@sandberg.pp.se * @param pkt Snoop packet to send. 3769753Sandreas@sandberg.pp.se */ 3779753Sandreas@sandberg.pp.se void sendFunctionalSnoop(PacketPtr pkt); 3789651SAndreas.Sandberg@ARM.com 3799753Sandreas@sandberg.pp.se /** 3809753Sandreas@sandberg.pp.se * Attempt to send a timing response to the master port by calling 3819753Sandreas@sandberg.pp.se * its corresponding receive function. If the send does not 3829753Sandreas@sandberg.pp.se * succeed, as indicated by the return value, then the sender must 3839753Sandreas@sandberg.pp.se * wait for a recvRespRetry at which point it can re-issue a 3849753Sandreas@sandberg.pp.se * sendTimingResp. 3859753Sandreas@sandberg.pp.se * 3869753Sandreas@sandberg.pp.se * @param pkt Packet to send. 3879753Sandreas@sandberg.pp.se * 38810913Sandreas.sandberg@arm.com * @return If the send was succesful or not. 3899753Sandreas@sandberg.pp.se */ 3909753Sandreas@sandberg.pp.se bool sendTimingResp(PacketPtr pkt); 3919753Sandreas@sandberg.pp.se 3929753Sandreas@sandberg.pp.se /** 3939753Sandreas@sandberg.pp.se * Attempt to send a timing snoop request packet to the master port 3949753Sandreas@sandberg.pp.se * by calling its corresponding receive function. Snoop requests 3959753Sandreas@sandberg.pp.se * always succeed and hence no return value is needed. 3969753Sandreas@sandberg.pp.se * 3979753Sandreas@sandberg.pp.se * @param pkt Packet to send. 3989753Sandreas@sandberg.pp.se */ 39910913Sandreas.sandberg@arm.com void sendTimingSnoopReq(PacketPtr pkt); 4009753Sandreas@sandberg.pp.se 40111629Smichael.lebeane@amd.com /** 40211629Smichael.lebeane@amd.com * Send a retry to the master port that previously attempted a 40311629Smichael.lebeane@amd.com * sendTimingReq to this slave port and failed. 40411629Smichael.lebeane@amd.com */ 40511629Smichael.lebeane@amd.com void sendRetryReq(); 40611629Smichael.lebeane@amd.com 4079753Sandreas@sandberg.pp.se /** 4089753Sandreas@sandberg.pp.se * Send a retry to the master port that previously attempted a 4099753Sandreas@sandberg.pp.se * sendTimingSnoopResp to this slave port and failed. 41010913Sandreas.sandberg@arm.com */ 4119753Sandreas@sandberg.pp.se void sendRetrySnoopResp(); 4129753Sandreas@sandberg.pp.se 4139753Sandreas@sandberg.pp.se /** 41410913Sandreas.sandberg@arm.com * Find out if the peer master port is snooping or not. 4159753Sandreas@sandberg.pp.se * 4169651SAndreas.Sandberg@ARM.com * @return true if the peer master port is snooping 4179651SAndreas.Sandberg@ARM.com */ 4189651SAndreas.Sandberg@ARM.com bool isSnooping() const { return _masterPort->isSnooping(); } 4199651SAndreas.Sandberg@ARM.com 4209651SAndreas.Sandberg@ARM.com /** 4219651SAndreas.Sandberg@ARM.com * Called by the owner to send a range change 4229651SAndreas.Sandberg@ARM.com */ 4239651SAndreas.Sandberg@ARM.com void sendRangeChange() const { 4249651SAndreas.Sandberg@ARM.com if (!_masterPort) 4259651SAndreas.Sandberg@ARM.com fatal("%s cannot sendRangeChange() without master port", name()); 4269651SAndreas.Sandberg@ARM.com _masterPort->recvRangeChange(); 4279651SAndreas.Sandberg@ARM.com } 4289651SAndreas.Sandberg@ARM.com 4299651SAndreas.Sandberg@ARM.com /** 4309651SAndreas.Sandberg@ARM.com * Get a list of the non-overlapping address ranges the owner is 4319651SAndreas.Sandberg@ARM.com * responsible for. All slave ports must override this function 4329651SAndreas.Sandberg@ARM.com * and return a populated list with at least one item. 4339651SAndreas.Sandberg@ARM.com * 4349651SAndreas.Sandberg@ARM.com * @return a list of ranges responded to 4359651SAndreas.Sandberg@ARM.com */ 4369651SAndreas.Sandberg@ARM.com virtual AddrRangeList getAddrRanges() const = 0; 4379651SAndreas.Sandberg@ARM.com 4389651SAndreas.Sandberg@ARM.com protected: 4399651SAndreas.Sandberg@ARM.com 4409651SAndreas.Sandberg@ARM.com /** 4419651SAndreas.Sandberg@ARM.com * Called by the master port to unbind. Should never be called 44211363Sandreas@sandberg.pp.se * directly. 44311363Sandreas@sandberg.pp.se */ 44411363Sandreas@sandberg.pp.se void unbind(); 44511363Sandreas@sandberg.pp.se 44611363Sandreas@sandberg.pp.se /** 44711363Sandreas@sandberg.pp.se * Called by the master port to bind. Should never be called 44811363Sandreas@sandberg.pp.se * directly. 44911363Sandreas@sandberg.pp.se */ 45011363Sandreas@sandberg.pp.se void bind(MasterPort& master_port); 45111363Sandreas@sandberg.pp.se 45211363Sandreas@sandberg.pp.se /** 45311363Sandreas@sandberg.pp.se * Receive an atomic request packet from the master port. 45411363Sandreas@sandberg.pp.se */ 45511363Sandreas@sandberg.pp.se virtual Tick recvAtomic(PacketPtr pkt) = 0; 45611363Sandreas@sandberg.pp.se 45711363Sandreas@sandberg.pp.se /** 45811363Sandreas@sandberg.pp.se * Receive a functional request packet from the master port. 45911363Sandreas@sandberg.pp.se */ 46011363Sandreas@sandberg.pp.se virtual void recvFunctional(PacketPtr pkt) = 0; 46111363Sandreas@sandberg.pp.se 46211363Sandreas@sandberg.pp.se /** 46311363Sandreas@sandberg.pp.se * Receive a timing request from the master port. 46411363Sandreas@sandberg.pp.se */ 4659651SAndreas.Sandberg@ARM.com virtual bool recvTimingReq(PacketPtr pkt) = 0; 4669651SAndreas.Sandberg@ARM.com 4679652SAndreas.Sandberg@ARM.com /** 4689652SAndreas.Sandberg@ARM.com * Availability request from the master port. 4699651SAndreas.Sandberg@ARM.com */ 4709651SAndreas.Sandberg@ARM.com virtual bool tryTiming(PacketPtr pkt) { 4719651SAndreas.Sandberg@ARM.com panic("%s was not expecting a %s\n", name(), __func__); 4729651SAndreas.Sandberg@ARM.com } 4739651SAndreas.Sandberg@ARM.com 4749651SAndreas.Sandberg@ARM.com /** 4759651SAndreas.Sandberg@ARM.com * Receive a timing snoop response from the master port. 4769651SAndreas.Sandberg@ARM.com */ 4779651SAndreas.Sandberg@ARM.com virtual bool recvTimingSnoopResp(PacketPtr pkt) 4789651SAndreas.Sandberg@ARM.com { 4799651SAndreas.Sandberg@ARM.com panic("%s was not expecting a timing snoop response\n", name()); 4809651SAndreas.Sandberg@ARM.com } 4819651SAndreas.Sandberg@ARM.com 4829651SAndreas.Sandberg@ARM.com /** 4839651SAndreas.Sandberg@ARM.com * Called by the master port if sendTimingResp was called on this 4849651SAndreas.Sandberg@ARM.com * slave port (causing recvTimingResp to be called on the master 4859651SAndreas.Sandberg@ARM.com * port) and was unsuccesful. 4869651SAndreas.Sandberg@ARM.com */ 4879651SAndreas.Sandberg@ARM.com virtual void recvRespRetry() = 0; 4889651SAndreas.Sandberg@ARM.com 4899651SAndreas.Sandberg@ARM.com}; 4909651SAndreas.Sandberg@ARM.com 4919651SAndreas.Sandberg@ARM.com#endif //__MEM_PORT_HH__ 4929753Sandreas@sandberg.pp.se