port.hh revision 8709:d7358736ac70
1/* 2 * Copyright (c) 2002-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Ron Dreslinski 29 */ 30 31/** 32 * @file 33 * Port Object Declaration. Ports are used to interface memory objects to 34 * each other. They will always come in pairs, and we refer to the other 35 * port object as the peer. These are used to make the design more 36 * modular so that a specific interface between every type of objcet doesn't 37 * have to be created. 38 */ 39 40#ifndef __MEM_PORT_HH__ 41#define __MEM_PORT_HH__ 42 43#include <list> 44 45#include "base/misc.hh" 46#include "base/range.hh" 47#include "base/types.hh" 48#include "mem/packet.hh" 49#include "mem/request.hh" 50 51/** This typedef is used to clean up the parameter list of 52 * getDeviceAddressRanges() and getPeerAddressRanges(). It's declared 53 * outside the Port object since it's also used by some mem objects. 54 * Eventually we should move this typedef to wherever Addr is 55 * defined. 56 */ 57 58typedef std::list<Range<Addr> > AddrRangeList; 59typedef std::list<Range<Addr> >::iterator AddrRangeIter; 60 61class MemObject; 62 63/** 64 * Ports are used to interface memory objects to 65 * each other. They will always come in pairs, and we refer to the other 66 * port object as the peer. These are used to make the design more 67 * modular so that a specific interface between every type of objcet doesn't 68 * have to be created. 69 * 70 * Recv accesor functions are being called from the peer interface. 71 * Send accessor functions are being called from the device the port is 72 * associated with, and it will call the peer recv. accessor function. 73 */ 74class Port 75{ 76 protected: 77 /** Descriptive name (for DPRINTF output) */ 78 mutable std::string portName; 79 80 /** A pointer to the peer port. Ports always come in pairs, that way they 81 can use a standardized interface to communicate between different 82 memory objects. */ 83 Port *peer; 84 85 /** A pointer to the MemObject that owns this port. This may not be set. */ 86 MemObject *owner; 87 88 public: 89 /** 90 * Constructor. 91 * 92 * @param _name Port name for DPRINTF output. Should include name 93 * of memory system object to which the port belongs. 94 * @param _owner Pointer to the MemObject that owns this port. 95 * Will not necessarily be set. 96 */ 97 Port(const std::string &_name, MemObject *_owner); 98 99 /** Return port name (for DPRINTF). */ 100 const std::string &name() const { return portName; } 101 102 virtual ~Port(); 103 104 // mey be better to use subclasses & RTTI? 105 /** Holds the ports status. Currently just that a range recomputation needs 106 * to be done. */ 107 enum Status { 108 RangeChange 109 }; 110 111 void setName(const std::string &name) 112 { portName = name; } 113 114 /** Function to set the pointer for the peer port. */ 115 virtual void setPeer(Port *port); 116 117 /** Function to get the pointer to the peer port. */ 118 Port *getPeer() { return peer; } 119 120 /** Function to set the owner of this port. */ 121 void setOwner(MemObject *_owner); 122 123 /** Function to return the owner of this port. */ 124 MemObject *getOwner() { return owner; } 125 126 /** Inform the peer port to delete itself and notify it's owner about it's 127 * demise. */ 128 void removeConn(); 129 130 bool isConnected() { return peer != NULL; } 131 132 protected: 133 134 /** These functions are protected because they should only be 135 * called by a peer port, never directly by any outside object. */ 136 137 /** Called to recive a timing call from the peer port. */ 138 virtual bool recvTiming(PacketPtr pkt) = 0; 139 140 /** Called to recive a atomic call from the peer port. */ 141 virtual Tick recvAtomic(PacketPtr pkt) = 0; 142 143 /** Called to recive a functional call from the peer port. */ 144 virtual void recvFunctional(PacketPtr pkt) = 0; 145 146 /** Called to recieve a status change from the peer port. */ 147 virtual void recvStatusChange(Status status) = 0; 148 149 /** Called by a peer port if the send was unsuccesful, and had to 150 wait. This shouldn't be valid for response paths (IO Devices). 151 so it is set to panic if it isn't already defined. 152 */ 153 virtual void recvRetry() { panic("??"); } 154 155 /** Called by a peer port in order to determine the block size of the 156 device connected to this port. It sometimes doesn't make sense for 157 this function to be called, so it just returns 0. Anytthing that is 158 concerned with the size should just ignore that. 159 */ 160 virtual unsigned deviceBlockSize() const { return 0; } 161 162 /** The peer port is requesting us to reply with a list of the ranges we 163 are responsible for. 164 @param resp is a list of ranges responded to 165 @param snoop is a list of ranges snooped 166 */ 167 virtual void getDeviceAddressRanges(AddrRangeList &resp, 168 bool &snoop) 169 { panic("??"); } 170 171 public: 172 173 /** Function called by associated memory device (cache, memory, iodevice) 174 in order to send a timing request to the port. Simply calls the peer 175 port receive function. 176 @return This function returns if the send was succesful in it's 177 recieve. If it was a failure, then the port will wait for a recvRetry 178 at which point it can possibly issue a successful sendTiming. This is used in 179 case a cache has a higher priority request come in while waiting for 180 the bus to arbitrate. 181 */ 182 bool sendTiming(PacketPtr pkt) { return peer->recvTiming(pkt); } 183 184 /** Function called by the associated device to send an atomic 185 * access, an access in which the data is moved and the state is 186 * updated in one cycle, without interleaving with other memory 187 * accesses. Returns estimated latency of access. 188 */ 189 Tick sendAtomic(PacketPtr pkt) 190 { return peer->recvAtomic(pkt); } 191 192 /** Function called by the associated device to send a functional access, 193 an access in which the data is instantly updated everywhere in the 194 memory system, without affecting the current state of any block or 195 moving the block. 196 */ 197 void sendFunctional(PacketPtr pkt) 198 { return peer->recvFunctional(pkt); } 199 200 /** Called by the associated device to send a status change to the device 201 connected to the peer interface. 202 */ 203 void sendStatusChange(Status status) {peer->recvStatusChange(status); } 204 205 /** When a timing access doesn't return a success, some time later the 206 Retry will be sent. 207 */ 208 void sendRetry() { return peer->recvRetry(); } 209 210 /** Called by the associated device if it wishes to find out the blocksize 211 of the device on attached to the peer port. 212 */ 213 unsigned peerBlockSize() const { return peer->deviceBlockSize(); } 214 215 /** Called by the associated device if it wishes to find out the address 216 ranges connected to the peer ports devices. 217 */ 218 void getPeerAddressRanges(AddrRangeList &resp, bool &snoop) 219 { peer->getDeviceAddressRanges(resp, snoop); } 220 221 /** This function is a wrapper around sendFunctional() 222 that breaks a larger, arbitrarily aligned access into 223 appropriate chunks. The default implementation can use 224 getBlockSize() to determine the block size and go from there. 225 */ 226 virtual void readBlob(Addr addr, uint8_t *p, int size); 227 228 /** This function is a wrapper around sendFunctional() 229 that breaks a larger, arbitrarily aligned access into 230 appropriate chunks. The default implementation can use 231 getBlockSize() to determine the block size and go from there. 232 */ 233 virtual void writeBlob(Addr addr, uint8_t *p, int size); 234 235 /** Fill size bytes starting at addr with byte value val. This 236 should not need to be virtual, since it can be implemented in 237 terms of writeBlob(). However, it shouldn't be 238 performance-critical either, so it could be if we wanted to. 239 */ 240 virtual void memsetBlob(Addr addr, uint8_t val, int size); 241 242 /** Inject a PrintReq for the given address to print the state of 243 * that address throughout the memory system. For debugging. 244 */ 245 void printAddr(Addr a); 246 247 private: 248 249 /** Internal helper function for read/writeBlob(). 250 */ 251 void blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd); 252}; 253 254#endif //__MEM_PORT_HH__ 255