mem: Move bind() and unbind() into the Port class.
authorGabe Black <gabeblack@google.com>
Thu, 7 Mar 2019 09:32:54 +0000 (01:32 -0800)
committerGabe Black <gabeblack@google.com>
Tue, 19 Mar 2019 10:21:46 +0000 (10:21 +0000)
These are now pure virtual methods which more specialized port
subclasses will need to implement. The SlavePort class implements them
by ignoring them and then providing parallel functions for the
MasterPort to call. The MasterPort's methods do basically what they
did before, except now bind() uses dynamic cast to check if its peer
is of the appropriate type and also to convert it into that type before
connecting to it.

Change-Id: I0948799bc954acaebf371e6b6612cee1d3023bc4
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/17038
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>

src/dev/net/etherint.cc
src/dev/net/etherint.hh
src/mem/port.cc
src/mem/port.hh
src/sim/port.cc
src/sim/port.hh

index 0c5e6b81797aaed2416059ca4ad7b5b78037d12e..b55e625f793918c7d23f44584cce9384e26f9869 100644 (file)
 #include "base/logging.hh"
 #include "sim/sim_object.hh"
 
+void
+EtherInt::bind(Port &peer)
+{
+    EtherInt *p = dynamic_cast<EtherInt *>(&peer);
+    if (!p) {
+        fatal("Attempt to bind port %s to non-ethernet port %s.",
+                name(), peer.name());
+    }
+    setPeer(p);
+    _connected = true;
+}
+
+void
+EtherInt::unbind()
+{
+    peer = nullptr;
+    _connected = false;
+}
+
 void
 EtherInt::setPeer(EtherInt *p)
 {
index 77032208c699f5c013b02e4b3422857c2d350a4c..0486631b20c32a62037e4e93718a69e676de39a7 100644 (file)
@@ -60,6 +60,9 @@ class EtherInt : public Port
     /** Return port name (for DPRINTF). */
     const std::string &name() const { return portName; }
 
+    void bind(Port &peer) override;
+    void unbind() override;
+
     void setPeer(EtherInt *p);
     EtherInt* getPeer() { return peer; }
 
index 6f72bbd38eec79b53a6547ab299ad580c334fb3f..001576fe3228e3561fb5c4ae77f1b3ce8deb3683 100644 (file)
@@ -70,12 +70,6 @@ BaseMasterPort::getSlavePort() const
     return *_baseSlavePort;
 }
 
-bool
-BaseMasterPort::isConnected() const
-{
-    return _baseSlavePort != NULL;
-}
-
 BaseSlavePort::BaseSlavePort(const std::string &name, PortID _id)
     : Port(name, _id), _baseMasterPort(NULL)
 {
@@ -95,12 +89,6 @@ BaseSlavePort::getMasterPort() const
     return *_baseMasterPort;
 }
 
-bool
-BaseSlavePort::isConnected() const
-{
-    return _baseMasterPort != NULL;
-}
-
 /**
  * Master port
  */
@@ -114,24 +102,21 @@ MasterPort::~MasterPort()
 }
 
 void
-MasterPort::bind(BaseSlavePort& slave_port)
+MasterPort::bind(Port &peer)
 {
-    // bind on the level of the base ports
-    _baseSlavePort = &slave_port;
-
-    // also attempt to base the slave to the appropriate type
-    SlavePort* cast_slave_port = dynamic_cast<SlavePort*>(&slave_port);
-
-    // if this port is compatible, then proceed with the binding
-    if (cast_slave_port != NULL) {
-        // master port keeps track of the slave port
-        _slavePort = cast_slave_port;
-        // slave port also keeps track of master port
-        _slavePort->bind(*this);
-    } else {
-        fatal("Master port %s cannot bind to %s\n", name(),
-              slave_port.name());
+    auto *slave_port = dynamic_cast<SlavePort *>(&peer);
+    if (!slave_port) {
+        fatal("Attempt to bind port %s to non-slave port %s.",
+                name(), peer.name());
     }
+    // bind on the level of the base ports
+    _baseSlavePort = slave_port;
+
+    // master port keeps track of the slave port
+    _slavePort = slave_port;
+    _connected = true;
+    // slave port also keeps track of master port
+    _slavePort->slaveBind(*this);
 }
 
 void
@@ -140,8 +125,9 @@ MasterPort::unbind()
     if (_slavePort == NULL)
         panic("Attempting to unbind master port %s that is not connected\n",
               name());
-    _slavePort->unbind();
+    _slavePort->slaveUnbind();
     _slavePort = NULL;
+    _connected = false;
     _baseSlavePort = NULL;
 }
 
@@ -218,17 +204,19 @@ SlavePort::~SlavePort()
 }
 
 void
-SlavePort::unbind()
+SlavePort::slaveUnbind()
 {
     _baseMasterPort = NULL;
     _masterPort = NULL;
+    _connected = false;
 }
 
 void
-SlavePort::bind(MasterPort& master_port)
+SlavePort::slaveBind(MasterPort& master_port)
 {
     _baseMasterPort = &master_port;
     _masterPort = &master_port;
+    _connected = true;
 }
 
 Tick
index 77081db4d90d80696cbd1ba3892acb1ff3153bfb..2154da007c7a0ec41d4550ade4140344fd1e3046 100644 (file)
@@ -77,10 +77,7 @@ class BaseMasterPort : public Port
 
   public:
 
-    virtual void bind(BaseSlavePort& slave_port) = 0;
-    virtual void unbind() = 0;
     BaseSlavePort& getSlavePort() const;
-    bool isConnected() const;
 
 };
 
@@ -101,7 +98,6 @@ class BaseSlavePort : public Port
   public:
 
     BaseMasterPort& getMasterPort() const;
-    bool isConnected() const;
 
 };
 
@@ -138,12 +134,12 @@ class MasterPort : public BaseMasterPort
      * Bind this master port to a slave port. This also does the
      * mirror action and binds the slave port to the master port.
      */
-    void bind(BaseSlavePort& slave_port);
+    void bind(Port &peer) override;
 
     /**
      * Unbind this master port and the associated slave port.
      */
-    void unbind();
+    void unbind() override;
 
     /**
      * Send an atomic request packet, where the data is moved and the
@@ -394,19 +390,25 @@ class SlavePort : public BaseSlavePort
      */
     virtual AddrRangeList getAddrRanges() const = 0;
 
+    /**
+     * We let the master port do the work, so these don't do anything.
+     */
+    void unbind() override {}
+    void bind(Port &peer) override {}
+
   protected:
 
     /**
      * Called by the master port to unbind. Should never be called
      * directly.
      */
-    void unbind();
+    void slaveUnbind();
 
     /**
      * Called by the master port to bind. Should never be called
      * directly.
      */
-    void bind(MasterPort& master_port);
+    void slaveBind(MasterPort& master_port);
 
     /**
      * Receive an atomic request packet from the master port.
index 551785ba4ddfbfb086fa42c5a439bf0d59c14dbf..b3139a630a639c0067a5345a154b26075cbcd059 100644 (file)
@@ -49,5 +49,7 @@
 
 #include "sim/port.hh"
 
-Port::Port(const std::string& _name, PortID _id) : portName(_name), id(_id) {}
+Port::Port(const std::string& _name, PortID _id) :
+    portName(_name), id(_id), _connected(false)
+{}
 Port::~Port() {}
index 368f46783f8517f8d57e2df88640e47e1191bcf1..e1811643f555fd7f0e42329128c00173028abb41 100644 (file)
@@ -63,7 +63,7 @@ class Port
   private:
 
     /** Descriptive name (for DPRINTF output) */
-    std::string portName;
+    const std::string portName;
 
   protected:
 
@@ -72,6 +72,10 @@ class Port
      * to InvalidPortID in case this port is not part of a vector.
      */
     const PortID id;
+    /**
+     * Whether this port is currently connected to a peer port.
+     */
+    bool _connected;
 
     /**
      * Abstract base class for ports
@@ -94,6 +98,14 @@ class Port
     /** Get the port id. */
     PortID getId() const { return id; }
 
+    /** Attach to a peer port. */
+    virtual void bind(Port &peer) = 0;
+
+    /** Dettach from a peer port. */
+    virtual void unbind() = 0;
+
+    /** Is this port currently connected to a peer? */
+    bool isConnected() const { return _connected; }
 };
 
 #endif //__SIM_PORT_HH__