Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/17038

Change subject: mem: Move bind() and unbind() into the Port class.
......................................................................

mem: Move bind() and unbind() into the Port class.

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
---
M src/dev/net/etherint.cc
M src/dev/net/etherint.hh
M src/mem/port.cc
M src/mem/port.hh
M src/sim/port.hh
M src/sim/sim_object.cc
6 files changed, 62 insertions(+), 30 deletions(-)



diff --git a/src/dev/net/etherint.cc b/src/dev/net/etherint.cc
index 0c5e6b8..816d615 100644
--- a/src/dev/net/etherint.cc
+++ b/src/dev/net/etherint.cc
@@ -34,6 +34,25 @@
 #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 = (p != nullptr);
+}
+
+void
+EtherInt::unbind()
+{
+    peer = nullptr;
+    _connected = false;
+}
+
+void
 EtherInt::setPeer(EtherInt *p)
 {
     if (peer && peer != p)
diff --git a/src/dev/net/etherint.hh b/src/dev/net/etherint.hh
index 7703220..0486631 100644
--- a/src/dev/net/etherint.hh
+++ b/src/dev/net/etherint.hh
@@ -60,6 +60,9 @@
     /** 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; }

diff --git a/src/mem/port.cc b/src/mem/port.cc
index 6f72bbd..73f96e5 100644
--- a/src/mem/port.cc
+++ b/src/mem/port.cc
@@ -70,12 +70,6 @@
     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 @@
     return *_baseMasterPort;
 }

-bool
-BaseSlavePort::isConnected() const
-{
-    return _baseMasterPort != NULL;
-}
-
 /**
  * Master port
  */
@@ -114,23 +102,29 @@
 }

 void
-MasterPort::bind(BaseSlavePort& slave_port)
+MasterPort::bind(Port &peer)
 {
+    auto *slave_port = dynamic_cast<BaseSlavePort *>(&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;
+    _baseSlavePort = slave_port;

     // also attempt to base the slave to the appropriate type
-    SlavePort* cast_slave_port = dynamic_cast<SlavePort*>(&slave_port);
+    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;
+        _connected = true;
         // slave port also keeps track of master port
-        _slavePort->bind(*this);
+        _slavePort->slaveBind(*this);
     } else {
         fatal("Master port %s cannot bind to %s\n", name(),
-              slave_port.name());
+              slave_port->name());
     }
 }

@@ -140,8 +134,9 @@
     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 +213,19 @@
 }

 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
diff --git a/src/mem/port.hh b/src/mem/port.hh
index 77081db..e94b144 100644
--- a/src/mem/port.hh
+++ b/src/mem/port.hh
@@ -77,10 +77,7 @@

   public:

-    virtual void bind(BaseSlavePort& slave_port) = 0;
-    virtual void unbind() = 0;
     BaseSlavePort& getSlavePort() const;
-    bool isConnected() const;

 };

@@ -101,7 +98,6 @@
   public:

     BaseMasterPort& getMasterPort() const;
-    bool isConnected() const;

 };

@@ -138,12 +134,12 @@
      * 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
@@ -397,16 +393,22 @@
   protected:

     /**
+     * We let the master port do the work, so these don't do anything.
+     */
+    void unbind() override {}
+    void bind(Port &peer) override {}
+
+    /**
      * 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.
diff --git a/src/sim/port.hh b/src/sim/port.hh
index 767308e..fd3a413 100644
--- a/src/sim/port.hh
+++ b/src/sim/port.hh
@@ -72,6 +72,7 @@
      * to InvalidPortID in case this port is not part of a vector.
      */
     const PortID id;
+    bool _connected;

     /**
      * Abstract base class for ports
@@ -80,7 +81,9 @@
* @param _owner The MemObject that is the structural owner of this port
      * @param _id A port identifier for vector ports
      */
- Port(const std::string& _name, PortID _id) : portName(_name), id(_id) {}
+    Port(const std::string& _name, PortID _id) :
+        portName(_name), id(_id), _connected(false)
+    {}

     /**
      * Virtual destructor due to inheritance.
@@ -95,6 +98,14 @@
     /** 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;
+
+    bool isConnected() { return _connected; }
+
 };

 #endif //__SIM_PORT_HH__
diff --git a/src/sim/sim_object.cc b/src/sim/sim_object.cc
index 3238058..7b794a0 100644
--- a/src/sim/sim_object.cc
+++ b/src/sim/sim_object.cc
@@ -136,7 +136,7 @@
 Port &
 SimObject::getPort(const std::string &if_name, PortID idx)
 {
-    fatal("%s does not have any master port named %s\n", name(), if_name);
+    fatal("%s does not have any port named %s\n", name(), if_name);
 }

 //

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/17038
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I0948799bc954acaebf371e6b6612cee1d3023bc4
Gerrit-Change-Number: 17038
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <gabebl...@google.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to