coherent_xbar.hh revision 4475
112855Sgabeblack@google.com/* 212855Sgabeblack@google.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 312855Sgabeblack@google.com * All rights reserved. 412855Sgabeblack@google.com * 512855Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 612855Sgabeblack@google.com * modification, are permitted provided that the following conditions are 712855Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 812855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 912855Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1012855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1112855Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1212855Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1312855Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1412855Sgabeblack@google.com * this software without specific prior written permission. 1512855Sgabeblack@google.com * 1612855Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712855Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812855Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912855Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012855Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112855Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212855Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312855Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412855Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512855Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612855Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712855Sgabeblack@google.com * 2812855Sgabeblack@google.com * Authors: Ron Dreslinski 2912855Sgabeblack@google.com * Ali Saidi 3012855Sgabeblack@google.com */ 3112855Sgabeblack@google.com 3212855Sgabeblack@google.com/** 3312855Sgabeblack@google.com * @file 3412855Sgabeblack@google.com * Declaration of a bus object. 3512855Sgabeblack@google.com */ 3612855Sgabeblack@google.com 3712855Sgabeblack@google.com#ifndef __MEM_BUS_HH__ 3812855Sgabeblack@google.com#define __MEM_BUS_HH__ 3912855Sgabeblack@google.com 4012855Sgabeblack@google.com#include <string> 4112855Sgabeblack@google.com#include <list> 4212855Sgabeblack@google.com#include <inttypes.h> 4312855Sgabeblack@google.com 4412855Sgabeblack@google.com#include "base/range.hh" 4512855Sgabeblack@google.com#include "base/hashmap.hh" 4612855Sgabeblack@google.com#include "base/range_map.hh" 4712855Sgabeblack@google.com#include "mem/mem_object.hh" 4812855Sgabeblack@google.com#include "mem/packet.hh" 4912855Sgabeblack@google.com#include "mem/port.hh" 5012855Sgabeblack@google.com#include "mem/request.hh" 5112855Sgabeblack@google.com#include "sim/eventq.hh" 5212855Sgabeblack@google.com 5312855Sgabeblack@google.comclass Bus : public MemObject 5412855Sgabeblack@google.com{ 5512855Sgabeblack@google.com /** Declaration of the buses port type, one will be instantiated for each 5612855Sgabeblack@google.com of the interfaces connecting to the bus. */ 5712855Sgabeblack@google.com class BusPort : public Port 5812855Sgabeblack@google.com { 5912855Sgabeblack@google.com bool _onRetryList; 6012855Sgabeblack@google.com 6112855Sgabeblack@google.com /** A pointer to the bus to which this port belongs. */ 6212855Sgabeblack@google.com Bus *bus; 6312855Sgabeblack@google.com 6412855Sgabeblack@google.com /** A id to keep track of the intercafe ID this port is connected to. */ 6512855Sgabeblack@google.com int id; 6612855Sgabeblack@google.com 6712855Sgabeblack@google.com public: 6812855Sgabeblack@google.com 6912855Sgabeblack@google.com /** Constructor for the BusPort.*/ 70 BusPort(const std::string &_name, Bus *_bus, int _id) 71 : Port(_name, _bus), _onRetryList(false), bus(_bus), id(_id) 72 { } 73 74 bool onRetryList() 75 { return _onRetryList; } 76 77 void onRetryList(bool newVal) 78 { _onRetryList = newVal; } 79 80 int getId() { return id; } 81 82 protected: 83 84 /** When reciving a timing request from the peer port (at id), 85 pass it to the bus. */ 86 virtual bool recvTiming(PacketPtr pkt) 87 { pkt->setSrc(id); return bus->recvTiming(pkt); } 88 89 /** When reciving a Atomic requestfrom the peer port (at id), 90 pass it to the bus. */ 91 virtual Tick recvAtomic(PacketPtr pkt) 92 { pkt->setSrc(id); return bus->recvAtomic(pkt); } 93 94 /** When reciving a Functional requestfrom the peer port (at id), 95 pass it to the bus. */ 96 virtual void recvFunctional(PacketPtr pkt) 97 { pkt->setSrc(id); bus->recvFunctional(pkt); } 98 99 /** When reciving a status changefrom the peer port (at id), 100 pass it to the bus. */ 101 virtual void recvStatusChange(Status status) 102 { bus->recvStatusChange(status, id); } 103 104 /** When reciving a retry from the peer port (at id), 105 pass it to the bus. */ 106 virtual void recvRetry() 107 { bus->recvRetry(id); } 108 109 // This should return all the 'owned' addresses that are 110 // downstream from this bus, yes? That is, the union of all 111 // the 'owned' address ranges of all the other interfaces on 112 // this bus... 113 virtual void getDeviceAddressRanges(AddrRangeList &resp, 114 bool &snoop) 115 { bus->addressRanges(resp, snoop, id); } 116 117 // Ask the bus to ask everyone on the bus what their block size is and 118 // take the max of it. This might need to be changed a bit if we ever 119 // support multiple block sizes. 120 virtual int deviceBlockSize() 121 { return bus->findBlockSize(id); } 122 123 }; 124 125 class BusFreeEvent : public Event 126 { 127 Bus * bus; 128 129 public: 130 BusFreeEvent(Bus * _bus); 131 void process(); 132 const char *description(); 133 }; 134 135 /** a globally unique id for this bus. */ 136 int busId; 137 /** the clock speed for the bus */ 138 int clock; 139 /** the width of the bus in bytes */ 140 int width; 141 /** the next tick at which the bus will be idle */ 142 Tick tickNextIdle; 143 144 Event * drainEvent; 145 146 147 static const int defaultId = -3; //Make it unique from Broadcast 148 149 typedef range_map<Addr,int>::iterator PortIter; 150 range_map<Addr, int> portMap; 151 152 AddrRangeList defaultRange; 153 154 typedef std::vector<BusPort*>::iterator SnoopIter; 155 std::vector<BusPort*> snoopPorts; 156 157 /** Function called by the port when the bus is recieving a Timing 158 transaction.*/ 159 bool recvTiming(PacketPtr pkt); 160 161 /** Function called by the port when the bus is recieving a Atomic 162 transaction.*/ 163 Tick recvAtomic(PacketPtr pkt); 164 165 /** Function called by the port when the bus is recieving a Functional 166 transaction.*/ 167 void recvFunctional(PacketPtr pkt); 168 169 /** Timing function called by port when it is once again able to process 170 * requests. */ 171 void recvRetry(int id); 172 173 /** Function called by the port when the bus is recieving a status change.*/ 174 void recvStatusChange(Port::Status status, int id); 175 176 /** Find which port connected to this bus (if any) should be given a packet 177 * with this address. 178 * @param addr Address to find port for. 179 * @param id Id of the port this packet was received from (to prevent 180 * loops) 181 * @return pointer to port that the packet should be sent out of. 182 */ 183 Port *findPort(Addr addr, int id); 184 185 /** Snoop all relevant ports atomicly. */ 186 Tick atomicSnoop(PacketPtr pkt, Port* responder); 187 188 /** Snoop all relevant ports functionally. */ 189 void functionalSnoop(PacketPtr pkt, Port *responder); 190 191 /** Call snoop on caches, be sure to set SNOOP_COMMIT bit if you want 192 * the snoop to happen 193 * @return True if succeds. 194 */ 195 bool timingSnoop(PacketPtr pkt, Port *responder); 196 197 /** Process address range request. 198 * @param resp addresses that we can respond to 199 * @param snoop addresses that we would like to snoop 200 * @param id ide of the busport that made the request. 201 */ 202 void addressRanges(AddrRangeList &resp, bool &snoop, int id); 203 204 /** Occupy the bus with transmitting the packet pkt */ 205 void occupyBus(PacketPtr pkt); 206 207 /** Ask everyone on the bus what their size is 208 * @param id id of the busport that made the request 209 * @return the max of all the sizes 210 */ 211 int findBlockSize(int id); 212 213 BusFreeEvent busIdle; 214 215 bool inRetry; 216 217 /** max number of bus ids we've handed out so far */ 218 short maxId; 219 220 /** An array of pointers to the peer port interfaces 221 connected to this bus.*/ 222 m5::hash_map<short,BusPort*> interfaces; 223 224 /** An array of pointers to ports that retry should be called on because the 225 * original send failed for whatever reason.*/ 226 std::list<BusPort*> retryList; 227 228 void addToRetryList(BusPort * port) 229 { 230 if (!inRetry) { 231 // The device wasn't retrying a packet, or wasn't at an appropriate 232 // time. 233 assert(!port->onRetryList()); 234 port->onRetryList(true); 235 retryList.push_back(port); 236 } else { 237 if (port->onRetryList()) { 238 // The device was retrying a packet. It didn't work, so we'll leave 239 // it at the head of the retry list. 240 assert(port == retryList.front()); 241 inRetry = false; 242 } 243 else { 244 port->onRetryList(true); 245 retryList.push_back(port); 246 } 247 } 248 } 249 250 /** Port that handles requests that don't match any of the interfaces.*/ 251 BusPort *defaultPort; 252 253 BusPort *funcPort; 254 int funcPortId; 255 256 /** Has the user specified their own default responder? */ 257 bool responderSet; 258 259 int defaultBlockSize; 260 int cachedBlockSize; 261 bool cachedBlockSizeValid; 262 263 public: 264 265 /** A function used to return the port associated with this bus object. */ 266 virtual Port *getPort(const std::string &if_name, int idx = -1); 267 virtual void deletePortRefs(Port *p); 268 269 virtual void init(); 270 271 unsigned int drain(Event *de); 272 273 Bus(const std::string &n, int bus_id, int _clock, int _width, 274 bool responder_set, int dflt_blk_size) 275 : MemObject(n), busId(bus_id), clock(_clock), width(_width), 276 tickNextIdle(0), drainEvent(NULL), busIdle(this), inRetry(false), 277 maxId(0), defaultPort(NULL), funcPort(NULL), funcPortId(-4), 278 responderSet(responder_set), defaultBlockSize(dflt_blk_size), 279 cachedBlockSize(0), cachedBlockSizeValid(false) 280 { 281 //Both the width and clock period must be positive 282 if (width <= 0) 283 fatal("Bus width must be positive\n"); 284 if (clock <= 0) 285 fatal("Bus clock period must be positive\n"); 286 } 287 288}; 289 290#endif //__MEM_BUS_HH__ 291