bridge.hh revision 4450
1/* 2 * Copyright (c) 2006 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: Ali Saidi 29 * Steve Reinhardt 30 */ 31 32/** 33 * @file 34 * Declaration of a simple bus bridge object with no buffering 35 */ 36 37#ifndef __MEM_BRIDGE_HH__ 38#define __MEM_BRIDGE_HH__ 39 40#include <string> 41#include <list> 42#include <inttypes.h> 43#include <queue> 44 45#include "mem/mem_object.hh" 46#include "mem/packet.hh" 47#include "mem/port.hh" 48#include "sim/eventq.hh" 49 50class Bridge : public MemObject 51{ 52 protected: 53 /** Declaration of the buses port type, one will be instantiated for each 54 of the interfaces connecting to the bus. */ 55 class BridgePort : public Port 56 { 57 /** A pointer to the bridge to which this port belongs. */ 58 Bridge *bridge; 59 60 /** 61 * Pointer to the port on the other side of the bridge 62 * (connected to the other bus). 63 */ 64 BridgePort *otherPort; 65 66 /** Minimum delay though this bridge. */ 67 Tick delay; 68 69 /** Min delay to respond to a nack. */ 70 Tick nackDelay; 71 72 bool fixPartialWrite; 73 74 class PacketBuffer : public Packet::SenderState { 75 76 public: 77 Tick ready; 78 PacketPtr pkt; 79 Packet::SenderState *origSenderState; 80 short origSrc; 81 bool expectResponse; 82 83 bool partialWriteFixed; 84 PacketPtr oldPkt; 85 86 PacketBuffer(PacketPtr _pkt, Tick t, bool nack = false) 87 : ready(t), pkt(_pkt), 88 origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()), 89 expectResponse(_pkt->needsResponse() && !nack), 90 partialWriteFixed(false) 91 92 { 93 if (!pkt->isResponse() && !nack && pkt->result != Packet::Nacked) 94 pkt->senderState = this; 95 } 96 97 void fixResponse(PacketPtr pkt) 98 { 99 assert(pkt->senderState == this); 100 pkt->setDest(origSrc); 101 pkt->senderState = origSenderState; 102 if (partialWriteFixed) 103 delete oldPkt; 104 } 105 106 void partialWriteFix(Port *port) 107 { 108 assert(!partialWriteFixed); 109 assert(expectResponse); 110 111 int pbs = port->peerBlockSize(); 112 partialWriteFixed = true; 113 PacketDataPtr data; 114 115 data = new uint8_t[pbs]; 116 PacketPtr funcPkt = new Packet(pkt->req, MemCmd::ReadReq, 117 Packet::Broadcast, pbs); 118 119 funcPkt->dataStatic(data); 120 port->sendFunctional(funcPkt); 121 assert(funcPkt->result == Packet::Success); 122 delete funcPkt; 123 124 oldPkt = pkt; 125 memcpy(data + oldPkt->getOffset(pbs), pkt->getPtr<uint8_t>(), 126 pkt->getSize()); 127 pkt = new Packet(oldPkt->req, MemCmd::WriteInvalidateReq, 128 Packet::Broadcast, pbs); 129 pkt->dataDynamicArray(data); 130 pkt->senderState = oldPkt->senderState; 131 } 132 133 void undoPartialWriteFix() 134 { 135 if (!partialWriteFixed) 136 return; 137 delete pkt; 138 pkt = oldPkt; 139 partialWriteFixed = false; 140 } 141 142 }; 143 144 /** 145 * Outbound packet queue. Packets are held in this queue for a 146 * specified delay to model the processing delay of the 147 * bridge. 148 */ 149 std::list<PacketBuffer*> sendQueue; 150 151 int outstandingResponses; 152 int queuedRequests; 153 154 /** If we're waiting for a retry to happen.*/ 155 bool inRetry; 156 157 /** Max queue size for outbound packets */ 158 int reqQueueLimit; 159 160 /** Max queue size for reserved responses. */ 161 int respQueueLimit; 162 163 /** 164 * Is this side blocked from accepting outbound packets? 165 */ 166 bool respQueueFull(); 167 bool reqQueueFull(); 168 169 void queueForSendTiming(PacketPtr pkt); 170 171 void finishSend(PacketBuffer *buf); 172 173 void nackRequest(PacketPtr pkt); 174 175 /** 176 * Handle send event, scheduled when the packet at the head of 177 * the outbound queue is ready to transmit (for timing 178 * accesses only). 179 */ 180 void trySend(); 181 182 class SendEvent : public Event 183 { 184 BridgePort *port; 185 186 public: 187 SendEvent(BridgePort *p) 188 : Event(&mainEventQueue), port(p) {} 189 190 virtual void process() { port->trySend(); } 191 192 virtual const char *description() { return "bridge send event"; } 193 }; 194 195 SendEvent sendEvent; 196 197 public: 198 /** Constructor for the BusPort.*/ 199 BridgePort(const std::string &_name, Bridge *_bridge, 200 BridgePort *_otherPort, int _delay, int _nack_delay, 201 int _req_limit, int _resp_limit, bool fix_partial_write); 202 203 protected: 204 205 /** When receiving a timing request from the peer port, 206 pass it to the bridge. */ 207 virtual bool recvTiming(PacketPtr pkt); 208 209 /** When receiving a retry request from the peer port, 210 pass it to the bridge. */ 211 virtual void recvRetry(); 212 213 /** When receiving a Atomic requestfrom the peer port, 214 pass it to the bridge. */ 215 virtual Tick recvAtomic(PacketPtr pkt); 216 217 /** When receiving a Functional request from the peer port, 218 pass it to the bridge. */ 219 virtual void recvFunctional(PacketPtr pkt); 220 221 /** When receiving a status changefrom the peer port, 222 pass it to the bridge. */ 223 virtual void recvStatusChange(Status status); 224 225 /** When receiving a address range request the peer port, 226 pass it to the bridge. */ 227 virtual void getDeviceAddressRanges(AddrRangeList &resp, 228 AddrRangeList &snoop); 229 }; 230 231 BridgePort portA, portB; 232 233 /** If this bridge should acknowledge writes. */ 234 bool ackWrites; 235 236 public: 237 struct Params 238 { 239 std::string name; 240 int req_size_a; 241 int req_size_b; 242 int resp_size_a; 243 int resp_size_b; 244 Tick delay; 245 Tick nack_delay; 246 bool write_ack; 247 bool fix_partial_write_a; 248 bool fix_partial_write_b; 249 }; 250 251 protected: 252 Params *_params; 253 254 public: 255 const Params *params() const { return _params; } 256 257 /** A function used to return the port associated with this bus object. */ 258 virtual Port *getPort(const std::string &if_name, int idx = -1); 259 260 virtual void init(); 261 262 Bridge(Params *p); 263}; 264 265#endif //__MEM_BUS_HH__ 266