X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmem%2Fbus.hh;h=ff1d2545d7be9aa5ebbade4c573872d34ba9dff9;hb=f720029e97358b2f69ea0ecaace89d5c2ccc6bfe;hp=96f1152a6f100342224f0dd2075cd115d8f219cd;hpb=00481d1f192c832d654379c2296d5b6020c12b1a;p=gem5.git diff --git a/src/mem/bus.hh b/src/mem/bus.hh index 96f1152a6..ff1d2545d 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -54,12 +54,14 @@ class Bus : public MemObject int busId; /** the clock speed for the bus */ int clock; - /** the width of the bus in bits */ + /** 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; @@ -69,20 +71,17 @@ class Bus : public MemObject AddrRangeList defaultRange; std::vector portSnoopList; - std::vector snoopCallbacks; - - /** 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. */ @@ -100,15 +99,6 @@ class Bus : public MemObject */ Port *findPort(Addr addr, int id); - /** Finds the port a packet should be sent to. If the bus is blocked, no port - * is returned. - * @param pkt Packet to find a destination port for. - * @param id Id of the port this packet was received from - * (to prevent loops) - */ - - Port *findDestPort(PacketPtr pkt, 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. @@ -119,18 +109,16 @@ class Bus : public MemObject std::vector findSnoopPorts(Addr addr, int id); /** Snoop all relevant ports atomicly. */ - void atomicSnoop(Packet *pkt); + Tick atomicSnoop(PacketPtr pkt); - /** Snoop for NACK and Blocked in phase 1 - * @return True if succeds. - */ - bool timingSnoopPhase1(Packet *pkt); + /** Snoop all relevant ports functionally. */ + void functionalSnoop(PacketPtr pkt); - /** @todo Don't need to commit all snoops just those that need it - *(register somehow). */ - /** Commit all snoops now that we know if any of them would have blocked. + /** Call snoop on caches, be sure to set SNOOP_COMMIT bit if you want + * the snoop to happen + * @return True if succeds. */ - void timingSnoopPhase2(Packet *pkt); + bool timingSnoop(PacketPtr pkt); /** Process address range request. * @param resp addresses that we can respond to @@ -139,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); /** 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; @@ -154,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), @@ -209,37 +207,43 @@ class Bus : public MemObject BusFreeEvent busIdle; - void occupyBus(int numCycles); - - Port * retryingPort; + 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(Port * port) + void addToRetryList(BusPort * port) { - if (!retryingPort) { + 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 { - // The device was retrying a packet. It didn't work, so we'll leave - // it at the head of the retry list. - retryingPort = 0; - - // We shouldn't be receiving a packet from one port when a different - // one is retrying. - assert(port == retryingPort); + 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: @@ -248,13 +252,19 @@ class Bus : public MemObject virtual void init(); - Bus(const std::string &n, int bus_id, int _clock, int _width) + 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), busIdle(this), retryingPort(0), defaultPort(NULL) + tickNextIdle(0), drainEvent(NULL), busIdle(this), inRetry(false), + defaultPort(NULL), responderSet(responder_set) { //Both the width and clock period must be positive - assert(width); - assert(clock); + if (width <= 0) + fatal("Bus width must be positive\n"); + if (clock <= 0) + fatal("Bus clock period must be positive\n"); } };