port.hh revision 2590
16313Sgblack@eecs.umich.edu/* 26313Sgblack@eecs.umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan 36313Sgblack@eecs.umich.edu * All rights reserved. 46313Sgblack@eecs.umich.edu * 56313Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 66313Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 76313Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 86313Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 96313Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 106313Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 116313Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 126313Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 136313Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 146313Sgblack@eecs.umich.edu * this software without specific prior written permission. 156313Sgblack@eecs.umich.edu * 166313Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176313Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186313Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196313Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206313Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216313Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226313Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236313Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246313Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256313Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266313Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276313Sgblack@eecs.umich.edu */ 286313Sgblack@eecs.umich.edu 296313Sgblack@eecs.umich.edu/** 306313Sgblack@eecs.umich.edu * @file 316335Sgblack@eecs.umich.edu * Port Object Decleration. Ports are used to interface memory objects to 329377Sgblack@eecs.umich.edu * each other. They will always come in pairs, and we refer to the other 336313Sgblack@eecs.umich.edu * port object as the peer. These are used to make the design more 346335Sgblack@eecs.umich.edu * modular so that a specific interface between every type of objcet doesn't 356335Sgblack@eecs.umich.edu * have to be created. 366335Sgblack@eecs.umich.edu */ 376313Sgblack@eecs.umich.edu 388232Snate@binkert.org#ifndef __MEM_PORT_HH__ 398232Snate@binkert.org#define __MEM_PORT_HH__ 409384SAndreas.Sandberg@arm.com 416313Sgblack@eecs.umich.edu#include <list> 426313Sgblack@eecs.umich.edu#include <inttypes.h> 436313Sgblack@eecs.umich.edu 446313Sgblack@eecs.umich.edu#include "base/misc.hh" 458829Sgblack@eecs.umich.edu#include "base/range.hh" 468829Sgblack@eecs.umich.edu#include "mem/packet.hh" 476335Sgblack@eecs.umich.edu#include "mem/request.hh" 488829Sgblack@eecs.umich.edu 498829Sgblack@eecs.umich.edu/** This typedef is used to clean up the parameter list of 508829Sgblack@eecs.umich.edu * getDeviceAddressRanges() and getPeerAddressRanges(). It's declared 518829Sgblack@eecs.umich.edu * outside the Port object since it's also used by some mem objects. 528829Sgblack@eecs.umich.edu * Eventually we should move this typedef to wherever Addr is 538829Sgblack@eecs.umich.edu * defined. 548829Sgblack@eecs.umich.edu */ 558829Sgblack@eecs.umich.edu 568829Sgblack@eecs.umich.edutypedef std::list<Range<Addr> > AddrRangeList; 578829Sgblack@eecs.umich.edutypedef std::list<Range<Addr> >::iterator AddrRangeIter; 588829Sgblack@eecs.umich.edu 598829Sgblack@eecs.umich.edu/** 608829Sgblack@eecs.umich.edu * Ports are used to interface memory objects to 616335Sgblack@eecs.umich.edu * each other. They will always come in pairs, and we refer to the other 629384SAndreas.Sandberg@arm.com * port object as the peer. These are used to make the design more 639384SAndreas.Sandberg@arm.com * modular so that a specific interface between every type of objcet doesn't 649384SAndreas.Sandberg@arm.com * have to be created. 659384SAndreas.Sandberg@arm.com * 669384SAndreas.Sandberg@arm.com * Recv accesor functions are being called from the peer interface. 679384SAndreas.Sandberg@arm.com * Send accessor functions are being called from the device the port is 689384SAndreas.Sandberg@arm.com * associated with, and it will call the peer recv. accessor function. 699384SAndreas.Sandberg@arm.com */ 709384SAndreas.Sandberg@arm.comclass Port 719384SAndreas.Sandberg@arm.com{ 729384SAndreas.Sandberg@arm.com public: 739384SAndreas.Sandberg@arm.com 749384SAndreas.Sandberg@arm.com virtual ~Port() {}; 759384SAndreas.Sandberg@arm.com // mey be better to use subclasses & RTTI? 769384SAndreas.Sandberg@arm.com /** Holds the ports status. Keeps track if it is blocked, or has 779384SAndreas.Sandberg@arm.com calculated a range change. */ 786313Sgblack@eecs.umich.edu enum Status { 796337Sgblack@eecs.umich.edu Blocked, 806337Sgblack@eecs.umich.edu Unblocked, 816337Sgblack@eecs.umich.edu RangeChange 826337Sgblack@eecs.umich.edu }; 836337Sgblack@eecs.umich.edu 846337Sgblack@eecs.umich.edu private: 856337Sgblack@eecs.umich.edu 866337Sgblack@eecs.umich.edu /** A pointer to the peer port. Ports always come in pairs, that way they 876337Sgblack@eecs.umich.edu can use a standardized interface to communicate between different 886337Sgblack@eecs.umich.edu memory objects. */ 896337Sgblack@eecs.umich.edu Port *peer; 906337Sgblack@eecs.umich.edu 916337Sgblack@eecs.umich.edu public: 926337Sgblack@eecs.umich.edu 936337Sgblack@eecs.umich.edu /** Function to set the pointer for the peer port. 946337Sgblack@eecs.umich.edu @todo should be called by the configuration stuff (python). 956337Sgblack@eecs.umich.edu */ 966337Sgblack@eecs.umich.edu void setPeer(Port *port) { peer = port; } 976337Sgblack@eecs.umich.edu 986337Sgblack@eecs.umich.edu /** Function to set the pointer for the peer port. 996337Sgblack@eecs.umich.edu @todo should be called by the configuration stuff (python). 1006337Sgblack@eecs.umich.edu */ 1016337Sgblack@eecs.umich.edu Port *getPeer() { return peer; } 1026337Sgblack@eecs.umich.edu 1036337Sgblack@eecs.umich.edu protected: 1046337Sgblack@eecs.umich.edu 1056337Sgblack@eecs.umich.edu /** These functions are protected because they should only be 1066337Sgblack@eecs.umich.edu * called by a peer port, never directly by any outside object. */ 1076337Sgblack@eecs.umich.edu 1086337Sgblack@eecs.umich.edu /** Called to recive a timing call from the peer port. */ 1096337Sgblack@eecs.umich.edu virtual bool recvTiming(Packet &pkt) = 0; 1106337Sgblack@eecs.umich.edu 1116337Sgblack@eecs.umich.edu /** Called to recive a atomic call from the peer port. */ 1126337Sgblack@eecs.umich.edu virtual Tick recvAtomic(Packet &pkt) = 0; 1136313Sgblack@eecs.umich.edu 1146313Sgblack@eecs.umich.edu /** Called to recive a functional call from the peer port. */ 1156337Sgblack@eecs.umich.edu virtual void recvFunctional(Packet &pkt) = 0; 1166337Sgblack@eecs.umich.edu 1176337Sgblack@eecs.umich.edu /** Called to recieve a status change from the peer port. */ 1186337Sgblack@eecs.umich.edu virtual void recvStatusChange(Status status) = 0; 1197741Sgblack@eecs.umich.edu 1207741Sgblack@eecs.umich.edu /** Called by a peer port if the send was unsuccesful, and had to 1216335Sgblack@eecs.umich.edu wait. This shouldn't be valid for response paths (IO Devices). 1226335Sgblack@eecs.umich.edu so it is set to panic if it isn't already defined. 1236335Sgblack@eecs.umich.edu */ 1246335Sgblack@eecs.umich.edu virtual Packet *recvRetry() { panic("??"); } 1256335Sgblack@eecs.umich.edu 1266335Sgblack@eecs.umich.edu /** Called by a peer port in order to determine the block size of the 1276335Sgblack@eecs.umich.edu device connected to this port. It sometimes doesn't make sense for 1286335Sgblack@eecs.umich.edu this function to be called, a DMA interface doesn't really have a 1296335Sgblack@eecs.umich.edu block size, so it is defaulted to a panic. 1306335Sgblack@eecs.umich.edu */ 1316335Sgblack@eecs.umich.edu virtual int deviceBlockSize() { panic("??"); } 1326335Sgblack@eecs.umich.edu 1337703Sgblack@eecs.umich.edu /** The peer port is requesting us to reply with a list of the ranges we 1346335Sgblack@eecs.umich.edu are responsible for. 1356335Sgblack@eecs.umich.edu @param resp is a list of ranges responded to 1366335Sgblack@eecs.umich.edu @param snoop is a list of ranges snooped 1377741Sgblack@eecs.umich.edu */ 1387741Sgblack@eecs.umich.edu virtual void getDeviceAddressRanges(AddrRangeList &resp, 1397741Sgblack@eecs.umich.edu AddrRangeList &snoop) 1407741Sgblack@eecs.umich.edu { panic("??"); } 1417741Sgblack@eecs.umich.edu 1427741Sgblack@eecs.umich.edu public: 1438829Sgblack@eecs.umich.edu 1448829Sgblack@eecs.umich.edu /** Function called by associated memory device (cache, memory, iodevice) 1456335Sgblack@eecs.umich.edu in order to send a timing request to the port. Simply calls the peer 1466335Sgblack@eecs.umich.edu port receive function. 1476335Sgblack@eecs.umich.edu @return This function returns if the send was succesful in it's 1486335Sgblack@eecs.umich.edu recieve. If it was a failure, then the port will wait for a recvRetry 1497741Sgblack@eecs.umich.edu at which point it can issue a successful sendTiming. This is used in 1506335Sgblack@eecs.umich.edu case a cache has a higher priority request come in while waiting for 1516335Sgblack@eecs.umich.edu the bus to arbitrate. 1526335Sgblack@eecs.umich.edu */ 1536335Sgblack@eecs.umich.edu bool sendTiming(Packet &pkt) { return peer->recvTiming(pkt); } 1546335Sgblack@eecs.umich.edu 1556335Sgblack@eecs.umich.edu /** Function called by the associated device to send an atomic access, 1566335Sgblack@eecs.umich.edu an access in which the data is moved and the state is updated in one 1576335Sgblack@eecs.umich.edu cycle, without interleaving with other memory accesses. 1586335Sgblack@eecs.umich.edu */ 1597703Sgblack@eecs.umich.edu Tick sendAtomic(Packet &pkt) 1607703Sgblack@eecs.umich.edu { return peer->recvAtomic(pkt); } 1617703Sgblack@eecs.umich.edu 1627703Sgblack@eecs.umich.edu /** Function called by the associated device to send a functional access, 1637703Sgblack@eecs.umich.edu an access in which the data is instantly updated everywhere in the 1647703Sgblack@eecs.umich.edu memory system, without affecting the current state of any block or 1657703Sgblack@eecs.umich.edu moving the block. 1667703Sgblack@eecs.umich.edu */ 1677703Sgblack@eecs.umich.edu void sendFunctional(Packet &pkt) 1687703Sgblack@eecs.umich.edu { return peer->recvFunctional(pkt); } 1697703Sgblack@eecs.umich.edu 1707703Sgblack@eecs.umich.edu /** Called by the associated device to send a status change to the device 1717703Sgblack@eecs.umich.edu connected to the peer interface. 1727703Sgblack@eecs.umich.edu */ 1736313Sgblack@eecs.umich.edu void sendStatusChange(Status status) {peer->recvStatusChange(status); } 1746313Sgblack@eecs.umich.edu 1756313Sgblack@eecs.umich.edu /** When a timing access doesn't return a success, some time later the 1766313Sgblack@eecs.umich.edu Retry will be sent. 1776313Sgblack@eecs.umich.edu */ 1786335Sgblack@eecs.umich.edu Packet *sendRetry() { return peer->recvRetry(); } 1796335Sgblack@eecs.umich.edu 1806335Sgblack@eecs.umich.edu /** Called by the associated device if it wishes to find out the blocksize 1816335Sgblack@eecs.umich.edu of the device on attached to the peer port. 1826335Sgblack@eecs.umich.edu */ 1836335Sgblack@eecs.umich.edu int peerBlockSize() { return peer->deviceBlockSize(); } 1846335Sgblack@eecs.umich.edu 1856335Sgblack@eecs.umich.edu /** Called by the associated device if it wishes to find out the address 1866335Sgblack@eecs.umich.edu ranges connected to the peer ports devices. 1876335Sgblack@eecs.umich.edu */ 1886335Sgblack@eecs.umich.edu void getPeerAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) 1896335Sgblack@eecs.umich.edu { peer->getDeviceAddressRanges(resp, snoop); } 1906335Sgblack@eecs.umich.edu 1916335Sgblack@eecs.umich.edu /** This function is a wrapper around sendFunctional() 1926335Sgblack@eecs.umich.edu that breaks a larger, arbitrarily aligned access into 1936335Sgblack@eecs.umich.edu appropriate chunks. The default implementation can use 1946335Sgblack@eecs.umich.edu getBlockSize() to determine the block size and go from there. 1956335Sgblack@eecs.umich.edu */ 1966335Sgblack@eecs.umich.edu virtual void readBlob(Addr addr, uint8_t *p, int size); 1978829Sgblack@eecs.umich.edu 1988829Sgblack@eecs.umich.edu /** This function is a wrapper around sendFunctional() 1998829Sgblack@eecs.umich.edu that breaks a larger, arbitrarily aligned access into 2008829Sgblack@eecs.umich.edu appropriate chunks. The default implementation can use 2016335Sgblack@eecs.umich.edu getBlockSize() to determine the block size and go from there. 2026335Sgblack@eecs.umich.edu */ 2036335Sgblack@eecs.umich.edu virtual void writeBlob(Addr addr, uint8_t *p, int size); 2046335Sgblack@eecs.umich.edu 2056335Sgblack@eecs.umich.edu /** Fill size bytes starting at addr with byte value val. This 2066335Sgblack@eecs.umich.edu should not need to be virtual, since it can be implemented in 2076335Sgblack@eecs.umich.edu terms of writeBlob(). However, it shouldn't be 2086335Sgblack@eecs.umich.edu performance-critical either, so it could be if we wanted to. 2097741Sgblack@eecs.umich.edu */ 2106335Sgblack@eecs.umich.edu virtual void memsetBlob(Addr addr, uint8_t val, int size); 2117741Sgblack@eecs.umich.edu 2126335Sgblack@eecs.umich.edu private: 2137741Sgblack@eecs.umich.edu 2146335Sgblack@eecs.umich.edu /** Internal helper function for read/writeBlob(). 2156335Sgblack@eecs.umich.edu */ 2166335Sgblack@eecs.umich.edu void blobHelper(Addr addr, uint8_t *p, int size, Command cmd); 2176335Sgblack@eecs.umich.edu}; 2186335Sgblack@eecs.umich.edu 2196335Sgblack@eecs.umich.edu/** A simple functional port that is only meant for one way communication to 2206335Sgblack@eecs.umich.edu * physical memory. It is only meant to be used to load data into memory before 2216335Sgblack@eecs.umich.edu * the simulation begins. 2226335Sgblack@eecs.umich.edu */ 2236335Sgblack@eecs.umich.edu 2246335Sgblack@eecs.umich.educlass FunctionalPort : public Port 2256335Sgblack@eecs.umich.edu{ 2266335Sgblack@eecs.umich.edu public: 2276335Sgblack@eecs.umich.edu virtual bool recvTiming(Packet &pkt) { panic("FuncPort is UniDir"); } 2286335Sgblack@eecs.umich.edu virtual Tick recvAtomic(Packet &pkt) { panic("FuncPort is UniDir"); } 2296335Sgblack@eecs.umich.edu virtual void recvFunctional(Packet &pkt) { panic("FuncPort is UniDir"); } 2306335Sgblack@eecs.umich.edu virtual void recvStatusChange(Status status) {} 2316335Sgblack@eecs.umich.edu 2326335Sgblack@eecs.umich.edu template <typename T> 2336335Sgblack@eecs.umich.edu inline void write(Addr addr, T d) 2346335Sgblack@eecs.umich.edu { 2356335Sgblack@eecs.umich.edu writeBlob(addr, (uint8_t*)&d, sizeof(T)); 2366335Sgblack@eecs.umich.edu } 2376335Sgblack@eecs.umich.edu 2386335Sgblack@eecs.umich.edu template <typename T> 2396335Sgblack@eecs.umich.edu inline T read(Addr addr) 2406335Sgblack@eecs.umich.edu { 2416335Sgblack@eecs.umich.edu T d; 2426335Sgblack@eecs.umich.edu readBlob(addr, (uint8_t*)&d, sizeof(T)); 2436335Sgblack@eecs.umich.edu return d; 2446335Sgblack@eecs.umich.edu } 2456335Sgblack@eecs.umich.edu}; 2466335Sgblack@eecs.umich.edu 2476335Sgblack@eecs.umich.edu#endif //__MEM_PORT_HH__ 2486335Sgblack@eecs.umich.edu