Deal with invalidations intersecting outstanding upgrades.
[gem5.git] / src / mem / port.hh
index 6b4184043f5a31870eb7d5b78c68abcd478294d5..b23de60509ddd6c268d39d72e74612a1e7d186cf 100644 (file)
@@ -58,6 +58,8 @@
 typedef std::list<Range<Addr> > AddrRangeList;
 typedef std::list<Range<Addr> >::iterator AddrRangeIter;
 
+class MemObject;
+
 /**
  * Ports are used to interface memory objects to
  * each other.  They will always come in pairs, and we refer to the other
@@ -81,10 +83,13 @@ class Port
         memory objects. */
     Port *peer;
 
+    /** A pointer to the MemObject that owns this port. This may not be set. */
+    MemObject *owner;
+
   public:
 
     Port()
-        : peer(NULL)
+        : peer(NULL), owner(NULL)
     { }
 
     /**
@@ -92,9 +97,11 @@ class Port
      *
      * @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 = NULL)
+        : portName(_name), peer(NULL), owner(_owner)
     { }
 
     /** Return port name (for DPRINTF). */
@@ -106,36 +113,42 @@ class Port
     /** Holds the ports status.  Currently just that a range recomputation needs
      * to be done. */
     enum Status {
-        RangeChange,
-        SnoopSquash
+        RangeChange
     };
 
     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) { owner = _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();
+
+
   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;
@@ -148,10 +161,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 int deviceBlockSize() { return 0; }
 
     /** The peer port is requesting us to reply with a list of the ranges we
         are responsible for.
@@ -159,7 +172,7 @@ class Port
         @param snoop is a list of ranges snooped
     */
     virtual void getDeviceAddressRanges(AddrRangeList &resp,
-            AddrRangeList &snoop)
+                                        bool &snoop)
     { panic("??"); }
 
   public:
@@ -173,14 +186,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,
@@ -188,7 +201,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
@@ -209,7 +222,7 @@ class Port
     /** 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()
@@ -237,7 +250,7 @@ class Port
 
     /** 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
@@ -248,14 +261,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: