X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmem%2Fbus.hh;h=ff1d2545d7be9aa5ebbade4c573872d34ba9dff9;hb=f720029e97358b2f69ea0ecaace89d5c2ccc6bfe;hp=3a2896886025dd28fd2e42fa9444b5f6d2c7c378;hpb=4b741100714c6f20749f344ddd4b16459f28df72;p=gem5.git diff --git a/src/mem/bus.hh b/src/mem/bus.hh index 3a2896886..ff1d2545d 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -30,7 +30,8 @@ */ /** - * @file Decleration of a bus object. + * @file + * Declaration of a bus object. */ #ifndef __MEM_BUS_HH__ @@ -45,13 +46,22 @@ #include "mem/packet.hh" #include "mem/port.hh" #include "mem/request.hh" +#include "sim/eventq.hh" class Bus : public MemObject { /** a globally unique id for this bus. */ int busId; + /** the clock speed for the bus */ + int clock; + /** the width of the bus in bytes */ + int width; + /** the next tick at which the bus will be idle */ + Tick tickNextIdle; - static const int defaultId = -1; + Event * drainEvent; + + static const int defaultId = -3; //Make it unique from Broadcast struct DevMap { int portId; @@ -59,19 +69,19 @@ class Bus : public MemObject }; std::vector portList; AddrRangeList defaultRange; - + std::vector portSnoopList; /** Function called by the port when the bus is recieving a Timing transaction.*/ - bool recvTiming(Packet *pkt); + bool recvTiming(PacketPtr pkt); /** Function called by the port when the bus is recieving a Atomic transaction.*/ - Tick recvAtomic(Packet *pkt); + Tick recvAtomic(PacketPtr pkt); /** Function called by the port when the bus is recieving a Functional transaction.*/ - void recvFunctional(Packet *pkt); + void recvFunctional(PacketPtr pkt); /** Timing function called by port when it is once again able to process * requests. */ @@ -89,6 +99,27 @@ class Bus : public MemObject */ Port *findPort(Addr addr, int id); + /** Find all ports with a matching snoop range, except src port. Keep in mind + * that the ranges shouldn't overlap or you will get a double snoop to the same + * interface.and the cache will assert out. + * @param addr Address to find snoop prts for. + * @param id Id of the src port of the request to avoid calling snoop on src + * @return vector of IDs to snoop on + */ + std::vector findSnoopPorts(Addr addr, int id); + + /** Snoop all relevant ports atomicly. */ + Tick atomicSnoop(PacketPtr pkt); + + /** Snoop all relevant ports functionally. */ + void functionalSnoop(PacketPtr pkt); + + /** Call snoop on caches, be sure to set SNOOP_COMMIT bit if you want + * the snoop to happen + * @return True if succeds. + */ + bool timingSnoop(PacketPtr pkt); + /** Process address range request. * @param resp addresses that we can respond to * @param snoop addresses that we would like to snoop @@ -96,11 +127,15 @@ class Bus : public MemObject */ void addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id); + /** Occupy the bus with transmitting the packet pkt */ + void occupyBus(PacketPtr pkt); - /** Decleration of the buses port type, one will be instantiated for each + /** Declaration of the buses port type, one will be instantiated for each of the interfaces connecting to the bus. */ class BusPort : public Port { + bool _onRetryList; + /** A pointer to the bus to which this port belongs. */ Bus *bus; @@ -111,24 +146,30 @@ class Bus : public MemObject /** Constructor for the BusPort.*/ BusPort(const std::string &_name, Bus *_bus, int _id) - : Port(_name), bus(_bus), id(_id) + : Port(_name, _bus), _onRetryList(false), bus(_bus), id(_id) { } + bool onRetryList() + { return _onRetryList; } + + void onRetryList(bool newVal) + { _onRetryList = newVal; } + protected: /** When reciving a timing request from the peer port (at id), pass it to the bus. */ - virtual bool recvTiming(Packet *pkt) + virtual bool recvTiming(PacketPtr pkt) { pkt->setSrc(id); return bus->recvTiming(pkt); } /** When reciving a Atomic requestfrom the peer port (at id), pass it to the bus. */ - virtual Tick recvAtomic(Packet *pkt) + virtual Tick recvAtomic(PacketPtr pkt) { pkt->setSrc(id); return bus->recvAtomic(pkt); } /** When reciving a Functional requestfrom the peer port (at id), pass it to the bus. */ - virtual void recvFunctional(Packet *pkt) + virtual void recvFunctional(PacketPtr pkt) { pkt->setSrc(id); bus->recvFunctional(pkt); } /** When reciving a status changefrom the peer port (at id), @@ -154,16 +195,55 @@ class Bus : public MemObject }; + class BusFreeEvent : public Event + { + Bus * bus; + + public: + BusFreeEvent(Bus * _bus); + void process(); + const char *description(); + }; + + BusFreeEvent busIdle; + + bool inRetry; + /** An array of pointers to the peer port interfaces connected to this bus.*/ - std::vector interfaces; + std::vector interfaces; /** An array of pointers to ports that retry should be called on because the * original send failed for whatever reason.*/ - std::list retryList; + std::list retryList; + + void addToRetryList(BusPort * port) + { + if (!inRetry) { + // The device wasn't retrying a packet, or wasn't at an appropriate + // time. + assert(!port->onRetryList()); + port->onRetryList(true); + retryList.push_back(port); + } else { + if (port->onRetryList()) { + // The device was retrying a packet. It didn't work, so we'll leave + // it at the head of the retry list. + assert(port == retryList.front()); + inRetry = false; + } + else { + port->onRetryList(true); + retryList.push_back(port); + } + } + } /** Port that handles requests that don't match any of the interfaces.*/ - Port *defaultPort; + BusPort *defaultPort; + + /** Has the user specified their own default responder? */ + bool responderSet; public: @@ -172,8 +252,20 @@ class Bus : public MemObject virtual void init(); - Bus(const std::string &n, int bus_id) - : MemObject(n), busId(bus_id), defaultPort(NULL) {} + unsigned int drain(Event *de); + + Bus(const std::string &n, int bus_id, int _clock, int _width, + bool responder_set) + : MemObject(n), busId(bus_id), clock(_clock), width(_width), + tickNextIdle(0), drainEvent(NULL), busIdle(this), inRetry(false), + defaultPort(NULL), responderSet(responder_set) + { + //Both the width and clock period must be positive + if (width <= 0) + fatal("Bus width must be positive\n"); + if (clock <= 0) + fatal("Bus clock period must be positive\n"); + } };