From 2a566b4fa7fbd805746d598d0ffc096c2710cef9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 16 Aug 2019 15:27:35 -0700 Subject: [PATCH] mem, sim, systemc: Reorganize Port and co.s bind, unbind slightly. The base Port class can keep track of its peer, and also whether it's connected. This is partially delegated away from the port subclasses which still keep track of a cast version of their peer pointer for their own conveneince, so that it can be used by generic code. Even with the Port mechanism's new flexibility, each port still has exactly one peer and is either connected or not based on whether there is a peer currently. Change-Id: Id3228617dd1604d196814254a1aadeac5ade7cde Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20232 Tested-by: kokoro Reviewed-by: Nikos Nikoleris Reviewed-by: Andreas Sandberg Maintainer: Gabe Black --- src/mem/port.cc | 48 +++++++++++++++++++++++++-------- src/mem/port.hh | 4 +++ src/sim/port.cc | 2 +- src/sim/port.hh | 24 +++++++++++++++-- src/systemc/sc_port_wrapper.hh | 3 +++ src/systemc/tlm_port_wrapper.hh | 2 ++ 6 files changed, 69 insertions(+), 14 deletions(-) diff --git a/src/mem/port.cc b/src/mem/port.cc index 40481b0bb..303d1bc41 100644 --- a/src/mem/port.cc +++ b/src/mem/port.cc @@ -70,6 +70,22 @@ BaseMasterPort::getSlavePort() const return *_baseSlavePort; } +void +BaseMasterPort::bind(Port &peer) +{ + _baseSlavePort = dynamic_cast(&peer); + fatal_if(!_baseSlavePort, "Attempt to bind port %s to non-master port %s.", + name(), peer.name()); + Port::bind(peer); +} + +void +BaseMasterPort::unbind() +{ + _baseSlavePort = nullptr; + Port::unbind(); +} + BaseSlavePort::BaseSlavePort(const std::string &name, PortID _id) : Port(name, _id), _baseMasterPort(NULL) { @@ -89,6 +105,22 @@ BaseSlavePort::getMasterPort() const return *_baseMasterPort; } +void +BaseSlavePort::bind(Port &peer) +{ + _baseMasterPort = dynamic_cast(&peer); + fatal_if(!_baseMasterPort, "Attempt to bind port %s to non-slave port %s.", + name(), peer.name()); + Port::bind(peer); +} + +void +BaseSlavePort::unbind() +{ + _baseMasterPort = nullptr; + Port::unbind(); +} + /** * Master port */ @@ -109,12 +141,9 @@ MasterPort::bind(Port &peer) 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; + BaseMasterPort::bind(peer); // slave port also keeps track of master port _slavePort->slaveBind(*this); } @@ -126,9 +155,8 @@ MasterPort::unbind() panic("Attempting to unbind master port %s that is not connected\n", name()); _slavePort->slaveUnbind(); - _slavePort = NULL; - _connected = false; - _baseSlavePort = NULL; + _slavePort = nullptr; + BaseMasterPort::unbind(); } AddrRangeList @@ -166,17 +194,15 @@ SlavePort::~SlavePort() void SlavePort::slaveUnbind() { - _baseMasterPort = NULL; _masterPort = NULL; - _connected = false; + BaseSlavePort::unbind(); } void SlavePort::slaveBind(MasterPort& master_port) { - _baseMasterPort = &master_port; _masterPort = &master_port; - _connected = true; + BaseSlavePort::bind(master_port); } Tick diff --git a/src/mem/port.hh b/src/mem/port.hh index 847bd1e7d..0b589dafc 100644 --- a/src/mem/port.hh +++ b/src/mem/port.hh @@ -78,6 +78,8 @@ class BaseMasterPort : public Port public: BaseSlavePort& getSlavePort() const; + void bind(Port &peer) override; + void unbind() override; }; /** @@ -94,6 +96,8 @@ class BaseSlavePort : public Port public: BaseMasterPort& getMasterPort() const; + void bind(Port &peer) override; + void unbind() override; }; /** Forward declaration */ diff --git a/src/sim/port.cc b/src/sim/port.cc index b3139a630..fa7df18cf 100644 --- a/src/sim/port.cc +++ b/src/sim/port.cc @@ -50,6 +50,6 @@ #include "sim/port.hh" Port::Port(const std::string& _name, PortID _id) : - portName(_name), id(_id), _connected(false) + portName(_name), id(_id), _peer(nullptr), _connected(false) {} Port::~Port() {} diff --git a/src/sim/port.hh b/src/sim/port.hh index e1811643f..ee4b548a5 100644 --- a/src/sim/port.hh +++ b/src/sim/port.hh @@ -72,6 +72,13 @@ class Port * to InvalidPortID in case this port is not part of a vector. */ const PortID id; + + /** + * A pointer to this port's peer. + */ + Port *_peer; + + /** * Whether this port is currently connected to a peer port. */ @@ -92,6 +99,9 @@ class Port public: + /** Return a reference to this port's peer. */ + Port &getPeer() { return *_peer; } + /** Return port name (for DPRINTF). */ const std::string name() const { return portName; } @@ -99,10 +109,20 @@ class Port PortID getId() const { return id; } /** Attach to a peer port. */ - virtual void bind(Port &peer) = 0; + virtual void + bind(Port &peer) + { + _peer = &peer; + _connected = true; + } /** Dettach from a peer port. */ - virtual void unbind() = 0; + virtual void + unbind() + { + _peer = nullptr; + _connected = false; + } /** Is this port currently connected to a peer? */ bool isConnected() const { return _connected; } diff --git a/src/systemc/sc_port_wrapper.hh b/src/systemc/sc_port_wrapper.hh index b6f6f8504..9f7d80de8 100644 --- a/src/systemc/sc_port_wrapper.hh +++ b/src/systemc/sc_port_wrapper.hh @@ -85,6 +85,7 @@ class ScPortWrapper : public ::Port fatal("Attempt to bind sc_port %s to incompatible port %s.", name(), peer.name()); } + Port::bind(peer); } private: @@ -123,6 +124,7 @@ class ScInterfaceWrapper : public ::Port // Don't bind to peer otherwise we may have error messages saying that // this interface has already be bound since the peer may already did // that. Just let sc_port or sc_export do the binding + Port::bind(peer); } private: @@ -160,6 +162,7 @@ class ScExportWrapper : public ::Port name(), peer.name()); port_.bind(iface->interface()); + Port::bind(peer); } private: diff --git a/src/systemc/tlm_port_wrapper.hh b/src/systemc/tlm_port_wrapper.hh index 0553a18ef..59f8d9fe0 100644 --- a/src/systemc/tlm_port_wrapper.hh +++ b/src/systemc/tlm_port_wrapper.hh @@ -74,6 +74,7 @@ class TlmInitiatorWrapper : public ::Port "incompatible port %s.", name(), peer.name()); initiator().bind(target->target()); + Port::bind(peer); } void @@ -107,6 +108,7 @@ class TlmTargetWrapper : public ::Port { // Ignore attempts to bind a target socket. The initiator will // handle it. + Port::bind(peer); } void -- 2.30.2