From 842a3a935fe0773ae204d0b5eb2b3eac0995b6ed Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 27 Sep 2022 02:56:10 -0700 Subject: [PATCH] mem: Add an API for requesting a back door without a Packet/Request. Make this part of the Functional protocol, since it should always return immediately, can be shared by the atomic and timing protocols, and thematically fits with that protocol. The default implementation on the receiving end just ignores the request and leaves the back door pointer set to null, effectively making back doors default "off" which matches their behavior in the atomic protocol. This mechamism helps fix a bug in the TLM gem5 bridges which need to translate to/from the DMI and back door mechanisms, where there can be an explicit request for a back door which does not have a transaction associated with it. It is also necessary for bridging DMI requests in timing mode, since the DMI requests must be instant, and the timing protocol does not send/receive packets instantly. Change-Id: I905f13b9bc83c3fa7877b05ce932e17c308125e2 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/65752 Tested-by: kokoro Reviewed-by: Jason Lowe-Power Maintainer: Gabe Black --- src/mem/port.cc | 16 ++++++++++++++++ src/mem/port.hh | 29 +++++++++++++++++++++++++++++ src/mem/protocol/functional.cc | 8 ++++++++ src/mem/protocol/functional.hh | 21 +++++++++++++++++++++ 4 files changed, 74 insertions(+) diff --git a/src/mem/port.cc b/src/mem/port.cc index 00f7ce6efa..18793d487b 100644 --- a/src/mem/port.cc +++ b/src/mem/port.cc @@ -102,6 +102,11 @@ class DefaultResponsePort : public ResponsePort // Functional protocol. void recvFunctional(PacketPtr) override { blowUp(); } + void + recvMemBackdoorReq(const MemBackdoorReq &, MemBackdoorPtr &) override + { + blowUp(); + } // General. AddrRangeList getAddrRanges() const override { return AddrRangeList(); } @@ -205,4 +210,15 @@ ResponsePort::recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor) return recvAtomic(pkt); } +void +ResponsePort::recvMemBackdoorReq(const MemBackdoorReq &req, + MemBackdoorPtr &backdoor) +{ + if (!defaultBackdoorWarned) { + DPRINTF(ResponsePort, + "Port %s doesn't support requesting a back door.", name()); + defaultBackdoorWarned = true; + } +} + } // namespace gem5 diff --git a/src/mem/port.hh b/src/mem/port.hh index 33ff117cf2..fb0f4b8812 100644 --- a/src/mem/port.hh +++ b/src/mem/port.hh @@ -161,6 +161,21 @@ class RequestPort: public Port, public AtomicRequestProtocol, */ void sendFunctional(PacketPtr pkt) const; + /** + * Send a request for a back door to a range of memory. + * + * @param req An object which describes what back door is being requested. + * @param backdoor Can be set to a back door pointer by the target to let + * caller have direct access to the requested range. The original + * caller should initialize this pointer to nullptr. If a receiver + * does not want to provide a back door, they should leave this + * value. If an intermediary wants to support a back door across it, + * it should pass this pointer through, or if not, return without + * passing the request further downstream. + */ + void sendMemBackdoorReq(const MemBackdoorReq &req, + MemBackdoorPtr &backdoor); + public: /* The timing protocol. */ @@ -438,6 +453,8 @@ class ResponsePort : public Port, public AtomicResponseProtocol, * Default implementations. */ Tick recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor) override; + void recvMemBackdoorReq(const MemBackdoorReq &req, + MemBackdoorPtr &backdoor) override; bool tryTiming(PacketPtr pkt) override @@ -491,6 +508,18 @@ RequestPort::sendFunctional(PacketPtr pkt) const } } +inline void +RequestPort::sendMemBackdoorReq(const MemBackdoorReq &req, + MemBackdoorPtr &backdoor) +{ + try { + return FunctionalRequestProtocol::sendMemBackdoorReq( + _responsePort, req, backdoor); + } catch (UnboundPortException) { + reportUnbound(); + } +} + inline bool RequestPort::sendTimingReq(PacketPtr pkt) { diff --git a/src/mem/protocol/functional.cc b/src/mem/protocol/functional.cc index 0f54d92a76..29cec23bc3 100644 --- a/src/mem/protocol/functional.cc +++ b/src/mem/protocol/functional.cc @@ -53,6 +53,14 @@ FunctionalRequestProtocol::send( return peer->recvFunctional(pkt); } +void +FunctionalRequestProtocol::sendMemBackdoorReq( + FunctionalResponseProtocol *peer, + const MemBackdoorReq &req, MemBackdoorPtr &backdoor) +{ + return peer->recvMemBackdoorReq(req, backdoor); +} + /* The response protocol. */ void diff --git a/src/mem/protocol/functional.hh b/src/mem/protocol/functional.hh index 27db171b2d..4f330b4788 100644 --- a/src/mem/protocol/functional.hh +++ b/src/mem/protocol/functional.hh @@ -41,6 +41,7 @@ #ifndef __MEM_GEM5_PROTOCOL_FUNCTIONAL_HH__ #define __MEM_GEM5_PROTOCOL_FUNCTIONAL_HH__ +#include "mem/backdoor.hh" #include "mem/packet.hh" namespace gem5 @@ -66,6 +67,16 @@ class FunctionalRequestProtocol * Receive a functional snoop request packet from the peer. */ virtual void recvFunctionalSnoop(PacketPtr pkt) = 0; + + /** + * Send a request for a back door to a range of memory. + * + * @param req An object which describes what back door is being requested. + * @param backdoor Can be set to a back door pointer by the target to let + * caller have direct access to the requested range. + */ + void sendMemBackdoorReq(FunctionalResponseProtocol *peer, + const MemBackdoorReq &req, MemBackdoorPtr &backdoor); }; class FunctionalResponseProtocol @@ -86,6 +97,16 @@ class FunctionalResponseProtocol * Receive a functional request packet from the peer. */ virtual void recvFunctional(PacketPtr pkt) = 0; + + /** + * Receive a request for a back door to a range of memory. + * + * @param req An object which describes what back door is being requested. + * @param backdoor Can be set to a back door pointer by the target to let + * caller have direct access to the requested range. + */ + virtual void recvMemBackdoorReq(const MemBackdoorReq &req, + MemBackdoorPtr &backdoor) = 0; }; } // namespace gem5