port.hh revision 8709
12SN/A/* 21762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Ron Dreslinski 292665Ssaidi@eecs.umich.edu */ 302SN/A 312SN/A/** 325569Snate@binkert.org * @file 335569Snate@binkert.org * Port Object Declaration. Ports are used to interface memory objects to 342SN/A * each other. They will always come in pairs, and we refer to the other 355569Snate@binkert.org * port object as the peer. These are used to make the design more 363614Sgblack@eecs.umich.edu * modular so that a specific interface between every type of objcet doesn't 373614Sgblack@eecs.umich.edu * have to be created. 383614Sgblack@eecs.umich.edu */ 392166SN/A 402147SN/A#ifndef __MEM_PORT_HH__ 415569Snate@binkert.org#define __MEM_PORT_HH__ 422167SN/A 432147SN/A#include <list> 442090SN/A 452222SN/A#include "base/misc.hh" 462090SN/A#include "base/range.hh" 472201SN/A#include "base/types.hh" 482201SN/A#include "mem/packet.hh" 492201SN/A#include "mem/request.hh" 502112SN/A 512174SN/A/** This typedef is used to clean up the parameter list of 522680Sktlim@umich.edu * getDeviceAddressRanges() and getPeerAddressRanges(). It's declared 532174SN/A * outside the Port object since it's also used by some mem objects. 542175SN/A * Eventually we should move this typedef to wherever Addr is 552222SN/A * defined. 562SN/A */ 572SN/A 582203SN/Atypedef std::list<Range<Addr> > AddrRangeList; 592166SN/Atypedef std::list<Range<Addr> >::iterator AddrRangeIter; 602166SN/A 612203SN/Aclass MemObject; 622166SN/A 632222SN/A/** 645569Snate@binkert.org * Ports are used to interface memory objects to 652166SN/A * each other. They will always come in pairs, and we refer to the other 664695Sgblack@eecs.umich.edu * port object as the peer. These are used to make the design more 672166SN/A * modular so that a specific interface between every type of objcet doesn't 682222SN/A * have to be created. 694695Sgblack@eecs.umich.edu * 702166SN/A * Recv accesor functions are being called from the peer interface. 712166SN/A * Send accessor functions are being called from the device the port is 722203SN/A * associated with, and it will call the peer recv. accessor function. 732166SN/A */ 742166SN/Aclass Port 752203SN/A{ 762166SN/A protected: 772222SN/A /** Descriptive name (for DPRINTF output) */ 785569Snate@binkert.org mutable std::string portName; 792166SN/A 804695Sgblack@eecs.umich.edu /** A pointer to the peer port. Ports always come in pairs, that way they 812166SN/A can use a standardized interface to communicate between different 822222SN/A memory objects. */ 834695Sgblack@eecs.umich.edu Port *peer; 842166SN/A 852166SN/A /** A pointer to the MemObject that owns this port. This may not be set. */ 862166SN/A MemObject *owner; 872166SN/A 882203SN/A public: 892166SN/A /** 902166SN/A * Constructor. 912147SN/A * 922090SN/A * @param _name Port name for DPRINTF output. Should include name 932147SN/A * of memory system object to which the port belongs. 942147SN/A * @param _owner Pointer to the MemObject that owns this port. 952147SN/A * Will not necessarily be set. 962222SN/A */ 975569Snate@binkert.org Port(const std::string &_name, MemObject *_owner); 982112SN/A 994695Sgblack@eecs.umich.edu /** Return port name (for DPRINTF). */ 1002147SN/A const std::string &name() const { return portName; } 1012222SN/A 1022147SN/A virtual ~Port(); 1032090SN/A 1042147SN/A // mey be better to use subclasses & RTTI? 1052090SN/A /** Holds the ports status. Currently just that a range recomputation needs 1062147SN/A * to be done. */ 1072147SN/A enum Status { 1082147SN/A RangeChange 1092222SN/A }; 1105569Snate@binkert.org 1115569Snate@binkert.org void setName(const std::string &name) 1125569Snate@binkert.org { portName = name; } 1135569Snate@binkert.org 1142112SN/A /** Function to set the pointer for the peer port. */ 1154695Sgblack@eecs.umich.edu virtual void setPeer(Port *port); 1162147SN/A 1172222SN/A /** Function to get the pointer to the peer port. */ 1182203SN/A Port *getPeer() { return peer; } 1192680Sktlim@umich.edu 1202203SN/A /** Function to set the owner of this port. */ 1212147SN/A void setOwner(MemObject *_owner); 1222090SN/A 1232147SN/A /** Function to return the owner of this port. */ 1242090SN/A MemObject *getOwner() { return owner; } 1252147SN/A 1262147SN/A /** Inform the peer port to delete itself and notify it's owner about it's 1272147SN/A * demise. */ 1282222SN/A void removeConn(); 1295569Snate@binkert.org 1305569Snate@binkert.org bool isConnected() { return peer != NULL; } 1315569Snate@binkert.org 1325569Snate@binkert.org protected: 1332112SN/A 1344695Sgblack@eecs.umich.edu /** These functions are protected because they should only be 1352147SN/A * called by a peer port, never directly by any outside object. */ 1362222SN/A 1372147SN/A /** Called to recive a timing call from the peer port. */ 1382090SN/A virtual bool recvTiming(PacketPtr pkt) = 0; 1392502SN/A 1402502SN/A /** Called to recive a atomic call from the peer port. */ 1414997Sgblack@eecs.umich.edu virtual Tick recvAtomic(PacketPtr pkt) = 0; 1425568Snate@binkert.org 1435736Snate@binkert.org /** Called to recive a functional call from the peer port. */ 1442502SN/A virtual void recvFunctional(PacketPtr pkt) = 0; 1455569Snate@binkert.org 1462502SN/A /** Called to recieve a status change from the peer port. */ 1475736Snate@binkert.org virtual void recvStatusChange(Status status) = 0; 1482502SN/A 1492502SN/A /** Called by a peer port if the send was unsuccesful, and had to 1504695Sgblack@eecs.umich.edu wait. This shouldn't be valid for response paths (IO Devices). 1512502SN/A so it is set to panic if it isn't already defined. 1522502SN/A */ 1532502SN/A virtual void recvRetry() { panic("??"); } 1542680Sktlim@umich.edu 1552502SN/A /** Called by a peer port in order to determine the block size of the 1562502SN/A device connected to this port. It sometimes doesn't make sense for 1572502SN/A this function to be called, so it just returns 0. Anytthing that is 1582502SN/A concerned with the size should just ignore that. 1592090SN/A */ 1602147SN/A virtual unsigned deviceBlockSize() const { return 0; } 1612147SN/A 1622147SN/A /** The peer port is requesting us to reply with a list of the ranges we 1632222SN/A are responsible for. 1645569Snate@binkert.org @param resp is a list of ranges responded to 1652112SN/A @param snoop is a list of ranges snooped 1665736Snate@binkert.org */ 1672502SN/A virtual void getDeviceAddressRanges(AddrRangeList &resp, 1682502SN/A bool &snoop) 1694695Sgblack@eecs.umich.edu { panic("??"); } 1702147SN/A 1712222SN/A public: 1724997Sgblack@eecs.umich.edu 1734997Sgblack@eecs.umich.edu /** Function called by associated memory device (cache, memory, iodevice) 1744997Sgblack@eecs.umich.edu in order to send a timing request to the port. Simply calls the peer 1752147SN/A port receive function. 1762090SN/A @return This function returns if the send was succesful in it's 1772502SN/A recieve. If it was a failure, then the port will wait for a recvRetry 1782090SN/A at which point it can possibly issue a successful sendTiming. This is used in 1792147SN/A case a cache has a higher priority request come in while waiting for 1802147SN/A the bus to arbitrate. 1812147SN/A */ 1822222SN/A bool sendTiming(PacketPtr pkt) { return peer->recvTiming(pkt); } 1835569Snate@binkert.org 1842112SN/A /** Function called by the associated device to send an atomic 1855736Snate@binkert.org * access, an access in which the data is moved and the state is 1862502SN/A * updated in one cycle, without interleaving with other memory 1872502SN/A * accesses. Returns estimated latency of access. 1884695Sgblack@eecs.umich.edu */ 1892147SN/A Tick sendAtomic(PacketPtr pkt) 1902222SN/A { return peer->recvAtomic(pkt); } 1912147SN/A 1922090SN/A /** Function called by the associated device to send a functional access, 1932502SN/A an access in which the data is instantly updated everywhere in the 1942090SN/A memory system, without affecting the current state of any block or 1952147SN/A moving the block. 1962147SN/A */ 1972147SN/A void sendFunctional(PacketPtr pkt) 1982222SN/A { return peer->recvFunctional(pkt); } 1995569Snate@binkert.org 2002112SN/A /** Called by the associated device to send a status change to the device 2015736Snate@binkert.org connected to the peer interface. 2022502SN/A */ 2032502SN/A void sendStatusChange(Status status) {peer->recvStatusChange(status); } 2044695Sgblack@eecs.umich.edu 2052147SN/A /** When a timing access doesn't return a success, some time later the 2062222SN/A Retry will be sent. 2072147SN/A */ 2082090SN/A void sendRetry() { return peer->recvRetry(); } 2092502SN/A 2102090SN/A /** Called by the associated device if it wishes to find out the blocksize 2112147SN/A of the device on attached to the peer port. 2122147SN/A */ 2132147SN/A unsigned peerBlockSize() const { return peer->deviceBlockSize(); } 2142222SN/A 2155569Snate@binkert.org /** Called by the associated device if it wishes to find out the address 2162112SN/A ranges connected to the peer ports devices. 2175736Snate@binkert.org */ 2182502SN/A void getPeerAddressRanges(AddrRangeList &resp, bool &snoop) 2192502SN/A { peer->getDeviceAddressRanges(resp, snoop); } 2204695Sgblack@eecs.umich.edu 2212147SN/A /** This function is a wrapper around sendFunctional() 2222222SN/A that breaks a larger, arbitrarily aligned access into 2232147SN/A appropriate chunks. The default implementation can use 2242090SN/A getBlockSize() to determine the block size and go from there. 2252502SN/A */ 2262090SN/A virtual void readBlob(Addr addr, uint8_t *p, int size); 2272147SN/A 2282147SN/A /** This function is a wrapper around sendFunctional() 2292147SN/A that breaks a larger, arbitrarily aligned access into 2302222SN/A appropriate chunks. The default implementation can use 2315569Snate@binkert.org getBlockSize() to determine the block size and go from there. 2322112SN/A */ 2335736Snate@binkert.org virtual void writeBlob(Addr addr, uint8_t *p, int size); 2342502SN/A 2352502SN/A /** Fill size bytes starting at addr with byte value val. This 2364695Sgblack@eecs.umich.edu should not need to be virtual, since it can be implemented in 2372147SN/A terms of writeBlob(). However, it shouldn't be 2382222SN/A performance-critical either, so it could be if we wanted to. 2392147SN/A */ 2402090SN/A virtual void memsetBlob(Addr addr, uint8_t val, int size); 2412502SN/A 2422502SN/A /** Inject a PrintReq for the given address to print the state of 2434997Sgblack@eecs.umich.edu * that address throughout the memory system. For debugging. 2442502SN/A */ 2455569Snate@binkert.org void printAddr(Addr a); 2462502SN/A 2475569Snate@binkert.org private: 2484695Sgblack@eecs.umich.edu 2492505SN/A /** Internal helper function for read/writeBlob(). 2502505SN/A */ 2512502SN/A void blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd); 2522680Sktlim@umich.edu}; 2532502SN/A 2542502SN/A#endif //__MEM_PORT_HH__ 2552502SN/A