summaryrefslogtreecommitdiff
path: root/src/mem/port.hh
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2019-08-15 16:41:51 -0700
committerGabe Black <gabeblack@google.com>2019-08-23 09:04:13 +0000
commitd97e4e1dd01a943a2c40ead90099d3e085059715 (patch)
tree4851265b9045c05f5307ec807f632169ddd4f6e0 /src/mem/port.hh
parent34b22c298c3fa742cb60b613f651874a869b93a0 (diff)
downloadgem5-d97e4e1dd01a943a2c40ead90099d3e085059715.tar.xz
mem: Split the various protocols out of the gem5 master/slave ports.
This makes the protocols easier to see in their entirity, and makes it easier to add a new type of port which only supports the functional protocol. Change-Id: If5d639bef45062f0a23af2ac46f50933e6a8f144 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20228 Maintainer: Gabe Black <gabeblack@google.com> Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Diffstat (limited to 'src/mem/port.hh')
-rw-r--r--src/mem/port.hh343
1 files changed, 188 insertions, 155 deletions
diff --git a/src/mem/port.hh b/src/mem/port.hh
index 76ad3bd63..16257ed4f 100644
--- a/src/mem/port.hh
+++ b/src/mem/port.hh
@@ -51,8 +51,10 @@
#define __MEM_PORT_HH__
#include "base/addr_range.hh"
-#include "mem/backdoor.hh"
+#include "mem/atomic_protocol.hh"
+#include "mem/functional_protocol.hh"
#include "mem/packet.hh"
+#include "mem/timing_protocol.hh"
#include "sim/port.hh"
class SimObject;
@@ -68,18 +70,14 @@ class BaseSlavePort;
*/
class BaseMasterPort : public Port
{
-
protected:
+ BaseSlavePort *_baseSlavePort;
- BaseSlavePort* _baseSlavePort;
-
- BaseMasterPort(const std::string& name, PortID id=InvalidPortID);
+ BaseMasterPort(const std::string &name, PortID id=InvalidPortID);
virtual ~BaseMasterPort();
public:
-
BaseSlavePort& getSlavePort() const;
-
};
/**
@@ -88,18 +86,14 @@ class BaseMasterPort : public Port
*/
class BaseSlavePort : public Port
{
-
protected:
+ BaseMasterPort *_baseMasterPort;
- BaseMasterPort* _baseMasterPort;
-
- BaseSlavePort(const std::string& name, PortID id=InvalidPortID);
+ BaseSlavePort(const std::string &name, PortID id=InvalidPortID);
virtual ~BaseSlavePort();
public:
-
BaseMasterPort& getMasterPort() const;
-
};
/** Forward declaration */
@@ -111,22 +105,22 @@ class SlavePort;
* transport functions. In addition to the basic functionality of
* sending packets, it also has functions to receive range changes or
* determine if the port is snooping or not.
+ *
+ * The three protocols are atomic, timing, and functional, each with its own
+ * header file.
*/
-class MasterPort : public BaseMasterPort
+class MasterPort : public BaseMasterPort, public AtomicRequestProtocol,
+ public TimingRequestProtocol, public FunctionalRequestProtocol
{
-
friend class SlavePort;
private:
-
- SlavePort* _slavePort;
+ SlavePort *_slavePort;
protected:
-
- SimObject& owner;
+ SimObject &owner;
public:
-
MasterPort(const std::string& name, SimObject* _owner,
PortID id=InvalidPortID);
virtual ~MasterPort();
@@ -143,6 +137,31 @@ class MasterPort : public BaseMasterPort
void unbind() override;
/**
+ * Determine if this master port is snooping or not. The default
+ * implementation returns false and thus tells the neighbour we
+ * are not snooping. Any master port that wants to receive snoop
+ * requests (e.g. a cache connected to a bus) has to override this
+ * function.
+ *
+ * @return true if the port should be considered a snooper
+ */
+ virtual bool isSnooping() const { return false; }
+
+ /**
+ * Get the address ranges of the connected slave port.
+ */
+ AddrRangeList getAddrRanges() const;
+
+ /**
+ * Inject a PrintReq for the given address to print the state of
+ * that address throughout the memory system. For debugging.
+ */
+ void printAddr(Addr a);
+
+ public:
+ /* The atomic protocol. */
+
+ /**
* Send an atomic request packet, where the data is moved and the
* state is updated in zero time, without interleaving with other
* memory accesses.
@@ -165,6 +184,9 @@ class MasterPort : public BaseMasterPort
*/
Tick sendAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor);
+ public:
+ /* The functional protocol. */
+
/**
* Send a functional request packet, where the data is instantly
* updated everywhere in the memory system, without affecting the
@@ -172,7 +194,10 @@ class MasterPort : public BaseMasterPort
*
* @param pkt Packet to send.
*/
- void sendFunctional(PacketPtr pkt);
+ void sendFunctional(PacketPtr pkt) const;
+
+ public:
+ /* The timing protocol. */
/**
* Attempt to send a timing request to the slave port by calling
@@ -219,84 +244,43 @@ class MasterPort : public BaseMasterPort
*/
virtual void sendRetryResp();
+ protected:
/**
- * Determine if this master port is snooping or not. The default
- * implementation returns false and thus tells the neighbour we
- * are not snooping. Any master port that wants to receive snoop
- * requests (e.g. a cache connected to a bus) has to override this
- * function.
- *
- * @return true if the port should be considered a snooper
- */
- virtual bool isSnooping() const { return false; }
-
- /**
- * Get the address ranges of the connected slave port.
- */
- AddrRangeList getAddrRanges() const;
-
- /** Inject a PrintReq for the given address to print the state of
- * that address throughout the memory system. For debugging.
+ * Called to receive an address range change from the peer slave
+ * port. The default implementation ignores the change and does
+ * nothing. Override this function in a derived class if the owner
+ * needs to be aware of the address ranges, e.g. in an
+ * interconnect component like a bus.
*/
- void printAddr(Addr a);
-
- protected:
+ virtual void recvRangeChange() { }
/**
- * Receive an atomic snoop request packet from the slave port.
+ * Default implementations.
*/
- virtual Tick recvAtomicSnoop(PacketPtr pkt)
+ Tick
+ recvAtomicSnoop(PacketPtr pkt) override
{
panic("%s was not expecting an atomic snoop request\n", name());
return 0;
}
- /**
- * Receive a functional snoop request packet from the slave port.
- */
- virtual void recvFunctionalSnoop(PacketPtr pkt)
+ void
+ recvFunctionalSnoop(PacketPtr pkt) override
{
panic("%s was not expecting a functional snoop request\n", name());
}
- /**
- * Receive a timing response from the slave port.
- */
- virtual bool recvTimingResp(PacketPtr pkt) = 0;
-
- /**
- * Receive a timing snoop request from the slave port.
- */
- virtual void recvTimingSnoopReq(PacketPtr pkt)
+ void
+ recvTimingSnoopReq(PacketPtr pkt) override
{
- panic("%s was not expecting a timing snoop request\n", name());
+ panic("%s was not expecting a timing snoop request.\n", name());
}
- /**
- * Called by the slave port if sendTimingReq was called on this
- * master port (causing recvTimingReq to be called on the slave
- * port) and was unsuccesful.
- */
- virtual void recvReqRetry() = 0;
-
- /**
- * Called by the slave port if sendTimingSnoopResp was called on this
- * master port (causing recvTimingSnoopResp to be called on the slave
- * port) and was unsuccesful.
- */
- virtual void recvRetrySnoopResp()
+ void
+ recvRetrySnoopResp() override
{
- panic("%s was not expecting a snoop retry\n", name());
+ panic("%s was not expecting a snoop retry.\n", name());
}
-
- /**
- * Called to receive an address range change from the peer slave
- * port. The default implementation ignores the change and does
- * nothing. Override this function in a derived class if the owner
- * needs to be aware of the address ranges, e.g. in an
- * interconnect component like a bus.
- */
- virtual void recvRangeChange() { }
};
/**
@@ -304,28 +288,64 @@ class MasterPort : public BaseMasterPort
* basic functionality of sending packets to its master peer, it also
* has functions specific to a slave, e.g. to send range changes
* and get the address ranges that the port responds to.
+ *
+ * The three protocols are atomic, timing, and functional, each with its own
+ * header file.
*/
-class SlavePort : public BaseSlavePort
+class SlavePort : public BaseSlavePort, public AtomicResponseProtocol,
+ public TimingResponseProtocol, public FunctionalResponseProtocol
{
-
friend class MasterPort;
private:
-
MasterPort* _masterPort;
bool defaultBackdoorWarned;
protected:
-
SimObject& owner;
public:
-
SlavePort(const std::string& name, SimObject* _owner,
PortID id=InvalidPortID);
virtual ~SlavePort();
/**
+ * Find out if the peer master port is snooping or not.
+ *
+ * @return true if the peer master port is snooping
+ */
+ bool isSnooping() const { return _masterPort->isSnooping(); }
+
+ /**
+ * Called by the owner to send a range change
+ */
+ void
+ sendRangeChange() const
+ {
+ fatal_if(!_masterPort,
+ "%s cannot sendRangeChange() without master port.", name());
+ _masterPort->recvRangeChange();
+ }
+
+ /**
+ * Get a list of the non-overlapping address ranges the owner is
+ * responsible for. All slave ports must override this function
+ * and return a populated list with at least one item.
+ *
+ * @return a list of ranges responded to
+ */
+ 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 {}
+
+ public:
+ /* The atomic protocol. */
+
+ /**
* Send an atomic snoop request packet, where the data is moved
* and the state is updated in zero time, without interleaving
* with other memory accesses.
@@ -334,7 +354,14 @@ class SlavePort : public BaseSlavePort
*
* @return Estimated latency of access.
*/
- Tick sendAtomicSnoop(PacketPtr pkt);
+ Tick
+ sendAtomicSnoop(PacketPtr pkt)
+ {
+ return AtomicResponseProtocol::sendSnoop(_masterPort, pkt);
+ }
+
+ public:
+ /* The functional protocol. */
/**
* Send a functional snoop request packet, where the data is
@@ -343,7 +370,14 @@ class SlavePort : public BaseSlavePort
*
* @param pkt Snoop packet to send.
*/
- void sendFunctionalSnoop(PacketPtr pkt);
+ void
+ sendFunctionalSnoop(PacketPtr pkt) const
+ {
+ FunctionalResponseProtocol::sendSnoop(_masterPort, pkt);
+ }
+
+ public:
+ /* The timing protocol. */
/**
* Attempt to send a timing response to the master port by calling
@@ -356,7 +390,11 @@ class SlavePort : public BaseSlavePort
*
* @return If the send was succesful or not.
*/
- bool sendTimingResp(PacketPtr pkt);
+ bool
+ sendTimingResp(PacketPtr pkt)
+ {
+ return TimingResponseProtocol::sendResp(_masterPort, pkt);
+ }
/**
* Attempt to send a timing snoop request packet to the master port
@@ -365,53 +403,33 @@ class SlavePort : public BaseSlavePort
*
* @param pkt Packet to send.
*/
- void sendTimingSnoopReq(PacketPtr pkt);
+ void
+ sendTimingSnoopReq(PacketPtr pkt)
+ {
+ TimingResponseProtocol::sendSnoopReq(_masterPort, pkt);
+ }
/**
* Send a retry to the master port that previously attempted a
* sendTimingReq to this slave port and failed.
*/
- void sendRetryReq();
+ void
+ sendRetryReq()
+ {
+ TimingResponseProtocol::sendRetryReq(_masterPort);
+ }
/**
* Send a retry to the master port that previously attempted a
* sendTimingSnoopResp to this slave port and failed.
*/
- void sendRetrySnoopResp();
-
- /**
- * Find out if the peer master port is snooping or not.
- *
- * @return true if the peer master port is snooping
- */
- bool isSnooping() const { return _masterPort->isSnooping(); }
-
- /**
- * Called by the owner to send a range change
- */
- void sendRangeChange() const {
- if (!_masterPort)
- fatal("%s cannot sendRangeChange() without master port", name());
- _masterPort->recvRangeChange();
+ void
+ sendRetrySnoopResp()
+ {
+ TimingResponseProtocol::sendRetrySnoopResp(_masterPort);
}
- /**
- * Get a list of the non-overlapping address ranges the owner is
- * responsible for. All slave ports must override this function
- * and return a populated list with at least one item.
- *
- * @return a list of ranges responded to
- */
- 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.
@@ -425,48 +443,63 @@ class SlavePort : public BaseSlavePort
void slaveBind(MasterPort& master_port);
/**
- * Receive an atomic request packet from the master port.
- */
- virtual Tick recvAtomic(PacketPtr pkt) = 0;
-
- /**
- * Receive an atomic request packet from the master port, and optionally
- * provide a backdoor to the data being accessed.
- */
- virtual Tick recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor);
-
- /**
- * Receive a functional request packet from the master port.
+ * Default implementations.
*/
- virtual void recvFunctional(PacketPtr pkt) = 0;
+ Tick recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor) override;
- /**
- * Receive a timing request from the master port.
- */
- virtual bool recvTimingReq(PacketPtr pkt) = 0;
-
- /**
- * Availability request from the master port.
- */
- virtual bool tryTiming(PacketPtr pkt) {
+ bool
+ tryTiming(PacketPtr pkt) override
+ {
panic("%s was not expecting a %s\n", name(), __func__);
}
- /**
- * Receive a timing snoop response from the master port.
- */
- virtual bool recvTimingSnoopResp(PacketPtr pkt)
+ bool
+ recvTimingSnoopResp(PacketPtr pkt) override
{
panic("%s was not expecting a timing snoop response\n", name());
}
+};
- /**
- * Called by the master port if sendTimingResp was called on this
- * slave port (causing recvTimingResp to be called on the master
- * port) and was unsuccesful.
- */
- virtual void recvRespRetry() = 0;
+inline Tick
+MasterPort::sendAtomic(PacketPtr pkt)
+{
+ return AtomicRequestProtocol::send(_slavePort, pkt);
+}
-};
+inline Tick
+MasterPort::sendAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor)
+{
+ return AtomicRequestProtocol::sendBackdoor(_slavePort, pkt, backdoor);
+}
+
+inline void
+MasterPort::sendFunctional(PacketPtr pkt) const
+{
+ return FunctionalRequestProtocol::send(_slavePort, pkt);
+}
+
+inline bool
+MasterPort::sendTimingReq(PacketPtr pkt)
+{
+ return TimingRequestProtocol::sendReq(_slavePort, pkt);
+}
+
+inline bool
+MasterPort::tryTiming(PacketPtr pkt) const
+{
+ return TimingRequestProtocol::trySend(_slavePort, pkt);
+}
+
+inline bool
+MasterPort::sendTimingSnoopResp(PacketPtr pkt)
+{
+ return TimingRequestProtocol::sendSnoopResp(_slavePort, pkt);
+}
+
+inline void
+MasterPort::sendRetryResp()
+{
+ TimingRequestProtocol::sendRetryResp(_slavePort);
+}
#endif //__MEM_PORT_HH__