port.hh revision 2520
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. 272381SN/A */ 282381SN/A 292381SN/A/** 302381SN/A * @file 312381SN/A * Port Object Decleration. Ports are used to interface memory objects to 322381SN/A * each other. They will always come in pairs, and we refer to the other 332381SN/A * port object as the peer. These are used to make the design more 342381SN/A * modular so that a specific interface between every type of objcet doesn't 352381SN/A * have to be created. 362381SN/A */ 372381SN/A 382381SN/A#ifndef __MEM_PORT_HH__ 392381SN/A#define __MEM_PORT_HH__ 402381SN/A 412381SN/A#include <string> 422381SN/A#include <list> 432381SN/A#include <inttypes.h> 442439SN/A 452381SN/A#include "base/misc.hh" 462381SN/A#include "base/range.hh" 472381SN/A#include "mem/packet.hh" 482381SN/A#include "mem/request.hh" 492407SN/A 502407SN/A/** This typedef is used to clean up the parameter list of 512407SN/A * getDeviceAddressRanges() and getPeerAddressRanges(). It's declared 522407SN/A * outside the Port object since it's also used by some mem objects. 532407SN/A * Eventually we should move this typedef to wherever Addr is 542407SN/A * defined. 552407SN/A */ 562407SN/A 572521SN/Atypedef std::list<Range<Addr> > AddrRangeList; 582407SN/A 592381SN/A/** 602381SN/A * Ports are used to interface memory objects to 612381SN/A * each other. They will always come in pairs, and we refer to the other 622381SN/A * port object as the peer. These are used to make the design more 632381SN/A * modular so that a specific interface between every type of objcet doesn't 642381SN/A * have to be created. 652381SN/A * 662381SN/A * Recv accesor functions are being called from the peer interface. 672381SN/A * Send accessor functions are being called from the device the port is 682381SN/A * associated with, and it will call the peer recv. accessor function. 692381SN/A */ 702381SN/Aclass Port 712381SN/A{ 722640Sstever@eecs.umich.edu public: 732640Sstever@eecs.umich.edu 742640Sstever@eecs.umich.edu virtual ~Port() {}; 752640Sstever@eecs.umich.edu // mey be better to use subclasses & RTTI? 762640Sstever@eecs.umich.edu /** Holds the ports status. Keeps track if it is blocked, or has 772661Sstever@eecs.umich.edu calculated a range change. */ 782661Sstever@eecs.umich.edu enum Status { 792661Sstever@eecs.umich.edu Blocked, 802661Sstever@eecs.umich.edu Unblocked, 812661Sstever@eecs.umich.edu RangeChange 822381SN/A }; 832381SN/A 842640Sstever@eecs.umich.edu private: 852640Sstever@eecs.umich.edu 862640Sstever@eecs.umich.edu /** A pointer to the peer port. Ports always come in pairs, that way they 872640Sstever@eecs.umich.edu can use a standardized interface to communicate between different 882640Sstever@eecs.umich.edu memory objects. */ 892640Sstever@eecs.umich.edu Port *peer; 902640Sstever@eecs.umich.edu 912661Sstever@eecs.umich.edu public: 922640Sstever@eecs.umich.edu 932640Sstever@eecs.umich.edu /** Function to set the pointer for the peer port. 942640Sstever@eecs.umich.edu @todo should be called by the configuration stuff (python). 952640Sstever@eecs.umich.edu */ 962640Sstever@eecs.umich.edu void setPeer(Port *port) { peer = port; } 972474SN/A 982640Sstever@eecs.umich.edu /** Function to set the pointer for the peer port. 992381SN/A @todo should be called by the configuration stuff (python). 1002657Ssaidi@eecs.umich.edu */ 1012657Ssaidi@eecs.umich.edu Port *getPeer() { return peer; } 1022381SN/A 1032381SN/A protected: 1042381SN/A 1052381SN/A /** These functions are protected because they should only be 1062381SN/A * called by a peer port, never directly by any outside object. */ 1072381SN/A 1082381SN/A /** Called to recive a timing call from the peer port. */ 1092642Sstever@eecs.umich.edu virtual bool recvTiming(Packet &pkt) = 0; 1102381SN/A 1112642Sstever@eecs.umich.edu /** Called to recive a atomic call from the peer port. */ 1122408SN/A virtual Tick recvAtomic(Packet &pkt) = 0; 1132408SN/A 1142409SN/A /** Called to recive a functional call from the peer port. */ 1152408SN/A virtual void recvFunctional(Packet &pkt) = 0; 1162381SN/A 1172381SN/A /** Called to recieve a status change from the peer port. */ 1182406SN/A virtual void recvStatusChange(Status status) = 0; 1192406SN/A 1202406SN/A /** Called by a peer port if the send was unsuccesful, and had to 1212381SN/A wait. This shouldn't be valid for response paths (IO Devices). 1222630SN/A so it is set to panic if it isn't already defined. 1232381SN/A */ 1242381SN/A virtual Packet *recvRetry() { panic("??"); } 1252630SN/A 1262381SN/A /** Called by a peer port in order to determine the block size of the 1272381SN/A device connected to this port. It sometimes doesn't make sense for 1282630SN/A this function to be called, a DMA interface doesn't really have a 1292381SN/A block size, so it is defaulted to a panic. 1302381SN/A */ 1312381SN/A virtual int deviceBlockSize() { panic("??"); } 1322381SN/A 1332381SN/A /** The peer port is requesting us to reply with a list of the ranges we 1342381SN/A are responsible for. 1352381SN/A @param owner is an output param that, if set, indicates that the 1362381SN/A port is the owner of the specified ranges (i.e., slave, default 1372657Ssaidi@eecs.umich.edu responder, etc.). If 'owner' is false, the interface is 1382381SN/A interested in the specified ranges for snooping purposes. If 1392381SN/A an object wants to own some ranges and snoop on others, it will 1402381SN/A need to use two different ports. 1412381SN/A */ 1422381SN/A virtual void getDeviceAddressRanges(AddrRangeList &range_list, 1432381SN/A bool &owner) 1442406SN/A { panic("??"); } 1452381SN/A 1462381SN/A public: 1472381SN/A 1482521SN/A /** Function called by associated memory device (cache, memory, iodevice) 1492521SN/A in order to send a timing request to the port. Simply calls the peer 1502381SN/A port receive function. 1512521SN/A @return This function returns if the send was succesful in it's 1522521SN/A recieve. If it was a failure, then the port will wait for a recvRetry 1532407SN/A at which point it can issue a successful sendTiming. This is used in 1542381SN/A case a cache has a higher priority request come in while waiting for 1552381SN/A the bus to arbitrate. 1562381SN/A */ 1572381SN/A bool sendTiming(Packet &pkt) { return peer->recvTiming(pkt); } 1582381SN/A 1592381SN/A /** Function called by the associated device to send an atomic access, 1602381SN/A an access in which the data is moved and the state is updated in one 1612381SN/A cycle, without interleaving with other memory accesses. 1622657Ssaidi@eecs.umich.edu */ 1632381SN/A Tick sendAtomic(Packet &pkt) 1642381SN/A { return peer->recvAtomic(pkt); } 1652381SN/A 1662630SN/A /** Function called by the associated device to send a functional access, 1672381SN/A an access in which the data is instantly updated everywhere in the 1682381SN/A memory system, without affecting the current state of any block or 1692381SN/A moving the block. 1702381SN/A */ 1712381SN/A void sendFunctional(Packet &pkt) 1722630SN/A { return peer->recvFunctional(pkt); } 1732381SN/A 1742381SN/A /** Called by the associated device to send a status change to the device 1752381SN/A connected to the peer interface. 1762381SN/A */ 1772520SN/A void sendStatusChange(Status status) {peer->recvStatusChange(status); } 1782520SN/A 1792381SN/A /** When a timing access doesn't return a success, some time later the 1802630SN/A Retry will be sent. 1812381SN/A */ 1822381SN/A Packet *sendRetry() { return peer->recvRetry(); } 1832381SN/A 1842381SN/A /** Called by the associated device if it wishes to find out the blocksize 1852381SN/A of the device on attached to the peer port. 1862381SN/A */ 1872381SN/A int peerBlockSize() { return peer->deviceBlockSize(); } 1882381SN/A 1892381SN/A /** Called by the associated device if it wishes to find out the address 1902381SN/A ranges connected to the peer ports devices. 1912657Ssaidi@eecs.umich.edu */ 1922381SN/A void getPeerAddressRanges(AddrRangeList &range_list, bool &owner) 1932381SN/A { peer->getDeviceAddressRanges(range_list, owner); } 1942381SN/A 1952381SN/A /** This function is a wrapper around sendFunctional() 1962406SN/A that breaks a larger, arbitrarily aligned access into 1972381SN/A appropriate chunks. The default implementation can use 1982381SN/A getBlockSize() to determine the block size and go from there. 1992381SN/A */ 2002381SN/A virtual void readBlob(Addr addr, uint8_t *p, int size); 2012521SN/A 2022521SN/A /** This function is a wrapper around sendFunctional() 2032381SN/A that breaks a larger, arbitrarily aligned access into 2042461SN/A appropriate chunks. The default implementation can use 2052461SN/A getBlockSize() to determine the block size and go from there. 2062461SN/A */ 2072461SN/A virtual void writeBlob(Addr addr, uint8_t *p, int size); 2082461SN/A 2092519SN/A /** Fill size bytes starting at addr with byte value val. This 2102381SN/A should not need to be virtual, since it can be implemented in 2112381SN/A terms of writeBlob(). However, it shouldn't be 2122381SN/A performance-critical either, so it could be if we wanted to. 2132381SN/A */ 2142381SN/A virtual void memsetBlob(Addr addr, uint8_t val, int size); 2152381SN/A 2162519SN/A private: 2172381SN/A 2182381SN/A /** Internal helper function for read/writeBlob(). 2192381SN/A */ 2202461SN/A void blobHelper(Addr addr, uint8_t *p, int size, Command cmd); 2212381SN/A}; 2222381SN/A 2232519SN/A/** A simple functional port that is only meant for one way communication to 2242405SN/A * physical memory. It is only meant to be used to load data into memory before 2252405SN/A * the simulation begins. 2262405SN/A */ 2272405SN/A 2282405SN/Aclass FunctionalPort : public Port 2292641Sstever@eecs.umich.edu{ 2302381SN/A public: 2312381SN/A virtual bool recvTiming(Packet &pkt) { panic("FuncPort is UniDir"); } 2322520SN/A virtual Tick recvAtomic(Packet &pkt) { panic("FuncPort is UniDir"); } 2332520SN/A virtual void recvFunctional(Packet &pkt) { panic("FuncPort is UniDir"); } 2342520SN/A virtual void recvStatusChange(Status status) {panic("FuncPort is UniDir");} 2352520SN/A}; 2362520SN/A 2372520SN/A 2382520SN/A#endif //__MEM_PORT_HH__ 2392520SN/A