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