port.hh revision 8709
12381SN/A/* 22381SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 32381SN/A * All rights reserved. 42381SN/A * 52381SN/A * Redistribution and use in source and binary forms, with or without 62381SN/A * modification, are permitted provided that the following conditions are 72381SN/A * met: redistributions of source code must retain the above copyright 82381SN/A * notice, this list of conditions and the following disclaimer; 92381SN/A * redistributions in binary form must reproduce the above copyright 102381SN/A * notice, this list of conditions and the following disclaimer in the 112381SN/A * documentation and/or other materials provided with the distribution; 122381SN/A * neither the name of the copyright holders nor the names of its 132381SN/A * contributors may be used to endorse or promote products derived from 142381SN/A * this software without specific prior written permission. 152381SN/A * 162381SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172381SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182381SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192381SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202381SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212381SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222381SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232381SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242381SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252381SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262381SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Ron Dreslinski 292381SN/A */ 302381SN/A 312381SN/A/** 322381SN/A * @file 332982Sstever@eecs.umich.edu * Port Object Declaration. Ports are used to interface memory objects to 342381SN/A * each other. They will always come in pairs, and we refer to the other 352381SN/A * port object as the peer. These are used to make the design more 362381SN/A * modular so that a specific interface between every type of objcet doesn't 372381SN/A * have to be created. 382381SN/A */ 392381SN/A 402381SN/A#ifndef __MEM_PORT_HH__ 412381SN/A#define __MEM_PORT_HH__ 422381SN/A 432381SN/A#include <list> 442381SN/A 452439SN/A#include "base/misc.hh" 462381SN/A#include "base/range.hh" 476215Snate@binkert.org#include "base/types.hh" 482381SN/A#include "mem/packet.hh" 492381SN/A#include "mem/request.hh" 502381SN/A 512407SN/A/** This typedef is used to clean up the parameter list of 522407SN/A * getDeviceAddressRanges() and getPeerAddressRanges(). It's declared 532407SN/A * outside the Port object since it's also used by some mem objects. 542407SN/A * Eventually we should move this typedef to wherever Addr is 552407SN/A * defined. 562407SN/A */ 572407SN/A 582407SN/Atypedef std::list<Range<Addr> > AddrRangeList; 592521SN/Atypedef std::list<Range<Addr> >::iterator AddrRangeIter; 602407SN/A 613401Sktlim@umich.educlass MemObject; 623401Sktlim@umich.edu 632381SN/A/** 642381SN/A * Ports are used to interface memory objects to 652381SN/A * each other. They will always come in pairs, and we refer to the other 662381SN/A * port object as the peer. These are used to make the design more 672381SN/A * modular so that a specific interface between every type of objcet doesn't 682381SN/A * have to be created. 692381SN/A * 702381SN/A * Recv accesor functions are being called from the peer interface. 712381SN/A * Send accessor functions are being called from the device the port is 722381SN/A * associated with, and it will call the peer recv. accessor function. 732381SN/A */ 748708Sandreas.hansson@arm.comclass Port 752381SN/A{ 765476Snate@binkert.org protected: 772640Sstever@eecs.umich.edu /** Descriptive name (for DPRINTF output) */ 782796Sktlim@umich.edu mutable std::string portName; 792640Sstever@eecs.umich.edu 802661Sstever@eecs.umich.edu /** A pointer to the peer port. Ports always come in pairs, that way they 812661Sstever@eecs.umich.edu can use a standardized interface to communicate between different 822661Sstever@eecs.umich.edu memory objects. */ 832661Sstever@eecs.umich.edu Port *peer; 842661Sstever@eecs.umich.edu 853401Sktlim@umich.edu /** A pointer to the MemObject that owns this port. This may not be set. */ 863401Sktlim@umich.edu MemObject *owner; 873401Sktlim@umich.edu 882381SN/A public: 892640Sstever@eecs.umich.edu /** 902640Sstever@eecs.umich.edu * Constructor. 912640Sstever@eecs.umich.edu * 922640Sstever@eecs.umich.edu * @param _name Port name for DPRINTF output. Should include name 932640Sstever@eecs.umich.edu * of memory system object to which the port belongs. 943401Sktlim@umich.edu * @param _owner Pointer to the MemObject that owns this port. 955494Sstever@gmail.com * Will not necessarily be set. 962640Sstever@eecs.umich.edu */ 975605Snate@binkert.org Port(const std::string &_name, MemObject *_owner); 982640Sstever@eecs.umich.edu 992640Sstever@eecs.umich.edu /** Return port name (for DPRINTF). */ 1002640Sstever@eecs.umich.edu const std::string &name() const { return portName; } 1012640Sstever@eecs.umich.edu 1025476Snate@binkert.org virtual ~Port(); 1032640Sstever@eecs.umich.edu 1042381SN/A // mey be better to use subclasses & RTTI? 1052657Ssaidi@eecs.umich.edu /** Holds the ports status. Currently just that a range recomputation needs 1062657Ssaidi@eecs.umich.edu * to be done. */ 1072381SN/A enum Status { 1083173Srdreslin@umich.edu RangeChange 1092381SN/A }; 1102381SN/A 1115494Sstever@gmail.com void setName(const std::string &name) 1125494Sstever@gmail.com { portName = name; } 1135494Sstever@gmail.com 1143401Sktlim@umich.edu /** Function to set the pointer for the peer port. */ 1154192Sktlim@umich.edu virtual void setPeer(Port *port); 1162381SN/A 1173401Sktlim@umich.edu /** Function to get the pointer to the peer port. */ 1182409SN/A Port *getPeer() { return peer; } 1192408SN/A 1205494Sstever@gmail.com /** Function to set the owner of this port. */ 1215605Snate@binkert.org void setOwner(MemObject *_owner); 1225494Sstever@gmail.com 1233401Sktlim@umich.edu /** Function to return the owner of this port. */ 1243401Sktlim@umich.edu MemObject *getOwner() { return owner; } 1253401Sktlim@umich.edu 1265494Sstever@gmail.com /** Inform the peer port to delete itself and notify it's owner about it's 1275494Sstever@gmail.com * demise. */ 1285494Sstever@gmail.com void removeConn(); 1294190Ssaidi@eecs.umich.edu 1308709Sandreas.hansson@arm.com bool isConnected() { return peer != NULL; } 1314190Ssaidi@eecs.umich.edu 1322381SN/A protected: 1332381SN/A 1342406SN/A /** These functions are protected because they should only be 1352406SN/A * called by a peer port, never directly by any outside object. */ 1362406SN/A 1372381SN/A /** Called to recive a timing call from the peer port. */ 1383349Sbinkertn@umich.edu virtual bool recvTiming(PacketPtr pkt) = 0; 1392381SN/A 1402381SN/A /** Called to recive a atomic call from the peer port. */ 1413349Sbinkertn@umich.edu virtual Tick recvAtomic(PacketPtr pkt) = 0; 1422381SN/A 1432381SN/A /** Called to recive a functional call from the peer port. */ 1443349Sbinkertn@umich.edu virtual void recvFunctional(PacketPtr pkt) = 0; 1452381SN/A 1462381SN/A /** Called to recieve a status change from the peer port. */ 1472381SN/A virtual void recvStatusChange(Status status) = 0; 1482381SN/A 1492381SN/A /** Called by a peer port if the send was unsuccesful, and had to 1502381SN/A wait. This shouldn't be valid for response paths (IO Devices). 1512381SN/A so it is set to panic if it isn't already defined. 1522381SN/A */ 1532657Ssaidi@eecs.umich.edu virtual void recvRetry() { panic("??"); } 1542381SN/A 1552381SN/A /** Called by a peer port in order to determine the block size of the 1562381SN/A device connected to this port. It sometimes doesn't make sense for 1574432Ssaidi@eecs.umich.edu this function to be called, so it just returns 0. Anytthing that is 1584432Ssaidi@eecs.umich.edu concerned with the size should just ignore that. 1592381SN/A */ 1606227Snate@binkert.org virtual unsigned deviceBlockSize() const { return 0; } 1612381SN/A 1622381SN/A /** The peer port is requesting us to reply with a list of the ranges we 1632381SN/A are responsible for. 1642521SN/A @param resp is a list of ranges responded to 1652521SN/A @param snoop is a list of ranges snooped 1662381SN/A */ 1672521SN/A virtual void getDeviceAddressRanges(AddrRangeList &resp, 1684475Sstever@eecs.umich.edu bool &snoop) 1692407SN/A { panic("??"); } 1702381SN/A 1712381SN/A public: 1722381SN/A 1732381SN/A /** Function called by associated memory device (cache, memory, iodevice) 1742381SN/A in order to send a timing request to the port. Simply calls the peer 1752381SN/A port receive function. 1762381SN/A @return This function returns if the send was succesful in it's 1772381SN/A recieve. If it was a failure, then the port will wait for a recvRetry 1782657Ssaidi@eecs.umich.edu at which point it can possibly issue a successful sendTiming. This is used in 1792381SN/A case a cache has a higher priority request come in while waiting for 1802381SN/A the bus to arbitrate. 1812381SN/A */ 1823349Sbinkertn@umich.edu bool sendTiming(PacketPtr pkt) { return peer->recvTiming(pkt); } 1832381SN/A 1842662Sstever@eecs.umich.edu /** Function called by the associated device to send an atomic 1852662Sstever@eecs.umich.edu * access, an access in which the data is moved and the state is 1862662Sstever@eecs.umich.edu * updated in one cycle, without interleaving with other memory 1872662Sstever@eecs.umich.edu * accesses. Returns estimated latency of access. 1882662Sstever@eecs.umich.edu */ 1893349Sbinkertn@umich.edu Tick sendAtomic(PacketPtr pkt) 1902381SN/A { return peer->recvAtomic(pkt); } 1912381SN/A 1922381SN/A /** Function called by the associated device to send a functional access, 1932381SN/A an access in which the data is instantly updated everywhere in the 1942520SN/A memory system, without affecting the current state of any block or 1952520SN/A moving the block. 1962381SN/A */ 1973349Sbinkertn@umich.edu void sendFunctional(PacketPtr pkt) 1982381SN/A { return peer->recvFunctional(pkt); } 1992381SN/A 2002381SN/A /** Called by the associated device to send a status change to the device 2012381SN/A connected to the peer interface. 2022381SN/A */ 2032381SN/A void sendStatusChange(Status status) {peer->recvStatusChange(status); } 2042381SN/A 2052381SN/A /** When a timing access doesn't return a success, some time later the 2062381SN/A Retry will be sent. 2072381SN/A */ 2082657Ssaidi@eecs.umich.edu void sendRetry() { return peer->recvRetry(); } 2092381SN/A 2102381SN/A /** Called by the associated device if it wishes to find out the blocksize 2112381SN/A of the device on attached to the peer port. 2122381SN/A */ 2136227Snate@binkert.org unsigned peerBlockSize() const { return peer->deviceBlockSize(); } 2142381SN/A 2152381SN/A /** Called by the associated device if it wishes to find out the address 2162381SN/A ranges connected to the peer ports devices. 2172381SN/A */ 2184475Sstever@eecs.umich.edu void getPeerAddressRanges(AddrRangeList &resp, bool &snoop) 2192521SN/A { peer->getDeviceAddressRanges(resp, snoop); } 2202381SN/A 2212461SN/A /** This function is a wrapper around sendFunctional() 2222461SN/A that breaks a larger, arbitrarily aligned access into 2232461SN/A appropriate chunks. The default implementation can use 2242461SN/A getBlockSize() to determine the block size and go from there. 2252461SN/A */ 2262519SN/A virtual void readBlob(Addr addr, uint8_t *p, int size); 2272381SN/A 2282381SN/A /** This function is a wrapper around sendFunctional() 2292381SN/A that breaks a larger, arbitrarily aligned access into 2302381SN/A appropriate chunks. The default implementation can use 2312381SN/A getBlockSize() to determine the block size and go from there. 2322381SN/A */ 2332519SN/A virtual void writeBlob(Addr addr, uint8_t *p, int size); 2342381SN/A 2352381SN/A /** Fill size bytes starting at addr with byte value val. This 2362381SN/A should not need to be virtual, since it can be implemented in 2372461SN/A terms of writeBlob(). However, it shouldn't be 2382381SN/A performance-critical either, so it could be if we wanted to. 2392381SN/A */ 2402519SN/A virtual void memsetBlob(Addr addr, uint8_t val, int size); 2412405SN/A 2425314Sstever@gmail.com /** Inject a PrintReq for the given address to print the state of 2435314Sstever@gmail.com * that address throughout the memory system. For debugging. 2445314Sstever@gmail.com */ 2455314Sstever@gmail.com void printAddr(Addr a); 2465314Sstever@gmail.com 2472405SN/A private: 2482405SN/A 2492405SN/A /** Internal helper function for read/writeBlob(). 2502405SN/A */ 2514022Sstever@eecs.umich.edu void blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd); 2522381SN/A}; 2532381SN/A 2542381SN/A#endif //__MEM_PORT_HH__ 255