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