X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmem%2Fport.hh;h=bb74bf497a35f6667ccef0c77ee1ef8ba155aac8;hb=cb76111a7e79c9b0364e49bdf34120f440e42746;hp=bb3bc1b1b06db223f89ae1d2ffc18bb7a108b783;hpb=2df9053bb0c158ae40f810b63be8ed0066465012;p=gem5.git diff --git a/src/mem/port.hh b/src/mem/port.hh index bb3bc1b1b..bb74bf497 100644 --- a/src/mem/port.hh +++ b/src/mem/port.hh @@ -41,12 +41,13 @@ #define __MEM_PORT_HH__ #include -#include #include "base/misc.hh" #include "base/range.hh" +#include "base/types.hh" #include "mem/packet.hh" #include "mem/request.hh" +#include "sim/eventq.hh" /** This typedef is used to clean up the parameter list of * getDeviceAddressRanges() and getPeerAddressRanges(). It's declared @@ -58,6 +59,9 @@ typedef std::list > AddrRangeList; typedef std::list >::iterator AddrRangeIter; +class EventQueue; +class MemObject; + /** * Ports are used to interface memory objects to * each other. They will always come in pairs, and we refer to the other @@ -69,10 +73,9 @@ typedef std::list >::iterator AddrRangeIter; * Send accessor functions are being called from the device the port is * associated with, and it will call the peer recv. accessor function. */ -class Port +class Port : public EventManager { - private: - + protected: /** Descriptive name (for DPRINTF output) */ mutable std::string portName; @@ -81,26 +84,24 @@ class Port memory objects. */ Port *peer; - public: - - Port() - : peer(NULL) - { } + /** A pointer to the MemObject that owns this port. This may not be set. */ + MemObject *owner; + public: /** * Constructor. * * @param _name Port name for DPRINTF output. Should include name * of memory system object to which the port belongs. + * @param _owner Pointer to the MemObject that owns this port. + * Will not necessarily be set. */ - Port(const std::string &_name) - : portName(_name), peer(NULL) - { } + Port(const std::string &_name, MemObject *_owner); /** Return port name (for DPRINTF). */ const std::string &name() const { return portName; } - virtual ~Port() {}; + virtual ~Port(); // mey be better to use subclasses & RTTI? /** Holds the ports status. Currently just that a range recomputation needs @@ -112,29 +113,39 @@ class Port void setName(const std::string &name) { portName = name; } - /** Function to set the pointer for the peer port. - @todo should be called by the configuration stuff (python). - */ - void setPeer(Port *port); + /** Function to set the pointer for the peer port. */ + virtual void setPeer(Port *port); - /** Function to set the pointer for the peer port. - @todo should be called by the configuration stuff (python). - */ + /** Function to get the pointer to the peer port. */ Port *getPeer() { return peer; } + /** Function to set the owner of this port. */ + void setOwner(MemObject *_owner); + + /** Function to return the owner of this port. */ + MemObject *getOwner() { return owner; } + + /** Inform the peer port to delete itself and notify it's owner about it's + * demise. */ + void removeConn(); + + virtual bool isDefaultPort() const { return false; } + + bool isConnected() { return peer && !peer->isDefaultPort(); } + protected: /** These functions are protected because they should only be * called by a peer port, never directly by any outside object. */ /** Called to recive a timing call from the peer port. */ - virtual bool recvTiming(Packet *pkt) = 0; + virtual bool recvTiming(PacketPtr pkt) = 0; /** Called to recive a atomic call from the peer port. */ - virtual Tick recvAtomic(Packet *pkt) = 0; + virtual Tick recvAtomic(PacketPtr pkt) = 0; /** Called to recive a functional call from the peer port. */ - virtual void recvFunctional(Packet *pkt) = 0; + virtual void recvFunctional(PacketPtr pkt) = 0; /** Called to recieve a status change from the peer port. */ virtual void recvStatusChange(Status status) = 0; @@ -147,10 +158,10 @@ class Port /** Called by a peer port in order to determine the block size of the device connected to this port. It sometimes doesn't make sense for - this function to be called, a DMA interface doesn't really have a - block size, so it is defaulted to a panic. + this function to be called, so it just returns 0. Anytthing that is + concerned with the size should just ignore that. */ - virtual int deviceBlockSize() { panic("??"); } + virtual unsigned deviceBlockSize() const { return 0; } /** The peer port is requesting us to reply with a list of the ranges we are responsible for. @@ -158,7 +169,7 @@ class Port @param snoop is a list of ranges snooped */ virtual void getDeviceAddressRanges(AddrRangeList &resp, - AddrRangeList &snoop) + bool &snoop) { panic("??"); } public: @@ -172,14 +183,14 @@ class Port case a cache has a higher priority request come in while waiting for the bus to arbitrate. */ - bool sendTiming(Packet *pkt) { return peer->recvTiming(pkt); } + bool sendTiming(PacketPtr pkt) { return peer->recvTiming(pkt); } /** Function called by the associated device to send an atomic * access, an access in which the data is moved and the state is * updated in one cycle, without interleaving with other memory * accesses. Returns estimated latency of access. */ - Tick sendAtomic(Packet *pkt) + Tick sendAtomic(PacketPtr pkt) { return peer->recvAtomic(pkt); } /** Function called by the associated device to send a functional access, @@ -187,7 +198,7 @@ class Port memory system, without affecting the current state of any block or moving the block. */ - void sendFunctional(Packet *pkt) + void sendFunctional(PacketPtr pkt) { return peer->recvFunctional(pkt); } /** Called by the associated device to send a status change to the device @@ -203,12 +214,12 @@ class Port /** Called by the associated device if it wishes to find out the blocksize of the device on attached to the peer port. */ - int peerBlockSize() { return peer->deviceBlockSize(); } + unsigned peerBlockSize() const { return peer->deviceBlockSize(); } /** Called by the associated device if it wishes to find out the address ranges connected to the peer ports devices. */ - void getPeerAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) + void getPeerAddressRanges(AddrRangeList &resp, bool &snoop) { peer->getDeviceAddressRanges(resp, snoop); } /** This function is a wrapper around sendFunctional() @@ -232,11 +243,16 @@ class Port */ virtual void memsetBlob(Addr addr, uint8_t val, int size); + /** Inject a PrintReq for the given address to print the state of + * that address throughout the memory system. For debugging. + */ + void printAddr(Addr a); + private: /** Internal helper function for read/writeBlob(). */ - void blobHelper(Addr addr, uint8_t *p, int size, Packet::Command cmd); + void blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd); }; /** A simple functional port that is only meant for one way communication to @@ -247,14 +263,16 @@ class Port class FunctionalPort : public Port { public: - FunctionalPort(const std::string &_name) - : Port(_name) + FunctionalPort(const std::string &_name, MemObject *_owner = NULL) + : Port(_name, _owner) {} protected: - virtual bool recvTiming(Packet *pkt) { panic("FuncPort is UniDir"); } - virtual Tick recvAtomic(Packet *pkt) { panic("FuncPort is UniDir"); } - virtual void recvFunctional(Packet *pkt) { panic("FuncPort is UniDir"); } + virtual bool recvTiming(PacketPtr pkt) { panic("FuncPort is UniDir"); + M5_DUMMY_RETURN } + virtual Tick recvAtomic(PacketPtr pkt) { panic("FuncPort is UniDir"); + M5_DUMMY_RETURN } + virtual void recvFunctional(PacketPtr pkt) { panic("FuncPort is UniDir"); } virtual void recvStatusChange(Status status) {} public: