bridge.hh revision 9029:120ba616606e
1/* 2 * Copyright (c) 2011-2012 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) 2006 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: Ali Saidi 41 * Steve Reinhardt 42 * Andreas Hansson 43 */ 44 45/** 46 * @file 47 * Declaration of a memory-mapped bus bridge that connects a master 48 * and a slave through a request and response queue. 49 */ 50 51#ifndef __MEM_BRIDGE_HH__ 52#define __MEM_BRIDGE_HH__ 53 54#include <list> 55#include <queue> 56#include <string> 57 58#include "base/fast_alloc.hh" 59#include "base/types.hh" 60#include "mem/mem_object.hh" 61#include "mem/packet.hh" 62#include "mem/port.hh" 63#include "params/Bridge.hh" 64#include "sim/eventq.hh" 65 66/** 67 * A bridge is used to interface two different busses (or in general a 68 * memory-mapped master and slave), with buffering for requests and 69 * responses. The bridge has a fixed delay for packets passing through 70 * it and responds to a fixed set of address ranges. 71 * 72 * The bridge comprises a slave port and a master port, that buffer 73 * outgoing responses and requests respectively. Buffer space is 74 * reserved when a request arrives, also reserving response space 75 * before forwarding the request. An incoming request is always 76 * accepted (recvTiming returns true), but is potentially NACKed if 77 * there is no request space or response space. 78 */ 79class Bridge : public MemObject 80{ 81 protected: 82 83 /** 84 * A bridge request state stores packets along with their sender 85 * state and original source. It has enough information to also 86 * restore the response once it comes back to the bridge. 87 */ 88 class RequestState : public Packet::SenderState, public FastAlloc 89 { 90 91 public: 92 93 Packet::SenderState *origSenderState; 94 Packet::NodeID origSrc; 95 96 RequestState(PacketPtr _pkt) 97 : origSenderState(_pkt->senderState), 98 origSrc(_pkt->getSrc()) 99 { } 100 101 void fixResponse(PacketPtr pkt) 102 { 103 assert(pkt->senderState == this); 104 pkt->setDest(origSrc); 105 pkt->senderState = origSenderState; 106 } 107 }; 108 109 /** 110 * A deferred request stores a packet along with its scheduled 111 * transmission time, and whether we can expect to see a response 112 * or not. 113 */ 114 class DeferredRequest 115 { 116 117 public: 118 119 Tick ready; 120 PacketPtr pkt; 121 bool expectResponse; 122 123 DeferredRequest(PacketPtr _pkt, Tick t) 124 : ready(t), pkt(_pkt), expectResponse(_pkt->needsResponse()) 125 { } 126 }; 127 128 /** 129 * A deferred response stores a packet along with its scheduled 130 * transmission time. It also contains information of whether the 131 * bridge NACKed the packet to be able to correctly maintain 132 * counters of outstanding responses. 133 */ 134 class DeferredResponse { 135 136 public: 137 138 Tick ready; 139 PacketPtr pkt; 140 bool nackedHere; 141 142 DeferredResponse(PacketPtr _pkt, Tick t, bool nack = false) 143 : ready(t), pkt(_pkt), nackedHere(nack) 144 { } 145 }; 146 147 // Forward declaration to allow the slave port to have a pointer 148 class BridgeMasterPort; 149 150 /** 151 * The port on the side that receives requests and sends 152 * responses. The slave port has a set of address ranges that it 153 * is responsible for. The slave port also has a buffer for the 154 * responses not yet sent. 155 */ 156 class BridgeSlavePort : public SlavePort 157 { 158 159 private: 160 161 /** A pointer to the bridge to which this port belongs. */ 162 Bridge *bridge; 163 164 /** 165 * Master port on the other side of the bridge 166 * (connected to the other bus). 167 */ 168 BridgeMasterPort& masterPort; 169 170 /** Minimum request delay though this bridge. */ 171 Tick delay; 172 173 /** Min delay to respond with a nack. */ 174 Tick nackDelay; 175 176 /** Address ranges to pass through the bridge */ 177 AddrRangeList ranges; 178 179 /** 180 * Response packet queue. Response packets are held in this 181 * queue for a specified delay to model the processing delay 182 * of the bridge. 183 */ 184 std::list<DeferredResponse> responseQueue; 185 186 /** Counter to track the outstanding responses. */ 187 unsigned int outstandingResponses; 188 189 /** If we're waiting for a retry to happen. */ 190 bool inRetry; 191 192 /** Max queue size for reserved responses. */ 193 unsigned int respQueueLimit; 194 195 /** 196 * Is this side blocked from accepting new response packets. 197 * 198 * @return true if the reserved space has reached the set limit 199 */ 200 bool respQueueFull(); 201 202 /** 203 * Turn the request packet into a NACK response and put it in 204 * the response queue and schedule its transmission. 205 * 206 * @param pkt the request packet to NACK 207 */ 208 void nackRequest(PacketPtr pkt); 209 210 /** 211 * Handle send event, scheduled when the packet at the head of 212 * the response queue is ready to transmit (for timing 213 * accesses only). 214 */ 215 void trySend(); 216 217 /** 218 * Private class for scheduling sending of responses from the 219 * response queue. 220 */ 221 class SendEvent : public Event 222 { 223 BridgeSlavePort& port; 224 225 public: 226 SendEvent(BridgeSlavePort& p) : port(p) {} 227 virtual void process() { port.trySend(); } 228 virtual const char *description() const { return "bridge send"; } 229 }; 230 231 /** Send event for the response queue. */ 232 SendEvent sendEvent; 233 234 public: 235 236 /** 237 * Constructor for the BridgeSlavePort. 238 * 239 * @param _name the port name including the owner 240 * @param _bridge the structural owner 241 * @param _masterPort the master port on the other side of the bridge 242 * @param _delay the delay from seeing a response to sending it 243 * @param _nack_delay the delay from a NACK to sending the response 244 * @param _resp_limit the size of the response queue 245 * @param _ranges a number of address ranges to forward 246 */ 247 BridgeSlavePort(const std::string &_name, Bridge *_bridge, 248 BridgeMasterPort& _masterPort, int _delay, 249 int _nack_delay, int _resp_limit, 250 std::vector<Range<Addr> > _ranges); 251 252 /** 253 * Queue a response packet to be sent out later and also schedule 254 * a send if necessary. 255 * 256 * @param pkt a response to send out after a delay 257 */ 258 void queueForSendTiming(PacketPtr pkt); 259 260 protected: 261 262 /** When receiving a timing request from the peer port, 263 pass it to the bridge. */ 264 virtual bool recvTimingReq(PacketPtr pkt); 265 266 /** When receiving a retry request from the peer port, 267 pass it to the bridge. */ 268 virtual void recvRetry(); 269 270 /** When receiving a Atomic requestfrom the peer port, 271 pass it to the bridge. */ 272 virtual Tick recvAtomic(PacketPtr pkt); 273 274 /** When receiving a Functional request from the peer port, 275 pass it to the bridge. */ 276 virtual void recvFunctional(PacketPtr pkt); 277 278 /** When receiving a address range request the peer port, 279 pass it to the bridge. */ 280 virtual AddrRangeList getAddrRanges(); 281 }; 282 283 284 /** 285 * Port on the side that forwards requests and receives 286 * responses. The master port has a buffer for the requests not 287 * yet sent. 288 */ 289 class BridgeMasterPort : public MasterPort 290 { 291 292 private: 293 294 /** A pointer to the bridge to which this port belongs. */ 295 Bridge* bridge; 296 297 /** 298 * Pointer to the slave port on the other side of the bridge 299 * (connected to the other bus). 300 */ 301 BridgeSlavePort& slavePort; 302 303 /** Minimum delay though this bridge. */ 304 Tick delay; 305 306 /** 307 * Request packet queue. Request packets are held in this 308 * queue for a specified delay to model the processing delay 309 * of the bridge. 310 */ 311 std::list<DeferredRequest> requestQueue; 312 313 /** If we're waiting for a retry to happen. */ 314 bool inRetry; 315 316 /** Max queue size for request packets */ 317 unsigned int reqQueueLimit; 318 319 /** 320 * Handle send event, scheduled when the packet at the head of 321 * the outbound queue is ready to transmit (for timing 322 * accesses only). 323 */ 324 void trySend(); 325 326 /** 327 * Private class for scheduling sending of requests from the 328 * request queue. 329 */ 330 class SendEvent : public Event 331 { 332 BridgeMasterPort& port; 333 334 public: 335 SendEvent(BridgeMasterPort& p) : port(p) {} 336 virtual void process() { port.trySend(); } 337 virtual const char *description() const { return "bridge send"; } 338 }; 339 340 /** Send event for the request queue. */ 341 SendEvent sendEvent; 342 343 public: 344 345 /** 346 * Constructor for the BridgeMasterPort. 347 * 348 * @param _name the port name including the owner 349 * @param _bridge the structural owner 350 * @param _slavePort the slave port on the other side of the bridge 351 * @param _delay the delay from seeing a request to sending it 352 * @param _req_limit the size of the request queue 353 */ 354 BridgeMasterPort(const std::string &_name, Bridge *_bridge, 355 BridgeSlavePort& _slavePort, int _delay, 356 int _req_limit); 357 358 /** 359 * Is this side blocked from accepting new request packets. 360 * 361 * @return true if the occupied space has reached the set limit 362 */ 363 bool reqQueueFull(); 364 365 /** 366 * Queue a request packet to be sent out later and also schedule 367 * a send if necessary. 368 * 369 * @param pkt a request to send out after a delay 370 */ 371 void queueForSendTiming(PacketPtr pkt); 372 373 /** 374 * Check a functional request against the packets in our 375 * request queue. 376 * 377 * @param pkt packet to check against 378 * 379 * @return true if we find a match 380 */ 381 bool checkFunctional(PacketPtr pkt); 382 383 protected: 384 385 /** When receiving a timing request from the peer port, 386 pass it to the bridge. */ 387 virtual bool recvTimingResp(PacketPtr pkt); 388 389 /** When receiving a retry request from the peer port, 390 pass it to the bridge. */ 391 virtual void recvRetry(); 392 }; 393 394 /** Slave port of the bridge. */ 395 BridgeSlavePort slavePort; 396 397 /** Master port of the bridge. */ 398 BridgeMasterPort masterPort; 399 400 /** If this bridge should acknowledge writes. */ 401 bool ackWrites; 402 403 public: 404 typedef BridgeParams Params; 405 406 protected: 407 Params *_params; 408 409 public: 410 const Params *params() const { return _params; } 411 412 virtual MasterPort& getMasterPort(const std::string& if_name, 413 int idx = -1); 414 virtual SlavePort& getSlavePort(const std::string& if_name, int idx = -1); 415 416 virtual void init(); 417 418 Bridge(Params *p); 419}; 420 421#endif //__MEM_BUS_HH__ 422