1/* 2 * Copyright (c) 2011-2012,2015,2017 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Copyright (c) 2002-2005 The Regents of The University of Michigan 15 * All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions are 19 * met: redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer; 21 * redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution; 24 * neither the name of the copyright holders nor the names of its 25 * contributors may be used to endorse or promote products derived from 26 * this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 * 40 * Authors: Ron Dreslinski 41 * Andreas Hansson 42 * William Wang 43 */ 44 45/** 46 * @file 47 * Port Object Declaration. 48 */ 49 50#ifndef __MEM_PORT_HH__ 51#define __MEM_PORT_HH__ 52 53#include "base/addr_range.hh" 54#include "mem/packet.hh" 55#include "mem/protocol/atomic.hh" 56#include "mem/protocol/functional.hh" 57#include "mem/protocol/timing.hh" 58#include "sim/port.hh" 59 60class SimObject; 61 62/** Forward declaration */ 63class BaseSlavePort; 64 65/** 66 * A BaseMasterPort is a protocol-agnostic master port, responsible 67 * only for the structural connection to a slave port. The final 68 * master port that inherits from the base class must override the 69 * bind member function for the specific slave port class. 70 */ 71class BaseMasterPort : public Port 72{ 73 protected: 74 BaseSlavePort *_baseSlavePort; 75 76 BaseMasterPort(const std::string &name, PortID id=InvalidPortID); 77 virtual ~BaseMasterPort(); 78 79 public: 80 BaseSlavePort& getSlavePort() const;
| 1/* 2 * Copyright (c) 2011-2012,2015,2017 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Copyright (c) 2002-2005 The Regents of The University of Michigan 15 * All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions are 19 * met: redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer; 21 * redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution; 24 * neither the name of the copyright holders nor the names of its 25 * contributors may be used to endorse or promote products derived from 26 * this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 * 40 * Authors: Ron Dreslinski 41 * Andreas Hansson 42 * William Wang 43 */ 44 45/** 46 * @file 47 * Port Object Declaration. 48 */ 49 50#ifndef __MEM_PORT_HH__ 51#define __MEM_PORT_HH__ 52 53#include "base/addr_range.hh" 54#include "mem/packet.hh" 55#include "mem/protocol/atomic.hh" 56#include "mem/protocol/functional.hh" 57#include "mem/protocol/timing.hh" 58#include "sim/port.hh" 59 60class SimObject; 61 62/** Forward declaration */ 63class BaseSlavePort; 64 65/** 66 * A BaseMasterPort is a protocol-agnostic master port, responsible 67 * only for the structural connection to a slave port. The final 68 * master port that inherits from the base class must override the 69 * bind member function for the specific slave port class. 70 */ 71class BaseMasterPort : public Port 72{ 73 protected: 74 BaseSlavePort *_baseSlavePort; 75 76 BaseMasterPort(const std::string &name, PortID id=InvalidPortID); 77 virtual ~BaseMasterPort(); 78 79 public: 80 BaseSlavePort& getSlavePort() const;
|
97}; 98 99/** Forward declaration */ 100class SlavePort; 101 102/** 103 * A MasterPort is a specialisation of a BaseMasterPort, which 104 * implements the default protocol for the three different level of 105 * transport functions. In addition to the basic functionality of 106 * sending packets, it also has functions to receive range changes or 107 * determine if the port is snooping or not. 108 * 109 * The three protocols are atomic, timing, and functional, each with its own 110 * header file. 111 */ 112class MasterPort : public BaseMasterPort, public AtomicRequestProtocol, 113 public TimingRequestProtocol, public FunctionalRequestProtocol 114{ 115 friend class SlavePort; 116 117 private: 118 SlavePort *_slavePort; 119 120 protected: 121 SimObject &owner; 122 123 public: 124 MasterPort(const std::string& name, SimObject* _owner, 125 PortID id=InvalidPortID); 126 virtual ~MasterPort(); 127 128 /** 129 * Bind this master port to a slave port. This also does the 130 * mirror action and binds the slave port to the master port. 131 */ 132 void bind(Port &peer) override; 133 134 /** 135 * Unbind this master port and the associated slave port. 136 */ 137 void unbind() override; 138 139 /** 140 * Determine if this master port is snooping or not. The default 141 * implementation returns false and thus tells the neighbour we 142 * are not snooping. Any master port that wants to receive snoop 143 * requests (e.g. a cache connected to a bus) has to override this 144 * function. 145 * 146 * @return true if the port should be considered a snooper 147 */ 148 virtual bool isSnooping() const { return false; } 149 150 /** 151 * Get the address ranges of the connected slave port. 152 */ 153 AddrRangeList getAddrRanges() const; 154 155 /** 156 * Inject a PrintReq for the given address to print the state of 157 * that address throughout the memory system. For debugging. 158 */ 159 void printAddr(Addr a); 160 161 public: 162 /* The atomic protocol. */ 163 164 /** 165 * Send an atomic request packet, where the data is moved and the 166 * state is updated in zero time, without interleaving with other 167 * memory accesses. 168 * 169 * @param pkt Packet to send. 170 * 171 * @return Estimated latency of access. 172 */ 173 Tick sendAtomic(PacketPtr pkt); 174 175 /** 176 * Send an atomic request packet like above, but also request a backdoor 177 * to the data being accessed. 178 * 179 * @param pkt Packet to send. 180 * @param backdoor Can be set to a back door pointer by the target to let 181 * caller have direct access to the requested data. 182 * 183 * @return Estimated latency of access. 184 */ 185 Tick sendAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor); 186 187 public: 188 /* The functional protocol. */ 189 190 /** 191 * Send a functional request packet, where the data is instantly 192 * updated everywhere in the memory system, without affecting the 193 * current state of any block or moving the block. 194 * 195 * @param pkt Packet to send. 196 */ 197 void sendFunctional(PacketPtr pkt) const; 198 199 public: 200 /* The timing protocol. */ 201 202 /** 203 * Attempt to send a timing request to the slave port by calling 204 * its corresponding receive function. If the send does not 205 * succeed, as indicated by the return value, then the sender must 206 * wait for a recvReqRetry at which point it can re-issue a 207 * sendTimingReq. 208 * 209 * @param pkt Packet to send. 210 * 211 * @return If the send was succesful or not. 212 */ 213 bool sendTimingReq(PacketPtr pkt); 214 215 /** 216 * Check if the slave can handle a timing request. 217 * 218 * If the send cannot be handled at the moment, as indicated by 219 * the return value, then the sender will receive a recvReqRetry 220 * at which point it can re-issue a sendTimingReq. 221 * 222 * @param pkt Packet to send. 223 * 224 * @return If the send was succesful or not. 225 */ 226 bool tryTiming(PacketPtr pkt) const; 227 228 /** 229 * Attempt to send a timing snoop response packet to the slave 230 * port by calling its corresponding receive function. If the send 231 * does not succeed, as indicated by the return value, then the 232 * sender must wait for a recvRetrySnoop at which point it can 233 * re-issue a sendTimingSnoopResp. 234 * 235 * @param pkt Packet to send. 236 */ 237 bool sendTimingSnoopResp(PacketPtr pkt); 238 239 /** 240 * Send a retry to the slave port that previously attempted a 241 * sendTimingResp to this master port and failed. Note that this 242 * is virtual so that the "fake" snoop response port in the 243 * coherent crossbar can override the behaviour. 244 */ 245 virtual void sendRetryResp(); 246 247 protected: 248 /** 249 * Called to receive an address range change from the peer slave 250 * port. The default implementation ignores the change and does 251 * nothing. Override this function in a derived class if the owner 252 * needs to be aware of the address ranges, e.g. in an 253 * interconnect component like a bus. 254 */ 255 virtual void recvRangeChange() { } 256 257 /** 258 * Default implementations. 259 */ 260 Tick 261 recvAtomicSnoop(PacketPtr pkt) override 262 { 263 panic("%s was not expecting an atomic snoop request\n", name()); 264 return 0; 265 } 266 267 void 268 recvFunctionalSnoop(PacketPtr pkt) override 269 { 270 panic("%s was not expecting a functional snoop request\n", name()); 271 } 272 273 void 274 recvTimingSnoopReq(PacketPtr pkt) override 275 { 276 panic("%s was not expecting a timing snoop request.\n", name()); 277 } 278 279 void 280 recvRetrySnoopResp() override 281 { 282 panic("%s was not expecting a snoop retry.\n", name()); 283 } 284}; 285 286/** 287 * A SlavePort is a specialisation of a port. In addition to the 288 * basic functionality of sending packets to its master peer, it also 289 * has functions specific to a slave, e.g. to send range changes 290 * and get the address ranges that the port responds to. 291 * 292 * The three protocols are atomic, timing, and functional, each with its own 293 * header file. 294 */ 295class SlavePort : public BaseSlavePort, public AtomicResponseProtocol, 296 public TimingResponseProtocol, public FunctionalResponseProtocol 297{ 298 friend class MasterPort; 299 300 private: 301 MasterPort* _masterPort; 302 bool defaultBackdoorWarned; 303 304 protected: 305 SimObject& owner; 306 307 public: 308 SlavePort(const std::string& name, SimObject* _owner, 309 PortID id=InvalidPortID); 310 virtual ~SlavePort(); 311 312 /** 313 * Find out if the peer master port is snooping or not. 314 * 315 * @return true if the peer master port is snooping 316 */ 317 bool isSnooping() const { return _masterPort->isSnooping(); } 318 319 /** 320 * Called by the owner to send a range change 321 */ 322 void 323 sendRangeChange() const 324 { 325 fatal_if(!_masterPort, 326 "%s cannot sendRangeChange() without master port.", name()); 327 _masterPort->recvRangeChange(); 328 } 329 330 /** 331 * Get a list of the non-overlapping address ranges the owner is 332 * responsible for. All slave ports must override this function 333 * and return a populated list with at least one item. 334 * 335 * @return a list of ranges responded to 336 */ 337 virtual AddrRangeList getAddrRanges() const = 0; 338 339 /** 340 * We let the master port do the work, so these don't do anything. 341 */ 342 void unbind() override {} 343 void bind(Port &peer) override {} 344 345 public: 346 /* The atomic protocol. */ 347 348 /** 349 * Send an atomic snoop request packet, where the data is moved 350 * and the state is updated in zero time, without interleaving 351 * with other memory accesses. 352 * 353 * @param pkt Snoop packet to send. 354 * 355 * @return Estimated latency of access. 356 */ 357 Tick 358 sendAtomicSnoop(PacketPtr pkt) 359 { 360 return AtomicResponseProtocol::sendSnoop(_masterPort, pkt); 361 } 362 363 public: 364 /* The functional protocol. */ 365 366 /** 367 * Send a functional snoop request packet, where the data is 368 * instantly updated everywhere in the memory system, without 369 * affecting the current state of any block or moving the block. 370 * 371 * @param pkt Snoop packet to send. 372 */ 373 void 374 sendFunctionalSnoop(PacketPtr pkt) const 375 { 376 FunctionalResponseProtocol::sendSnoop(_masterPort, pkt); 377 } 378 379 public: 380 /* The timing protocol. */ 381 382 /** 383 * Attempt to send a timing response to the master port by calling 384 * its corresponding receive function. If the send does not 385 * succeed, as indicated by the return value, then the sender must 386 * wait for a recvRespRetry at which point it can re-issue a 387 * sendTimingResp. 388 * 389 * @param pkt Packet to send. 390 * 391 * @return If the send was succesful or not. 392 */ 393 bool 394 sendTimingResp(PacketPtr pkt) 395 { 396 return TimingResponseProtocol::sendResp(_masterPort, pkt); 397 } 398 399 /** 400 * Attempt to send a timing snoop request packet to the master port 401 * by calling its corresponding receive function. Snoop requests 402 * always succeed and hence no return value is needed. 403 * 404 * @param pkt Packet to send. 405 */ 406 void 407 sendTimingSnoopReq(PacketPtr pkt) 408 { 409 TimingResponseProtocol::sendSnoopReq(_masterPort, pkt); 410 } 411 412 /** 413 * Send a retry to the master port that previously attempted a 414 * sendTimingReq to this slave port and failed. 415 */ 416 void 417 sendRetryReq() 418 { 419 TimingResponseProtocol::sendRetryReq(_masterPort); 420 } 421 422 /** 423 * Send a retry to the master port that previously attempted a 424 * sendTimingSnoopResp to this slave port and failed. 425 */ 426 void 427 sendRetrySnoopResp() 428 { 429 TimingResponseProtocol::sendRetrySnoopResp(_masterPort); 430 } 431 432 protected: 433 /** 434 * Called by the master port to unbind. Should never be called 435 * directly. 436 */ 437 void slaveUnbind(); 438 439 /** 440 * Called by the master port to bind. Should never be called 441 * directly. 442 */ 443 void slaveBind(MasterPort& master_port); 444 445 /** 446 * Default implementations. 447 */ 448 Tick recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor) override; 449 450 bool 451 tryTiming(PacketPtr pkt) override 452 { 453 panic("%s was not expecting a %s\n", name(), __func__); 454 } 455 456 bool 457 recvTimingSnoopResp(PacketPtr pkt) override 458 { 459 panic("%s was not expecting a timing snoop response\n", name()); 460 } 461}; 462 463inline Tick 464MasterPort::sendAtomic(PacketPtr pkt) 465{ 466 return AtomicRequestProtocol::send(_slavePort, pkt); 467} 468 469inline Tick 470MasterPort::sendAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor) 471{ 472 return AtomicRequestProtocol::sendBackdoor(_slavePort, pkt, backdoor); 473} 474 475inline void 476MasterPort::sendFunctional(PacketPtr pkt) const 477{ 478 return FunctionalRequestProtocol::send(_slavePort, pkt); 479} 480 481inline bool 482MasterPort::sendTimingReq(PacketPtr pkt) 483{ 484 return TimingRequestProtocol::sendReq(_slavePort, pkt); 485} 486 487inline bool 488MasterPort::tryTiming(PacketPtr pkt) const 489{ 490 return TimingRequestProtocol::trySend(_slavePort, pkt); 491} 492 493inline bool 494MasterPort::sendTimingSnoopResp(PacketPtr pkt) 495{ 496 return TimingRequestProtocol::sendSnoopResp(_slavePort, pkt); 497} 498 499inline void 500MasterPort::sendRetryResp() 501{ 502 TimingRequestProtocol::sendRetryResp(_slavePort); 503} 504 505#endif //__MEM_PORT_HH__
| 101}; 102 103/** Forward declaration */ 104class SlavePort; 105 106/** 107 * A MasterPort is a specialisation of a BaseMasterPort, which 108 * implements the default protocol for the three different level of 109 * transport functions. In addition to the basic functionality of 110 * sending packets, it also has functions to receive range changes or 111 * determine if the port is snooping or not. 112 * 113 * The three protocols are atomic, timing, and functional, each with its own 114 * header file. 115 */ 116class MasterPort : public BaseMasterPort, public AtomicRequestProtocol, 117 public TimingRequestProtocol, public FunctionalRequestProtocol 118{ 119 friend class SlavePort; 120 121 private: 122 SlavePort *_slavePort; 123 124 protected: 125 SimObject &owner; 126 127 public: 128 MasterPort(const std::string& name, SimObject* _owner, 129 PortID id=InvalidPortID); 130 virtual ~MasterPort(); 131 132 /** 133 * Bind this master port to a slave port. This also does the 134 * mirror action and binds the slave port to the master port. 135 */ 136 void bind(Port &peer) override; 137 138 /** 139 * Unbind this master port and the associated slave port. 140 */ 141 void unbind() override; 142 143 /** 144 * Determine if this master port is snooping or not. The default 145 * implementation returns false and thus tells the neighbour we 146 * are not snooping. Any master port that wants to receive snoop 147 * requests (e.g. a cache connected to a bus) has to override this 148 * function. 149 * 150 * @return true if the port should be considered a snooper 151 */ 152 virtual bool isSnooping() const { return false; } 153 154 /** 155 * Get the address ranges of the connected slave port. 156 */ 157 AddrRangeList getAddrRanges() const; 158 159 /** 160 * Inject a PrintReq for the given address to print the state of 161 * that address throughout the memory system. For debugging. 162 */ 163 void printAddr(Addr a); 164 165 public: 166 /* The atomic protocol. */ 167 168 /** 169 * Send an atomic request packet, where the data is moved and the 170 * state is updated in zero time, without interleaving with other 171 * memory accesses. 172 * 173 * @param pkt Packet to send. 174 * 175 * @return Estimated latency of access. 176 */ 177 Tick sendAtomic(PacketPtr pkt); 178 179 /** 180 * Send an atomic request packet like above, but also request a backdoor 181 * to the data being accessed. 182 * 183 * @param pkt Packet to send. 184 * @param backdoor Can be set to a back door pointer by the target to let 185 * caller have direct access to the requested data. 186 * 187 * @return Estimated latency of access. 188 */ 189 Tick sendAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor); 190 191 public: 192 /* The functional protocol. */ 193 194 /** 195 * Send a functional request packet, where the data is instantly 196 * updated everywhere in the memory system, without affecting the 197 * current state of any block or moving the block. 198 * 199 * @param pkt Packet to send. 200 */ 201 void sendFunctional(PacketPtr pkt) const; 202 203 public: 204 /* The timing protocol. */ 205 206 /** 207 * Attempt to send a timing request to the slave port by calling 208 * its corresponding receive function. If the send does not 209 * succeed, as indicated by the return value, then the sender must 210 * wait for a recvReqRetry at which point it can re-issue a 211 * sendTimingReq. 212 * 213 * @param pkt Packet to send. 214 * 215 * @return If the send was succesful or not. 216 */ 217 bool sendTimingReq(PacketPtr pkt); 218 219 /** 220 * Check if the slave can handle a timing request. 221 * 222 * If the send cannot be handled at the moment, as indicated by 223 * the return value, then the sender will receive a recvReqRetry 224 * at which point it can re-issue a sendTimingReq. 225 * 226 * @param pkt Packet to send. 227 * 228 * @return If the send was succesful or not. 229 */ 230 bool tryTiming(PacketPtr pkt) const; 231 232 /** 233 * Attempt to send a timing snoop response packet to the slave 234 * port by calling its corresponding receive function. If the send 235 * does not succeed, as indicated by the return value, then the 236 * sender must wait for a recvRetrySnoop at which point it can 237 * re-issue a sendTimingSnoopResp. 238 * 239 * @param pkt Packet to send. 240 */ 241 bool sendTimingSnoopResp(PacketPtr pkt); 242 243 /** 244 * Send a retry to the slave port that previously attempted a 245 * sendTimingResp to this master port and failed. Note that this 246 * is virtual so that the "fake" snoop response port in the 247 * coherent crossbar can override the behaviour. 248 */ 249 virtual void sendRetryResp(); 250 251 protected: 252 /** 253 * Called to receive an address range change from the peer slave 254 * port. The default implementation ignores the change and does 255 * nothing. Override this function in a derived class if the owner 256 * needs to be aware of the address ranges, e.g. in an 257 * interconnect component like a bus. 258 */ 259 virtual void recvRangeChange() { } 260 261 /** 262 * Default implementations. 263 */ 264 Tick 265 recvAtomicSnoop(PacketPtr pkt) override 266 { 267 panic("%s was not expecting an atomic snoop request\n", name()); 268 return 0; 269 } 270 271 void 272 recvFunctionalSnoop(PacketPtr pkt) override 273 { 274 panic("%s was not expecting a functional snoop request\n", name()); 275 } 276 277 void 278 recvTimingSnoopReq(PacketPtr pkt) override 279 { 280 panic("%s was not expecting a timing snoop request.\n", name()); 281 } 282 283 void 284 recvRetrySnoopResp() override 285 { 286 panic("%s was not expecting a snoop retry.\n", name()); 287 } 288}; 289 290/** 291 * A SlavePort is a specialisation of a port. In addition to the 292 * basic functionality of sending packets to its master peer, it also 293 * has functions specific to a slave, e.g. to send range changes 294 * and get the address ranges that the port responds to. 295 * 296 * The three protocols are atomic, timing, and functional, each with its own 297 * header file. 298 */ 299class SlavePort : public BaseSlavePort, public AtomicResponseProtocol, 300 public TimingResponseProtocol, public FunctionalResponseProtocol 301{ 302 friend class MasterPort; 303 304 private: 305 MasterPort* _masterPort; 306 bool defaultBackdoorWarned; 307 308 protected: 309 SimObject& owner; 310 311 public: 312 SlavePort(const std::string& name, SimObject* _owner, 313 PortID id=InvalidPortID); 314 virtual ~SlavePort(); 315 316 /** 317 * Find out if the peer master port is snooping or not. 318 * 319 * @return true if the peer master port is snooping 320 */ 321 bool isSnooping() const { return _masterPort->isSnooping(); } 322 323 /** 324 * Called by the owner to send a range change 325 */ 326 void 327 sendRangeChange() const 328 { 329 fatal_if(!_masterPort, 330 "%s cannot sendRangeChange() without master port.", name()); 331 _masterPort->recvRangeChange(); 332 } 333 334 /** 335 * Get a list of the non-overlapping address ranges the owner is 336 * responsible for. All slave ports must override this function 337 * and return a populated list with at least one item. 338 * 339 * @return a list of ranges responded to 340 */ 341 virtual AddrRangeList getAddrRanges() const = 0; 342 343 /** 344 * We let the master port do the work, so these don't do anything. 345 */ 346 void unbind() override {} 347 void bind(Port &peer) override {} 348 349 public: 350 /* The atomic protocol. */ 351 352 /** 353 * Send an atomic snoop request packet, where the data is moved 354 * and the state is updated in zero time, without interleaving 355 * with other memory accesses. 356 * 357 * @param pkt Snoop packet to send. 358 * 359 * @return Estimated latency of access. 360 */ 361 Tick 362 sendAtomicSnoop(PacketPtr pkt) 363 { 364 return AtomicResponseProtocol::sendSnoop(_masterPort, pkt); 365 } 366 367 public: 368 /* The functional protocol. */ 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 378 sendFunctionalSnoop(PacketPtr pkt) const 379 { 380 FunctionalResponseProtocol::sendSnoop(_masterPort, pkt); 381 } 382 383 public: 384 /* The timing protocol. */ 385 386 /** 387 * Attempt to send a timing response to the master port by calling 388 * its corresponding receive function. If the send does not 389 * succeed, as indicated by the return value, then the sender must 390 * wait for a recvRespRetry at which point it can re-issue a 391 * sendTimingResp. 392 * 393 * @param pkt Packet to send. 394 * 395 * @return If the send was succesful or not. 396 */ 397 bool 398 sendTimingResp(PacketPtr pkt) 399 { 400 return TimingResponseProtocol::sendResp(_masterPort, pkt); 401 } 402 403 /** 404 * Attempt to send a timing snoop request packet to the master port 405 * by calling its corresponding receive function. Snoop requests 406 * always succeed and hence no return value is needed. 407 * 408 * @param pkt Packet to send. 409 */ 410 void 411 sendTimingSnoopReq(PacketPtr pkt) 412 { 413 TimingResponseProtocol::sendSnoopReq(_masterPort, pkt); 414 } 415 416 /** 417 * Send a retry to the master port that previously attempted a 418 * sendTimingReq to this slave port and failed. 419 */ 420 void 421 sendRetryReq() 422 { 423 TimingResponseProtocol::sendRetryReq(_masterPort); 424 } 425 426 /** 427 * Send a retry to the master port that previously attempted a 428 * sendTimingSnoopResp to this slave port and failed. 429 */ 430 void 431 sendRetrySnoopResp() 432 { 433 TimingResponseProtocol::sendRetrySnoopResp(_masterPort); 434 } 435 436 protected: 437 /** 438 * Called by the master port to unbind. Should never be called 439 * directly. 440 */ 441 void slaveUnbind(); 442 443 /** 444 * Called by the master port to bind. Should never be called 445 * directly. 446 */ 447 void slaveBind(MasterPort& master_port); 448 449 /** 450 * Default implementations. 451 */ 452 Tick recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor) override; 453 454 bool 455 tryTiming(PacketPtr pkt) override 456 { 457 panic("%s was not expecting a %s\n", name(), __func__); 458 } 459 460 bool 461 recvTimingSnoopResp(PacketPtr pkt) override 462 { 463 panic("%s was not expecting a timing snoop response\n", name()); 464 } 465}; 466 467inline Tick 468MasterPort::sendAtomic(PacketPtr pkt) 469{ 470 return AtomicRequestProtocol::send(_slavePort, pkt); 471} 472 473inline Tick 474MasterPort::sendAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor) 475{ 476 return AtomicRequestProtocol::sendBackdoor(_slavePort, pkt, backdoor); 477} 478 479inline void 480MasterPort::sendFunctional(PacketPtr pkt) const 481{ 482 return FunctionalRequestProtocol::send(_slavePort, pkt); 483} 484 485inline bool 486MasterPort::sendTimingReq(PacketPtr pkt) 487{ 488 return TimingRequestProtocol::sendReq(_slavePort, pkt); 489} 490 491inline bool 492MasterPort::tryTiming(PacketPtr pkt) const 493{ 494 return TimingRequestProtocol::trySend(_slavePort, pkt); 495} 496 497inline bool 498MasterPort::sendTimingSnoopResp(PacketPtr pkt) 499{ 500 return TimingRequestProtocol::sendSnoopResp(_slavePort, pkt); 501} 502 503inline void 504MasterPort::sendRetryResp() 505{ 506 TimingRequestProtocol::sendRetryResp(_slavePort); 507} 508 509#endif //__MEM_PORT_HH__
|