bridge.hh revision 4450
12568SN/A/* 22568SN/A * Copyright (c) 2006 The Regents of The University of Michigan 32568SN/A * All rights reserved. 42568SN/A * 52568SN/A * Redistribution and use in source and binary forms, with or without 62568SN/A * modification, are permitted provided that the following conditions are 72568SN/A * met: redistributions of source code must retain the above copyright 82568SN/A * notice, this list of conditions and the following disclaimer; 92568SN/A * redistributions in binary form must reproduce the above copyright 102568SN/A * notice, this list of conditions and the following disclaimer in the 112568SN/A * documentation and/or other materials provided with the distribution; 122568SN/A * neither the name of the copyright holders nor the names of its 132568SN/A * contributors may be used to endorse or promote products derived from 142568SN/A * this software without specific prior written permission. 152568SN/A * 162568SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172568SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182568SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192568SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202568SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212568SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222568SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232568SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242568SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252568SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262568SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Ali Saidi 292665Ssaidi@eecs.umich.edu * Steve Reinhardt 302568SN/A */ 312568SN/A 322568SN/A/** 332982Sstever@eecs.umich.edu * @file 342982Sstever@eecs.umich.edu * Declaration of a simple bus bridge object with no buffering 352568SN/A */ 362568SN/A 372568SN/A#ifndef __MEM_BRIDGE_HH__ 382568SN/A#define __MEM_BRIDGE_HH__ 392568SN/A 402568SN/A#include <string> 412568SN/A#include <list> 422568SN/A#include <inttypes.h> 432568SN/A#include <queue> 442568SN/A 452568SN/A#include "mem/mem_object.hh" 462568SN/A#include "mem/packet.hh" 472568SN/A#include "mem/port.hh" 482568SN/A#include "sim/eventq.hh" 492568SN/A 502568SN/Aclass Bridge : public MemObject 512568SN/A{ 522568SN/A protected: 532982Sstever@eecs.umich.edu /** Declaration of the buses port type, one will be instantiated for each 542568SN/A of the interfaces connecting to the bus. */ 552568SN/A class BridgePort : public Port 562568SN/A { 572643Sstever@eecs.umich.edu /** A pointer to the bridge to which this port belongs. */ 582568SN/A Bridge *bridge; 592568SN/A 602643Sstever@eecs.umich.edu /** 612643Sstever@eecs.umich.edu * Pointer to the port on the other side of the bridge 622643Sstever@eecs.umich.edu * (connected to the other bus). 632643Sstever@eecs.umich.edu */ 642643Sstever@eecs.umich.edu BridgePort *otherPort; 652643Sstever@eecs.umich.edu 662643Sstever@eecs.umich.edu /** Minimum delay though this bridge. */ 672643Sstever@eecs.umich.edu Tick delay; 682643Sstever@eecs.umich.edu 694435Ssaidi@eecs.umich.edu /** Min delay to respond to a nack. */ 704435Ssaidi@eecs.umich.edu Tick nackDelay; 714435Ssaidi@eecs.umich.edu 724432Ssaidi@eecs.umich.edu bool fixPartialWrite; 734432Ssaidi@eecs.umich.edu 742643Sstever@eecs.umich.edu class PacketBuffer : public Packet::SenderState { 752643Sstever@eecs.umich.edu 762643Sstever@eecs.umich.edu public: 772643Sstever@eecs.umich.edu Tick ready; 783349Sbinkertn@umich.edu PacketPtr pkt; 792643Sstever@eecs.umich.edu Packet::SenderState *origSenderState; 802643Sstever@eecs.umich.edu short origSrc; 812643Sstever@eecs.umich.edu bool expectResponse; 822643Sstever@eecs.umich.edu 834432Ssaidi@eecs.umich.edu bool partialWriteFixed; 844432Ssaidi@eecs.umich.edu PacketPtr oldPkt; 854432Ssaidi@eecs.umich.edu 864433Ssaidi@eecs.umich.edu PacketBuffer(PacketPtr _pkt, Tick t, bool nack = false) 872643Sstever@eecs.umich.edu : ready(t), pkt(_pkt), 882643Sstever@eecs.umich.edu origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()), 894433Ssaidi@eecs.umich.edu expectResponse(_pkt->needsResponse() && !nack), 904450Ssaidi@eecs.umich.edu partialWriteFixed(false) 914433Ssaidi@eecs.umich.edu 922643Sstever@eecs.umich.edu { 934450Ssaidi@eecs.umich.edu if (!pkt->isResponse() && !nack && pkt->result != Packet::Nacked) 942657Ssaidi@eecs.umich.edu pkt->senderState = this; 952643Sstever@eecs.umich.edu } 962643Sstever@eecs.umich.edu 973349Sbinkertn@umich.edu void fixResponse(PacketPtr pkt) 982643Sstever@eecs.umich.edu { 992643Sstever@eecs.umich.edu assert(pkt->senderState == this); 1002643Sstever@eecs.umich.edu pkt->setDest(origSrc); 1012643Sstever@eecs.umich.edu pkt->senderState = origSenderState; 1024432Ssaidi@eecs.umich.edu if (partialWriteFixed) 1034432Ssaidi@eecs.umich.edu delete oldPkt; 1042643Sstever@eecs.umich.edu } 1054432Ssaidi@eecs.umich.edu 1064432Ssaidi@eecs.umich.edu void partialWriteFix(Port *port) 1074432Ssaidi@eecs.umich.edu { 1084432Ssaidi@eecs.umich.edu assert(!partialWriteFixed); 1094432Ssaidi@eecs.umich.edu assert(expectResponse); 1104432Ssaidi@eecs.umich.edu 1114432Ssaidi@eecs.umich.edu int pbs = port->peerBlockSize(); 1124432Ssaidi@eecs.umich.edu partialWriteFixed = true; 1134432Ssaidi@eecs.umich.edu PacketDataPtr data; 1144432Ssaidi@eecs.umich.edu 1154432Ssaidi@eecs.umich.edu data = new uint8_t[pbs]; 1164432Ssaidi@eecs.umich.edu PacketPtr funcPkt = new Packet(pkt->req, MemCmd::ReadReq, 1174432Ssaidi@eecs.umich.edu Packet::Broadcast, pbs); 1184432Ssaidi@eecs.umich.edu 1194432Ssaidi@eecs.umich.edu funcPkt->dataStatic(data); 1204432Ssaidi@eecs.umich.edu port->sendFunctional(funcPkt); 1214432Ssaidi@eecs.umich.edu assert(funcPkt->result == Packet::Success); 1224432Ssaidi@eecs.umich.edu delete funcPkt; 1234432Ssaidi@eecs.umich.edu 1244432Ssaidi@eecs.umich.edu oldPkt = pkt; 1254432Ssaidi@eecs.umich.edu memcpy(data + oldPkt->getOffset(pbs), pkt->getPtr<uint8_t>(), 1264432Ssaidi@eecs.umich.edu pkt->getSize()); 1274432Ssaidi@eecs.umich.edu pkt = new Packet(oldPkt->req, MemCmd::WriteInvalidateReq, 1284432Ssaidi@eecs.umich.edu Packet::Broadcast, pbs); 1294432Ssaidi@eecs.umich.edu pkt->dataDynamicArray(data); 1304432Ssaidi@eecs.umich.edu pkt->senderState = oldPkt->senderState; 1314432Ssaidi@eecs.umich.edu } 1324432Ssaidi@eecs.umich.edu 1334432Ssaidi@eecs.umich.edu void undoPartialWriteFix() 1344432Ssaidi@eecs.umich.edu { 1354432Ssaidi@eecs.umich.edu if (!partialWriteFixed) 1364432Ssaidi@eecs.umich.edu return; 1374432Ssaidi@eecs.umich.edu delete pkt; 1384432Ssaidi@eecs.umich.edu pkt = oldPkt; 1394432Ssaidi@eecs.umich.edu partialWriteFixed = false; 1404432Ssaidi@eecs.umich.edu } 1414432Ssaidi@eecs.umich.edu 1422643Sstever@eecs.umich.edu }; 1432643Sstever@eecs.umich.edu 1442643Sstever@eecs.umich.edu /** 1452643Sstever@eecs.umich.edu * Outbound packet queue. Packets are held in this queue for a 1462643Sstever@eecs.umich.edu * specified delay to model the processing delay of the 1472643Sstever@eecs.umich.edu * bridge. 1482643Sstever@eecs.umich.edu */ 1492643Sstever@eecs.umich.edu std::list<PacketBuffer*> sendQueue; 1502643Sstever@eecs.umich.edu 1512643Sstever@eecs.umich.edu int outstandingResponses; 1524433Ssaidi@eecs.umich.edu int queuedRequests; 1532643Sstever@eecs.umich.edu 1544435Ssaidi@eecs.umich.edu /** If we're waiting for a retry to happen.*/ 1554435Ssaidi@eecs.umich.edu bool inRetry; 1564435Ssaidi@eecs.umich.edu 1572643Sstever@eecs.umich.edu /** Max queue size for outbound packets */ 1584435Ssaidi@eecs.umich.edu int reqQueueLimit; 1594435Ssaidi@eecs.umich.edu 1604435Ssaidi@eecs.umich.edu /** Max queue size for reserved responses. */ 1614435Ssaidi@eecs.umich.edu int respQueueLimit; 1622643Sstever@eecs.umich.edu 1632643Sstever@eecs.umich.edu /** 1642643Sstever@eecs.umich.edu * Is this side blocked from accepting outbound packets? 1652643Sstever@eecs.umich.edu */ 1664435Ssaidi@eecs.umich.edu bool respQueueFull(); 1674435Ssaidi@eecs.umich.edu bool reqQueueFull(); 1682643Sstever@eecs.umich.edu 1694433Ssaidi@eecs.umich.edu void queueForSendTiming(PacketPtr pkt); 1702643Sstever@eecs.umich.edu 1712643Sstever@eecs.umich.edu void finishSend(PacketBuffer *buf); 1722643Sstever@eecs.umich.edu 1734433Ssaidi@eecs.umich.edu void nackRequest(PacketPtr pkt); 1744433Ssaidi@eecs.umich.edu 1752643Sstever@eecs.umich.edu /** 1762643Sstever@eecs.umich.edu * Handle send event, scheduled when the packet at the head of 1772643Sstever@eecs.umich.edu * the outbound queue is ready to transmit (for timing 1782643Sstever@eecs.umich.edu * accesses only). 1792643Sstever@eecs.umich.edu */ 1802643Sstever@eecs.umich.edu void trySend(); 1812643Sstever@eecs.umich.edu 1822643Sstever@eecs.umich.edu class SendEvent : public Event 1832643Sstever@eecs.umich.edu { 1842643Sstever@eecs.umich.edu BridgePort *port; 1852643Sstever@eecs.umich.edu 1862643Sstever@eecs.umich.edu public: 1872643Sstever@eecs.umich.edu SendEvent(BridgePort *p) 1882643Sstever@eecs.umich.edu : Event(&mainEventQueue), port(p) {} 1892643Sstever@eecs.umich.edu 1902643Sstever@eecs.umich.edu virtual void process() { port->trySend(); } 1912643Sstever@eecs.umich.edu 1922643Sstever@eecs.umich.edu virtual const char *description() { return "bridge send event"; } 1932643Sstever@eecs.umich.edu }; 1942643Sstever@eecs.umich.edu 1952643Sstever@eecs.umich.edu SendEvent sendEvent; 1962568SN/A 1972568SN/A public: 1982568SN/A /** Constructor for the BusPort.*/ 1994435Ssaidi@eecs.umich.edu BridgePort(const std::string &_name, Bridge *_bridge, 2004435Ssaidi@eecs.umich.edu BridgePort *_otherPort, int _delay, int _nack_delay, 2014435Ssaidi@eecs.umich.edu int _req_limit, int _resp_limit, bool fix_partial_write); 2022568SN/A 2032568SN/A protected: 2042568SN/A 2052643Sstever@eecs.umich.edu /** When receiving a timing request from the peer port, 2062643Sstever@eecs.umich.edu pass it to the bridge. */ 2073349Sbinkertn@umich.edu virtual bool recvTiming(PacketPtr pkt); 2082568SN/A 2092643Sstever@eecs.umich.edu /** When receiving a retry request from the peer port, 2102568SN/A pass it to the bridge. */ 2112657Ssaidi@eecs.umich.edu virtual void recvRetry(); 2122568SN/A 2132643Sstever@eecs.umich.edu /** When receiving a Atomic requestfrom the peer port, 2142568SN/A pass it to the bridge. */ 2153349Sbinkertn@umich.edu virtual Tick recvAtomic(PacketPtr pkt); 2162568SN/A 2172643Sstever@eecs.umich.edu /** When receiving a Functional request from the peer port, 2182568SN/A pass it to the bridge. */ 2193349Sbinkertn@umich.edu virtual void recvFunctional(PacketPtr pkt); 2202568SN/A 2212643Sstever@eecs.umich.edu /** When receiving a status changefrom the peer port, 2222568SN/A pass it to the bridge. */ 2232643Sstever@eecs.umich.edu virtual void recvStatusChange(Status status); 2242568SN/A 2252643Sstever@eecs.umich.edu /** When receiving a address range request the peer port, 2262568SN/A pass it to the bridge. */ 2272643Sstever@eecs.umich.edu virtual void getDeviceAddressRanges(AddrRangeList &resp, 2282643Sstever@eecs.umich.edu AddrRangeList &snoop); 2292568SN/A }; 2302568SN/A 2312643Sstever@eecs.umich.edu BridgePort portA, portB; 2322568SN/A 2332568SN/A /** If this bridge should acknowledge writes. */ 2342568SN/A bool ackWrites; 2352568SN/A 2362568SN/A public: 2374435Ssaidi@eecs.umich.edu struct Params 2384435Ssaidi@eecs.umich.edu { 2394435Ssaidi@eecs.umich.edu std::string name; 2404435Ssaidi@eecs.umich.edu int req_size_a; 2414435Ssaidi@eecs.umich.edu int req_size_b; 2424435Ssaidi@eecs.umich.edu int resp_size_a; 2434435Ssaidi@eecs.umich.edu int resp_size_b; 2444435Ssaidi@eecs.umich.edu Tick delay; 2454435Ssaidi@eecs.umich.edu Tick nack_delay; 2464435Ssaidi@eecs.umich.edu bool write_ack; 2474435Ssaidi@eecs.umich.edu bool fix_partial_write_a; 2484435Ssaidi@eecs.umich.edu bool fix_partial_write_b; 2494435Ssaidi@eecs.umich.edu }; 2504435Ssaidi@eecs.umich.edu 2514435Ssaidi@eecs.umich.edu protected: 2524435Ssaidi@eecs.umich.edu Params *_params; 2534435Ssaidi@eecs.umich.edu 2544435Ssaidi@eecs.umich.edu public: 2554435Ssaidi@eecs.umich.edu const Params *params() const { return _params; } 2562568SN/A 2572568SN/A /** A function used to return the port associated with this bus object. */ 2582738Sstever@eecs.umich.edu virtual Port *getPort(const std::string &if_name, int idx = -1); 2592568SN/A 2602568SN/A virtual void init(); 2612568SN/A 2624435Ssaidi@eecs.umich.edu Bridge(Params *p); 2632568SN/A}; 2642568SN/A 2652568SN/A#endif //__MEM_BUS_HH__ 266