bridge.hh revision 4435
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 bool nacked; 86 87 PacketBuffer(PacketPtr _pkt, Tick t, bool nack = false) 88 : ready(t), pkt(_pkt), 89 origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()), 90 expectResponse(_pkt->needsResponse() && !nack), 91 partialWriteFixed(false), nacked(nack) 92 93 { 94 if (!pkt->isResponse() && !nack) 95 pkt->senderState = this; 96 } 97 98 void fixResponse(PacketPtr pkt) 99 { 100 assert(pkt->senderState == this); 101 pkt->setDest(origSrc); 102 pkt->senderState = origSenderState; 103 if (partialWriteFixed) 104 delete oldPkt; 105 } 106 107 void partialWriteFix(Port *port) 108 { 109 assert(!partialWriteFixed); 110 assert(expectResponse); 111 112 int pbs = port->peerBlockSize(); 113 partialWriteFixed = true; 114 PacketDataPtr data; 115 116 data = new uint8_t[pbs]; 117 PacketPtr funcPkt = new Packet(pkt->req, MemCmd::ReadReq, 118 Packet::Broadcast, pbs); 119 120 funcPkt->dataStatic(data); 121 port->sendFunctional(funcPkt); 122 assert(funcPkt->result == Packet::Success); 123 delete funcPkt; 124 125 oldPkt = pkt; 126 memcpy(data + oldPkt->getOffset(pbs), pkt->getPtr<uint8_t>(), 127 pkt->getSize()); 128 pkt = new Packet(oldPkt->req, MemCmd::WriteInvalidateReq, 129 Packet::Broadcast, pbs); 130 pkt->dataDynamicArray(data); 131 pkt->senderState = oldPkt->senderState; 132 } 133 134 void undoPartialWriteFix() 135 { 136 if (!partialWriteFixed) 137 return; 138 delete pkt; 139 pkt = oldPkt; 140 partialWriteFixed = false; 141 } 142 143 }; 144 145 /** 146 * Outbound packet queue. Packets are held in this queue for a 147 * specified delay to model the processing delay of the 148 * bridge. 149 */ 150 std::list<PacketBuffer*> sendQueue; 151 152 int outstandingResponses; 153 int queuedRequests; 154 155 /** If we're waiting for a retry to happen.*/ 156 bool inRetry; 157 158 /** Max queue size for outbound packets */ 159 int reqQueueLimit; 160 161 /** Max queue size for reserved responses. */ 162 int respQueueLimit; 163 164 /** 165 * Is this side blocked from accepting outbound packets? 166 */ 167 bool respQueueFull(); 168 bool reqQueueFull(); 169 170 void queueForSendTiming(PacketPtr pkt); 171 172 void finishSend(PacketBuffer *buf); 173 174 void nackRequest(PacketPtr pkt); 175 176 /** 177 * Handle send event, scheduled when the packet at the head of 178 * the outbound queue is ready to transmit (for timing 179 * accesses only). 180 */ 181 void trySend(); 182 183 class SendEvent : public Event 184 { 185 BridgePort *port; 186 187 public: 188 SendEvent(BridgePort *p) 189 : Event(&mainEventQueue), port(p) {} 190 191 virtual void process() { port->trySend(); } 192 193 virtual const char *description() { return "bridge send event"; } 194 }; 195 196 SendEvent sendEvent; 197 198 public: 199 /** Constructor for the BusPort.*/ 200 BridgePort(const std::string &_name, Bridge *_bridge, 201 BridgePort *_otherPort, int _delay, int _nack_delay, 202 int _req_limit, int _resp_limit, bool fix_partial_write); 203 204 protected: 205 206 /** When receiving a timing request from the peer port, 207 pass it to the bridge. */ 208 virtual bool recvTiming(PacketPtr pkt); 209 210 /** When receiving a retry request from the peer port, 211 pass it to the bridge. */ 212 virtual void recvRetry(); 213 214 /** When receiving a Atomic requestfrom the peer port, 215 pass it to the bridge. */ 216 virtual Tick recvAtomic(PacketPtr pkt); 217 218 /** When receiving a Functional request from the peer port, 219 pass it to the bridge. */ 220 virtual void recvFunctional(PacketPtr pkt); 221 222 /** When receiving a status changefrom the peer port, 223 pass it to the bridge. */ 224 virtual void recvStatusChange(Status status); 225 226 /** When receiving a address range request the peer port, 227 pass it to the bridge. */ 228 virtual void getDeviceAddressRanges(AddrRangeList &resp, 229 AddrRangeList &snoop); 230 }; 231 232 BridgePort portA, portB; 233 234 /** If this bridge should acknowledge writes. */ 235 bool ackWrites; 236 237 public: 238 struct Params 239 { 240 std::string name; 241 int req_size_a; 242 int req_size_b; 243 int resp_size_a; 244 int resp_size_b; 245 Tick delay; 246 Tick nack_delay; 247 bool write_ack; 248 bool fix_partial_write_a; 249 bool fix_partial_write_b; 250 }; 251 252 protected: 253 Params *_params; 254 255 public: 256 const Params *params() const { return _params; } 257 258 /** A function used to return the port associated with this bus object. */ 259 virtual Port *getPort(const std::string &if_name, int idx = -1); 260 261 virtual void init(); 262 263 Bridge(Params *p); 264}; 265 266#endif //__MEM_BUS_HH__ 267