port.hh revision 9325
12440SN/A/* 22440SN/A * Copyright (c) 2011-2012 ARM Limited 32440SN/A * All rights reserved 42440SN/A * 52440SN/A * The license below extends only to copyright in the software and shall 62440SN/A * not be construed as granting a license to any other intellectual 72440SN/A * property including but not limited to intellectual property relating 82440SN/A * to a hardware implementation of the functionality of the software 92440SN/A * licensed hereunder. You may use the software subject to the license 102440SN/A * terms below provided that you ensure that this notice is replicated 112440SN/A * unmodified and in its entirety in all distributions of the software, 122440SN/A * modified or unmodified, in source code or in binary form. 132440SN/A * 142440SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 152440SN/A * All rights reserved. 162440SN/A * 172440SN/A * Redistribution and use in source and binary forms, with or without 182440SN/A * modification, are permitted provided that the following conditions are 192440SN/A * met: redistributions of source code must retain the above copyright 202440SN/A * notice, this list of conditions and the following disclaimer; 212440SN/A * redistributions in binary form must reproduce the above copyright 222440SN/A * notice, this list of conditions and the following disclaimer in the 232440SN/A * documentation and/or other materials provided with the distribution; 242440SN/A * neither the name of the copyright holders nor the names of its 252440SN/A * contributors may be used to endorse or promote products derived from 262440SN/A * this software without specific prior written permission. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 292665Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 302440SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 312440SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 322440SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 332440SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 342440SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 352440SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 362440SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 372972Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 382460SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 392440SN/A * 403120Sgblack@eecs.umich.edu * Authors: Ron Dreslinski 412440SN/A * Andreas Hansson 422440SN/A * William Wang 432440SN/A */ 442440SN/A 453577Sgblack@eecs.umich.edu/** 463577Sgblack@eecs.umich.edu * @file 473577Sgblack@eecs.umich.edu * Port Object Declaration. 484172Ssaidi@eecs.umich.edu */ 493577Sgblack@eecs.umich.edu 503577Sgblack@eecs.umich.edu#ifndef __MEM_PORT_HH__ 512440SN/A#define __MEM_PORT_HH__ 523484Sktlim@umich.edu 532440SN/A#include <list> 542440SN/A 553484Sktlim@umich.edu#include "base/addr_range.hh" 563484Sktlim@umich.edu#include "mem/packet.hh" 572440SN/A 582440SN/A/** 592440SN/A * This typedef is used to clean up getAddrRanges(). It's declared 602440SN/A * outside the Port object since it's also used by some mem objects. 612440SN/A * Eventually we should move this typedef to wherever Addr is 622440SN/A * defined. 632440SN/A */ 642467SN/A 652440SN/Atypedef std::list<AddrRange> AddrRangeList; 662440SN/Atypedef std::list<AddrRange>::iterator AddrRangeIter; 672440SN/Atypedef std::list<AddrRange>::const_iterator AddrRangeConstIter; 682440SN/A 692467SN/Aclass MemObject; 702440SN/A 712440SN/A/** 722440SN/A * Ports are used to interface memory objects to each other. A port is 732440SN/A * either a master or a slave and the connected peer is always of the 742467SN/A * opposite role. Each port has a name, an owner, and an identifier. 752440SN/A */ 762440SN/Aclass Port 772440SN/A{ 782440SN/A 792467SN/A private: 802440SN/A 812440SN/A /** Descriptive name (for DPRINTF output) */ 822440SN/A std::string portName; 832440SN/A 842467SN/A protected: 852440SN/A 862440SN/A /** 872440SN/A * A numeric identifier to distinguish ports in a vector, and set 882440SN/A * to InvalidPortID in case this port is not part of a vector. 892440SN/A */ 902467SN/A const PortID id; 912440SN/A 922440SN/A /** A reference to the MemObject that owns this port. */ 932440SN/A MemObject& owner; 942467SN/A 952440SN/A /** 962440SN/A * Abstract base class for ports 972440SN/A * 982440SN/A * @param _name Port name including the owners name 992440SN/A * @param _owner The MemObject that is the structural owner of this port 1002467SN/A * @param _id A port identifier for vector ports 1012440SN/A */ 1022440SN/A Port(const std::string& _name, MemObject& _owner, PortID _id); 1032440SN/A 1042467SN/A /** 1052440SN/A * Virtual destructor due to inheritance. 1062440SN/A */ 1072440SN/A virtual ~Port(); 1082440SN/A 1092440SN/A public: 1102440SN/A 1112440SN/A /** Return port name (for DPRINTF). */ 1122440SN/A const std::string name() const { return portName; } 1132440SN/A 1142440SN/A /** Get the port id. */ 1152440SN/A PortID getId() const { return id; } 1162440SN/A 1172440SN/A}; 1182440SN/A 1192680Sktlim@umich.edu/** Forward declaration */ 1202440SN/Aclass BaseSlavePort; 1212680Sktlim@umich.edu 1222680Sktlim@umich.edu/** 1232440SN/A * A BaseMasterPort is a protocol-agnostic master port, responsible 1243961Sgblack@eecs.umich.edu * only for the structural connection to a slave port. The final 1253961Sgblack@eecs.umich.edu * master port that inherits from the base class must override the 1262440SN/A * bind member function for the specific slave port class. 1272440SN/A */ 1282440SN/Aclass BaseMasterPort : public Port 1292440SN/A{ 1302440SN/A 1312440SN/A protected: 1322440SN/A 1332467SN/A BaseSlavePort* _baseSlavePort; 1342440SN/A 1352440SN/A BaseMasterPort(const std::string& name, MemObject* owner, 1362467SN/A PortID id = InvalidPortID); 1372440SN/A virtual ~BaseMasterPort(); 1382440SN/A 1392467SN/A public: 1402467SN/A 1412440SN/A virtual void bind(BaseSlavePort& slave_port) = 0; 1422440SN/A virtual void unbind() = 0; 1432467SN/A BaseSlavePort& getSlavePort() const; 1442440SN/A bool isConnected() const; 1452467SN/A 1462440SN/A}; 1472440SN/A 1482440SN/A/** 1492467SN/A * A BaseSlavePort is a protocol-agnostic slave port, responsible 1502440SN/A * only for the structural connection to a master port. 1512440SN/A */ 1522440SN/Aclass BaseSlavePort : public Port 1532680Sktlim@umich.edu{ 1542680Sktlim@umich.edu 1552440SN/A protected: 1562440SN/A 1572440SN/A BaseMasterPort* _baseMasterPort; 1582680Sktlim@umich.edu 1592440SN/A BaseSlavePort(const std::string& name, MemObject* owner, 1602680Sktlim@umich.edu PortID id = InvalidPortID); 1612680Sktlim@umich.edu virtual ~BaseSlavePort(); 1622440SN/A 1632440SN/A public: 1642440SN/A 1652440SN/A BaseMasterPort& getMasterPort() const; 1662440SN/A bool isConnected() const; 167 168}; 169 170/** Forward declaration */ 171class SlavePort; 172 173/** 174 * A MasterPort is a specialisation of a BaseMasterPort, which 175 * implements the default protocol for the three different level of 176 * transport functions. In addition to the basic functionality of 177 * sending packets, it also has functions to receive range changes or 178 * determine if the port is snooping or not. 179 */ 180class MasterPort : public BaseMasterPort 181{ 182 183 friend class SlavePort; 184 185 private: 186 187 SlavePort* _slavePort; 188 189 public: 190 191 MasterPort(const std::string& name, MemObject* owner, 192 PortID id = InvalidPortID); 193 virtual ~MasterPort(); 194 195 /** 196 * Bind this master port to a slave port. This also does the 197 * mirror action and binds the slave port to the master port. 198 */ 199 void bind(BaseSlavePort& slave_port); 200 201 /** 202 * Unbind this master port and the associated slave port. 203 */ 204 void unbind(); 205 206 /** 207 * Send an atomic request packet, where the data is moved and the 208 * state is updated in zero time, without interleaving with other 209 * memory accesses. 210 * 211 * @param pkt Packet to send. 212 * 213 * @return Estimated latency of access. 214 */ 215 Tick sendAtomic(PacketPtr pkt); 216 217 /** 218 * Send a functional request packet, where the data is instantly 219 * updated everywhere in the memory system, without affecting the 220 * current state of any block or moving the block. 221 * 222 * @param pkt Packet to send. 223 */ 224 void sendFunctional(PacketPtr pkt); 225 226 /** 227 * Attempt to send a timing request to the slave port by calling 228 * its corresponding receive function. If the send does not 229 * succeed, as indicated by the return value, then the sender must 230 * wait for a recvRetry at which point it can re-issue a 231 * sendTimingReq. 232 * 233 * @param pkt Packet to send. 234 * 235 * @return If the send was succesful or not. 236 */ 237 bool sendTimingReq(PacketPtr pkt); 238 239 /** 240 * Attempt to send a timing snoop response packet to the slave 241 * port by calling its corresponding receive function. If the send 242 * does not succeed, as indicated by the return value, then the 243 * sender must wait for a recvRetry at which point it can re-issue 244 * a sendTimingSnoopResp. 245 * 246 * @param pkt Packet to send. 247 */ 248 bool sendTimingSnoopResp(PacketPtr pkt); 249 250 /** 251 * Send a retry to the slave port that previously attempted a 252 * sendTimingResp to this master port and failed. 253 */ 254 void sendRetry(); 255 256 /** 257 * Determine if this master port is snooping or not. The default 258 * implementation returns false and thus tells the neighbour we 259 * are not snooping. Any master port that wants to receive snoop 260 * requests (e.g. a cache connected to a bus) has to override this 261 * function. 262 * 263 * @return true if the port should be considered a snooper 264 */ 265 virtual bool isSnooping() const { return false; } 266 267 /** 268 * Called by a peer port in order to determine the block size of 269 * the owner of this port. 270 */ 271 virtual unsigned deviceBlockSize() const { return 0; } 272 273 /** Called by the associated device if it wishes to find out the blocksize 274 of the device on attached to the peer port. 275 */ 276 unsigned peerBlockSize() const; 277 278 /** 279 * Get the address ranges of the connected slave port. 280 */ 281 AddrRangeList getAddrRanges() const; 282 283 /** Inject a PrintReq for the given address to print the state of 284 * that address throughout the memory system. For debugging. 285 */ 286 void printAddr(Addr a); 287 288 protected: 289 290 /** 291 * Receive an atomic snoop request packet from the slave port. 292 */ 293 virtual Tick recvAtomicSnoop(PacketPtr pkt) 294 { 295 panic("%s was not expecting an atomic snoop request\n", name()); 296 return 0; 297 } 298 299 /** 300 * Receive a functional snoop request packet from the slave port. 301 */ 302 virtual void recvFunctionalSnoop(PacketPtr pkt) 303 { 304 panic("%s was not expecting a functional snoop request\n", name()); 305 } 306 307 /** 308 * Receive a timing response from the slave port. 309 */ 310 virtual bool recvTimingResp(PacketPtr pkt) = 0; 311 312 /** 313 * Receive a timing snoop request from the slave port. 314 */ 315 virtual void recvTimingSnoopReq(PacketPtr pkt) 316 { 317 panic("%s was not expecting a timing snoop request\n", name()); 318 } 319 320 /** 321 * Called by the slave port if sendTimingReq or 322 * sendTimingSnoopResp was called on this master port (causing 323 * recvTimingReq and recvTimingSnoopResp to be called on the 324 * slave port) and was unsuccesful. 325 */ 326 virtual void recvRetry() = 0; 327 328 /** 329 * Called to receive an address range change from the peer slave 330 * port. The default implementation ignores the change and does 331 * nothing. Override this function in a derived class if the owner 332 * needs to be aware of the address ranges, e.g. in an 333 * interconnect component like a bus. 334 */ 335 virtual void recvRangeChange() { } 336}; 337 338/** 339 * A SlavePort is a specialisation of a port. In addition to the 340 * basic functionality of sending packets to its master peer, it also 341 * has functions specific to a slave, e.g. to send range changes 342 * and get the address ranges that the port responds to. 343 */ 344class SlavePort : public BaseSlavePort 345{ 346 347 friend class MasterPort; 348 349 private: 350 351 MasterPort* _masterPort; 352 353 public: 354 355 SlavePort(const std::string& name, MemObject* owner, 356 PortID id = InvalidPortID); 357 virtual ~SlavePort(); 358 359 /** 360 * Send an atomic snoop request packet, where the data is moved 361 * and the state is updated in zero time, without interleaving 362 * with other memory accesses. 363 * 364 * @param pkt Snoop packet to send. 365 * 366 * @return Estimated latency of access. 367 */ 368 Tick sendAtomicSnoop(PacketPtr pkt); 369 370 /** 371 * Send a functional snoop request packet, where the data is 372 * instantly updated everywhere in the memory system, without 373 * affecting the current state of any block or moving the block. 374 * 375 * @param pkt Snoop packet to send. 376 */ 377 void sendFunctionalSnoop(PacketPtr pkt); 378 379 /** 380 * Attempt to send a timing response to the master port by calling 381 * its corresponding receive function. If the send does not 382 * succeed, as indicated by the return value, then the sender must 383 * wait for a recvRetry at which point it can re-issue a 384 * sendTimingResp. 385 * 386 * @param pkt Packet to send. 387 * 388 * @return If the send was succesful or not. 389 */ 390 bool sendTimingResp(PacketPtr pkt); 391 392 /** 393 * Attempt to send a timing snoop request packet to the master port 394 * by calling its corresponding receive function. Snoop requests 395 * always succeed and hence no return value is needed. 396 * 397 * @param pkt Packet to send. 398 */ 399 void sendTimingSnoopReq(PacketPtr pkt); 400 401 /** 402 * Send a retry to the master port that previously attempted a 403 * sendTimingReq or sendTimingSnoopResp to this slave port and 404 * failed. 405 */ 406 void sendRetry(); 407 408 /** 409 * Called by a peer port in order to determine the block size of 410 * the owner of this port. 411 */ 412 virtual unsigned deviceBlockSize() const { return 0; } 413 414 /** Called by the associated device if it wishes to find out the blocksize 415 of the device on attached to the peer port. 416 */ 417 unsigned peerBlockSize() const; 418 419 /** 420 * Find out if the peer master port is snooping or not. 421 * 422 * @return true if the peer master port is snooping 423 */ 424 bool isSnooping() const { return _masterPort->isSnooping(); } 425 426 /** 427 * Called by the owner to send a range change 428 */ 429 void sendRangeChange() const { _masterPort->recvRangeChange(); } 430 431 /** 432 * Get a list of the non-overlapping address ranges the owner is 433 * responsible for. All slave ports must override this function 434 * and return a populated list with at least one item. 435 * 436 * @return a list of ranges responded to 437 */ 438 virtual AddrRangeList getAddrRanges() const = 0; 439 440 protected: 441 442 /** 443 * Called by the master port to unbind. Should never be called 444 * directly. 445 */ 446 void unbind(); 447 448 /** 449 * Called by the master port to bind. Should never be called 450 * directly. 451 */ 452 void bind(MasterPort& master_port); 453 454 /** 455 * Receive an atomic request packet from the master port. 456 */ 457 virtual Tick recvAtomic(PacketPtr pkt) = 0; 458 459 /** 460 * Receive a functional request packet from the master port. 461 */ 462 virtual void recvFunctional(PacketPtr pkt) = 0; 463 464 /** 465 * Receive a timing request from the master port. 466 */ 467 virtual bool recvTimingReq(PacketPtr pkt) = 0; 468 469 /** 470 * Receive a timing snoop response from the master port. 471 */ 472 virtual bool recvTimingSnoopResp(PacketPtr pkt) 473 { 474 panic("%s was not expecting a timing snoop response\n", name()); 475 } 476 477 /** 478 * Called by the master port if sendTimingResp was called on this 479 * slave port (causing recvTimingResp to be called on the master 480 * port) and was unsuccesful. 481 */ 482 virtual void recvRetry() = 0; 483 484}; 485 486#endif //__MEM_PORT_HH__ 487