X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmem%2Fbus.hh;h=a89738775cb0650292b33b12b6977193cb02cea4;hb=bdde892d668e17fb5a67de0e560a85b9092adf9e;hp=9c7054b9494f341bd4013ac52705d4a1d250f9c1;hpb=174f7753ae8b5d5c856f262e770e3184f37077ea;p=gem5.git diff --git a/src/mem/bus.hh b/src/mem/bus.hh index 9c7054b94..a89738775 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,25 +46,35 @@ #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; struct DevMap { int portId; Range range; }; std::vector portList; - + AddrRangeList defaultRange; + std::vector portSnoopList; /** Function called by the port when the bus is recieving a Timing - transaction.*/ + transaction.*/ bool recvTiming(Packet *pkt); /** Function called by the port when the bus is recieving a Atomic - transaction.*/ + transaction.*/ Tick recvAtomic(Packet *pkt); /** Function called by the port when the bus is recieving a Functional @@ -86,6 +97,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. */ + void atomicSnoop(Packet *pkt); + + /** Snoop all relevant ports functionally. */ + void functionalSnoop(Packet *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(Packet *pkt); + /** Process address range request. * @param resp addresses that we can respond to * @param snoop addresses that we would like to snoop @@ -94,7 +126,7 @@ class Bus : public MemObject void addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id); - /** 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 { @@ -151,6 +183,22 @@ class Bus : public MemObject }; + class BusFreeEvent : public Event + { + Bus * bus; + + public: + BusFreeEvent(Bus * _bus); + void process(); + const char *description(); + }; + + BusFreeEvent busIdle; + + void occupyBus(int numCycles); + + Port * retryingPort; + /** An array of pointers to the peer port interfaces connected to this bus.*/ std::vector interfaces; @@ -159,6 +207,26 @@ class Bus : public MemObject * original send failed for whatever reason.*/ std::list retryList; + void addToRetryList(Port * port) + { + if (!retryingPort) { + // The device wasn't retrying a packet, or wasn't at an appropriate + // time. + 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 = NULL; + + // We shouldn't be receiving a packet from one port when a different + // one is retrying. + assert(port == retryingPort); + } + } + + /** Port that handles requests that don't match any of the interfaces.*/ + Port *defaultPort; + public: /** A function used to return the port associated with this bus object. */ @@ -166,8 +234,14 @@ class Bus : public MemObject virtual void init(); - Bus(const std::string &n, int bus_id) - : MemObject(n), busId(bus_id) {} + Bus(const std::string &n, int bus_id, int _clock, int _width) + : MemObject(n), busId(bus_id), clock(_clock), width(_width), + tickNextIdle(0), busIdle(this), retryingPort(NULL), defaultPort(NULL) + { + //Both the width and clock period must be positive + assert(width); + assert(clock); + } };