port.hh revision 9088
13358Srdreslin@umich.edu/* 21693Sstever@eecs.umich.edu * Copyright (c) 2011-2012 ARM Limited 31693Sstever@eecs.umich.edu * All rights reserved 41693Sstever@eecs.umich.edu * 51693Sstever@eecs.umich.edu * The license below extends only to copyright in the software and shall 61693Sstever@eecs.umich.edu * not be construed as granting a license to any other intellectual 71693Sstever@eecs.umich.edu * property including but not limited to intellectual property relating 81693Sstever@eecs.umich.edu * to a hardware implementation of the functionality of the software 91693Sstever@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 101693Sstever@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 111693Sstever@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 121693Sstever@eecs.umich.edu * modified or unmodified, in source code or in binary form. 131693Sstever@eecs.umich.edu * 141693Sstever@eecs.umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan 151693Sstever@eecs.umich.edu * All rights reserved. 161693Sstever@eecs.umich.edu * 171693Sstever@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 181693Sstever@eecs.umich.edu * modification, are permitted provided that the following conditions are 191693Sstever@eecs.umich.edu * met: redistributions of source code must retain the above copyright 201693Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 211693Sstever@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 221693Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 231693Sstever@eecs.umich.edu * documentation and/or other materials provided with the distribution; 241693Sstever@eecs.umich.edu * neither the name of the copyright holders nor the names of its 251693Sstever@eecs.umich.edu * contributors may be used to endorse or promote products derived from 261693Sstever@eecs.umich.edu * this software without specific prior written permission. 271693Sstever@eecs.umich.edu * 281693Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 293358Srdreslin@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 303358Srdreslin@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 311516SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 323358Srdreslin@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 333358Srdreslin@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 343358Srdreslin@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 353358Srdreslin@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 361516SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 373358Srdreslin@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 383358Srdreslin@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 393358Srdreslin@umich.edu * 403358Srdreslin@umich.edu * Authors: Ron Dreslinski 413358Srdreslin@umich.edu * Andreas Hansson 423358Srdreslin@umich.edu * William Wang 433358Srdreslin@umich.edu */ 443358Srdreslin@umich.edu 453358Srdreslin@umich.edu/** 463358Srdreslin@umich.edu * @file 473358Srdreslin@umich.edu * Port Object Declaration. 483358Srdreslin@umich.edu */ 493360Srdreslin@umich.edu 503358Srdreslin@umich.edu#ifndef __MEM_PORT_HH__ 513358Srdreslin@umich.edu#define __MEM_PORT_HH__ 523358Srdreslin@umich.edu 533358Srdreslin@umich.edu#include <list> 543360Srdreslin@umich.edu 553360Srdreslin@umich.edu#include "base/range.hh" 563360Srdreslin@umich.edu#include "mem/packet.hh" 573360Srdreslin@umich.edu 583360Srdreslin@umich.edu/** 593360Srdreslin@umich.edu * This typedef is used to clean up getAddrRanges(). It's declared 603360Srdreslin@umich.edu * outside the Port object since it's also used by some mem objects. 613360Srdreslin@umich.edu * Eventually we should move this typedef to wherever Addr is 623358Srdreslin@umich.edu * defined. 633358Srdreslin@umich.edu */ 643360Srdreslin@umich.edu 653358Srdreslin@umich.edutypedef std::list<Range<Addr> > AddrRangeList; 663358Srdreslin@umich.edutypedef std::list<Range<Addr> >::iterator AddrRangeIter; 673358Srdreslin@umich.edu 683358Srdreslin@umich.educlass MemObject; 693358Srdreslin@umich.edu 703358Srdreslin@umich.edu/** 713358Srdreslin@umich.edu * Ports are used to interface memory objects to each other. A port is 723358Srdreslin@umich.edu * either a master or a slave and the connected peer is always of the 733358Srdreslin@umich.edu * opposite role. Each port has a name, an owner, and an identifier. 743360Srdreslin@umich.edu */ 753360Srdreslin@umich.educlass Port 763360Srdreslin@umich.edu{ 773360Srdreslin@umich.edu 783358Srdreslin@umich.edu private: 793358Srdreslin@umich.edu 803358Srdreslin@umich.edu /** Descriptive name (for DPRINTF output) */ 813358Srdreslin@umich.edu std::string portName; 823358Srdreslin@umich.edu 833358Srdreslin@umich.edu protected: 843358Srdreslin@umich.edu 853358Srdreslin@umich.edu /** 863358Srdreslin@umich.edu * A numeric identifier to distinguish ports in a vector, and set 873360Srdreslin@umich.edu * to InvalidPortID in case this port is not part of a vector. 883358Srdreslin@umich.edu */ 893358Srdreslin@umich.edu const PortID id; 903358Srdreslin@umich.edu 913360Srdreslin@umich.edu /** A reference to the MemObject that owns this port. */ 923358Srdreslin@umich.edu MemObject& owner; 933358Srdreslin@umich.edu 943358Srdreslin@umich.edu /** 953360Srdreslin@umich.edu * Abstract base class for ports 963358Srdreslin@umich.edu * 973358Srdreslin@umich.edu * @param _name Port name including the owners name 983358Srdreslin@umich.edu * @param _owner The MemObject that is the structural owner of this port 993360Srdreslin@umich.edu * @param _id A port identifier for vector ports 1003358Srdreslin@umich.edu */ 1013358Srdreslin@umich.edu Port(const std::string& _name, MemObject& _owner, PortID _id); 1023358Srdreslin@umich.edu 1033360Srdreslin@umich.edu /** 1043358Srdreslin@umich.edu * Virtual destructor due to inheritance. 1053360Srdreslin@umich.edu */ 1063358Srdreslin@umich.edu virtual ~Port(); 1073358Srdreslin@umich.edu 1083360Srdreslin@umich.edu public: 1093358Srdreslin@umich.edu 1103360Srdreslin@umich.edu /** Return port name (for DPRINTF). */ 1113358Srdreslin@umich.edu const std::string name() const { return portName; } 1123358Srdreslin@umich.edu 1133360Srdreslin@umich.edu /** Get the port id. */ 1143358Srdreslin@umich.edu PortID getId() const { return id; } 1153358Srdreslin@umich.edu 1163358Srdreslin@umich.edu}; 1173360Srdreslin@umich.edu 1183358Srdreslin@umich.edu/** Forward declaration */ 1193358Srdreslin@umich.educlass SlavePort; 1203358Srdreslin@umich.edu 1213360Srdreslin@umich.edu/** 1223358Srdreslin@umich.edu * A MasterPort is a specialisation of a port. In addition to the 1233358Srdreslin@umich.edu * basic functionality of sending packets to its slave peer, it also 1243358Srdreslin@umich.edu * has functions specific to a master, e.g. to receive range changes 1253358Srdreslin@umich.edu * or determine if the port is snooping or not. 1263360Srdreslin@umich.edu */ 1273358Srdreslin@umich.educlass MasterPort : public Port 1283360Srdreslin@umich.edu{ 1293358Srdreslin@umich.edu 1303358Srdreslin@umich.edu friend class SlavePort; 1313360Srdreslin@umich.edu 1323358Srdreslin@umich.edu private: 1333360Srdreslin@umich.edu 1343358Srdreslin@umich.edu SlavePort* _slavePort; 1353358Srdreslin@umich.edu 1363358Srdreslin@umich.edu public: 1373358Srdreslin@umich.edu 1383358Srdreslin@umich.edu MasterPort(const std::string& name, MemObject* owner, 1393358Srdreslin@umich.edu PortID id = InvalidPortID); 1403358Srdreslin@umich.edu virtual ~MasterPort(); 1413358Srdreslin@umich.edu 1423358Srdreslin@umich.edu void bind(SlavePort& slave_port); 1433358Srdreslin@umich.edu SlavePort& getSlavePort() const; 1443358Srdreslin@umich.edu bool isConnected() const; 1453358Srdreslin@umich.edu 1463358Srdreslin@umich.edu /** 1473358Srdreslin@umich.edu * Send an atomic request packet, where the data is moved and the 1483358Srdreslin@umich.edu * state is updated in zero time, without interleaving with other 1493358Srdreslin@umich.edu * memory accesses. 1503358Srdreslin@umich.edu * 1513358Srdreslin@umich.edu * @param pkt Packet to send. 1523358Srdreslin@umich.edu * 1533358Srdreslin@umich.edu * @return Estimated latency of access. 1543358Srdreslin@umich.edu */ 1553358Srdreslin@umich.edu Tick sendAtomic(PacketPtr pkt); 1563358Srdreslin@umich.edu 1573358Srdreslin@umich.edu /** 1583358Srdreslin@umich.edu * Send a functional request packet, where the data is instantly 1593358Srdreslin@umich.edu * updated everywhere in the memory system, without affecting the 1603358Srdreslin@umich.edu * current state of any block or moving the block. 1613358Srdreslin@umich.edu * 1623358Srdreslin@umich.edu * @param pkt Packet to send. 1633358Srdreslin@umich.edu */ 1643358Srdreslin@umich.edu void sendFunctional(PacketPtr pkt); 1653358Srdreslin@umich.edu 1663358Srdreslin@umich.edu /** 1673358Srdreslin@umich.edu * Attempt to send a timing request to the slave port by calling 1683358Srdreslin@umich.edu * its corresponding receive function. If the send does not 1693358Srdreslin@umich.edu * succeed, as indicated by the return value, then the sender must 1703358Srdreslin@umich.edu * wait for a recvRetry at which point it can re-issue a 1713358Srdreslin@umich.edu * sendTimingReq. 1721516SN/A * 1733358Srdreslin@umich.edu * @param pkt Packet to send. 1743358Srdreslin@umich.edu * 1753358Srdreslin@umich.edu * @return If the send was succesful or not. 1761516SN/A */ 1773358Srdreslin@umich.edu bool sendTimingReq(PacketPtr pkt); 1783358Srdreslin@umich.edu 1793358Srdreslin@umich.edu /** 1803358Srdreslin@umich.edu * Attempt to send a timing snoop response packet to the slave 1813358Srdreslin@umich.edu * port by calling its corresponding receive function. If the send 1821516SN/A * does not succeed, as indicated by the return value, then the 1833358Srdreslin@umich.edu * sender must wait for a recvRetry at which point it can re-issue 1843358Srdreslin@umich.edu * a sendTimingSnoopResp. 1853358Srdreslin@umich.edu * 1863358Srdreslin@umich.edu * @param pkt Packet to send. 1873358Srdreslin@umich.edu */ 1883358Srdreslin@umich.edu bool sendTimingSnoopResp(PacketPtr pkt); 1893358Srdreslin@umich.edu 1903358Srdreslin@umich.edu /** 1913358Srdreslin@umich.edu * Send a retry to the slave port that previously attempted a 1923358Srdreslin@umich.edu * sendTimingResp to this master port and failed. 1933358Srdreslin@umich.edu */ 1943358Srdreslin@umich.edu void sendRetry(); 1953358Srdreslin@umich.edu 1963358Srdreslin@umich.edu /** 1973358Srdreslin@umich.edu * Determine if this master port is snooping or not. The default 1983358Srdreslin@umich.edu * implementation returns false and thus tells the neighbour we 1993358Srdreslin@umich.edu * are not snooping. Any master port that wants to receive snoop 2003358Srdreslin@umich.edu * requests (e.g. a cache connected to a bus) has to override this 2013358Srdreslin@umich.edu * function. 2023358Srdreslin@umich.edu * 2033358Srdreslin@umich.edu * @return true if the port should be considered a snooper 2043358Srdreslin@umich.edu */ 2053358Srdreslin@umich.edu virtual bool isSnooping() const { return false; } 2063358Srdreslin@umich.edu 2073358Srdreslin@umich.edu /** 2083358Srdreslin@umich.edu * Called by a peer port in order to determine the block size of 2093358Srdreslin@umich.edu * the owner of this port. 2103358Srdreslin@umich.edu */ 2113358Srdreslin@umich.edu virtual unsigned deviceBlockSize() const { return 0; } 2123358Srdreslin@umich.edu 2133358Srdreslin@umich.edu /** Called by the associated device if it wishes to find out the blocksize 2143358Srdreslin@umich.edu of the device on attached to the peer port. 2153358Srdreslin@umich.edu */ 2163358Srdreslin@umich.edu unsigned peerBlockSize() const; 2173358Srdreslin@umich.edu 2183358Srdreslin@umich.edu /** Inject a PrintReq for the given address to print the state of 2193358Srdreslin@umich.edu * that address throughout the memory system. For debugging. 2203358Srdreslin@umich.edu */ 2213358Srdreslin@umich.edu void printAddr(Addr a); 2223358Srdreslin@umich.edu 2233358Srdreslin@umich.edu protected: 2243358Srdreslin@umich.edu 2253358Srdreslin@umich.edu /** 2263358Srdreslin@umich.edu * Receive an atomic snoop request packet from the slave port. 2273358Srdreslin@umich.edu */ 2283358Srdreslin@umich.edu virtual Tick recvAtomicSnoop(PacketPtr pkt) 2293358Srdreslin@umich.edu { 2303358Srdreslin@umich.edu panic("%s was not expecting an atomic snoop request\n", name()); 2313358Srdreslin@umich.edu return 0; 2323358Srdreslin@umich.edu } 2333358Srdreslin@umich.edu 2343358Srdreslin@umich.edu /** 2353358Srdreslin@umich.edu * Receive a functional snoop request packet from the slave port. 2363358Srdreslin@umich.edu */ 2373358Srdreslin@umich.edu virtual void recvFunctionalSnoop(PacketPtr pkt) 2381516SN/A { 2393358Srdreslin@umich.edu panic("%s was not expecting a functional snoop request\n", name()); 2401516SN/A } 2411516SN/A 2421516SN/A /** 2433358Srdreslin@umich.edu * Receive a timing response from the slave port. 2443358Srdreslin@umich.edu */ 2453358Srdreslin@umich.edu virtual bool recvTimingResp(PacketPtr pkt) = 0; 2463358Srdreslin@umich.edu 2473358Srdreslin@umich.edu /** 2483358Srdreslin@umich.edu * Receive a timing snoop request from the slave port. 2493358Srdreslin@umich.edu */ 2503358Srdreslin@umich.edu virtual void recvTimingSnoopReq(PacketPtr pkt) 2513358Srdreslin@umich.edu { 2523358Srdreslin@umich.edu panic("%s was not expecting a timing snoop request\n", name()); 2533358Srdreslin@umich.edu } 2543358Srdreslin@umich.edu 2553358Srdreslin@umich.edu /** 2563358Srdreslin@umich.edu * Called by the slave port if sendTimingReq or 2573358Srdreslin@umich.edu * sendTimingSnoopResp was called on this master port (causing 2583358Srdreslin@umich.edu * recvTimingReq and recvTimingSnoopResp to be called on the 2593358Srdreslin@umich.edu * slave port) and was unsuccesful. 2603358Srdreslin@umich.edu */ 2613358Srdreslin@umich.edu virtual void recvRetry() = 0; 2623358Srdreslin@umich.edu 2633358Srdreslin@umich.edu /** 2643358Srdreslin@umich.edu * Called to receive an address range change from the peer slave 2653358Srdreslin@umich.edu * port. the default implementation ignored the change and does 2663358Srdreslin@umich.edu * nothing. Override this function in a derived class if the owner 2673358Srdreslin@umich.edu * needs to be aware of he laesddress ranges, e.g. in an 2683358Srdreslin@umich.edu * interconnect component like a bus. 269 */ 270 virtual void recvRangeChange() { } 271}; 272 273/** 274 * A SlavePort is a specialisation of a port. In addition to the 275 * basic functionality of sending packets to its master peer, it also 276 * has functions specific to a slave, e.g. to send range changes 277 * and get the address ranges that the port responds to. 278 */ 279class SlavePort : public Port 280{ 281 282 friend class MasterPort; 283 284 private: 285 286 MasterPort* _masterPort; 287 288 public: 289 290 SlavePort(const std::string& name, MemObject* owner, 291 PortID id = InvalidPortID); 292 virtual ~SlavePort(); 293 294 void bind(MasterPort& master_port); 295 MasterPort& getMasterPort() const; 296 bool isConnected() const; 297 298 /** 299 * Send an atomic snoop request packet, where the data is moved 300 * and the state is updated in zero time, without interleaving 301 * with other memory accesses. 302 * 303 * @param pkt Snoop packet to send. 304 * 305 * @return Estimated latency of access. 306 */ 307 Tick sendAtomicSnoop(PacketPtr pkt); 308 309 /** 310 * Send a functional snoop request packet, where the data is 311 * instantly updated everywhere in the memory system, without 312 * affecting the current state of any block or moving the block. 313 * 314 * @param pkt Snoop packet to send. 315 */ 316 void sendFunctionalSnoop(PacketPtr pkt); 317 318 /** 319 * Attempt to send a timing response to the master port by calling 320 * its corresponding receive function. If the send does not 321 * succeed, as indicated by the return value, then the sender must 322 * wait for a recvRetry at which point it can re-issue a 323 * sendTimingResp. 324 * 325 * @param pkt Packet to send. 326 * 327 * @return If the send was succesful or not. 328 */ 329 bool sendTimingResp(PacketPtr pkt); 330 331 /** 332 * Attempt to send a timing snoop request packet to the master port 333 * by calling its corresponding receive function. Snoop requests 334 * always succeed and hence no return value is needed. 335 * 336 * @param pkt Packet to send. 337 */ 338 void sendTimingSnoopReq(PacketPtr pkt); 339 340 /** 341 * Send a retry to the master port that previously attempted a 342 * sendTimingReq or sendTimingSnoopResp to this slave port and 343 * failed. 344 */ 345 void sendRetry(); 346 347 /** 348 * Called by a peer port in order to determine the block size of 349 * the owner of this port. 350 */ 351 virtual unsigned deviceBlockSize() const { return 0; } 352 353 /** Called by the associated device if it wishes to find out the blocksize 354 of the device on attached to the peer port. 355 */ 356 unsigned peerBlockSize() const; 357 358 /** 359 * Find out if the peer master port is snooping or not. 360 * 361 * @return true if the peer master port is snooping 362 */ 363 bool isSnooping() const { return _masterPort->isSnooping(); } 364 365 /** 366 * Called by the owner to send a range change 367 */ 368 void sendRangeChange() const { _masterPort->recvRangeChange(); } 369 370 /** 371 * Get a list of the non-overlapping address ranges the owner is 372 * responsible for. All slave ports must override this function 373 * and return a populated list with at least one item. 374 * 375 * @return a list of ranges responded to 376 */ 377 virtual AddrRangeList getAddrRanges() = 0; 378 379 protected: 380 381 /** 382 * Receive an atomic request packet from the master port. 383 */ 384 virtual Tick recvAtomic(PacketPtr pkt) = 0; 385 386 /** 387 * Receive a functional request packet from the master port. 388 */ 389 virtual void recvFunctional(PacketPtr pkt) = 0; 390 391 /** 392 * Receive a timing request from the master port. 393 */ 394 virtual bool recvTimingReq(PacketPtr pkt) = 0; 395 396 /** 397 * Receive a timing snoop response from the master port. 398 */ 399 virtual bool recvTimingSnoopResp(PacketPtr pkt) 400 { 401 panic("%s was not expecting a timing snoop response\n", name()); 402 } 403 404 /** 405 * Called by the master port if sendTimingResp was called on this 406 * slave port (causing recvTimingResp to be called on the master 407 * port) and was unsuccesful. 408 */ 409 virtual void recvRetry() = 0; 410 411}; 412 413#endif //__MEM_PORT_HH__ 414