From d5bdf6cf79a7710331ba340cfd26cb63b2ee37d8 Mon Sep 17 00:00:00 2001 From: Yan Lee Date: Tue, 23 May 2023 01:07:45 -0700 Subject: [PATCH] mem: port: add TracingExtension for debug purpose TracingExtension contains a stack recording the port names passed through of the Packet. The target receiving the Packet can dump out the whole path of this Packet for the debug purpose. This mechanism can be enabled with the debug flag PortTrace. Change-Id: Ic11e708b35fdddc4f4b786d91b35fd4def08948c Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/71538 Reviewed-by: Jason Lowe-Power Maintainer: Jason Lowe-Power Tested-by: kokoro Reviewed-by: Yu-hsin Wang --- src/mem/SConscript | 1 + src/mem/port.cc | 24 +++++++++++++++ src/mem/port.hh | 73 ++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 92 insertions(+), 6 deletions(-) diff --git a/src/mem/SConscript b/src/mem/SConscript index 351f24e907..6e017e0397 100644 --- a/src/mem/SConscript +++ b/src/mem/SConscript @@ -151,6 +151,7 @@ DebugFlag('MemCtrl') DebugFlag('MMU') DebugFlag('MemoryAccess') DebugFlag('PacketQueue') +DebugFlag("PortTrace") DebugFlag('ResponsePort') DebugFlag('StackDist') DebugFlag("DRAMSim2") diff --git a/src/mem/port.cc b/src/mem/port.cc index 2a253b91a3..2f754c89df 100644 --- a/src/mem/port.cc +++ b/src/mem/port.cc @@ -45,6 +45,7 @@ #include "mem/port.hh" #include "base/trace.hh" +#include "debug/PortTrace.hh" #include "debug/ResponsePort.hh" #include "sim/sim_object.hh" @@ -186,6 +187,29 @@ RequestPort::printAddr(Addr a) sendFunctional(&pkt); } +void +RequestPort::addTrace(PacketPtr pkt) const +{ + if (!gem5::debug::PortTrace || !pkt) + return; + auto ext = pkt->getExtension(); + if (!ext) { + ext = std::make_shared(); + pkt->setExtension(ext); + } + ext->add(name(), _responsePort->name()); +} + +void +RequestPort::removeTrace(PacketPtr pkt) const +{ + if (!gem5::debug::PortTrace || !pkt) + return; + auto ext = pkt->getExtension(); + panic_if(!ext, "There is no TracingExtension in the packet."); + ext->remove(); +} + /** * Response port */ diff --git a/src/mem/port.hh b/src/mem/port.hh index a3acffc427..2555706444 100644 --- a/src/mem/port.hh +++ b/src/mem/port.hh @@ -46,6 +46,10 @@ #ifndef __MEM_PORT_HH__ #define __MEM_PORT_HH__ +#include +#include +#include + #include "base/addr_range.hh" #include "mem/packet.hh" #include "mem/protocol/atomic.hh" @@ -64,6 +68,43 @@ class SlavePort; class ResponsePort; +/** + * TracingExtension is an Extension of the Packet for recording the trace + * of the Packet. The stack in the TracingExtension holds the name of the + * ports that the Packet has passed through. + */ +class TracingExtension : public gem5::Extension +{ + public: + TracingExtension() = default; + TracingExtension(const std::stack& q) { trace_ = q; } + + std::unique_ptr clone() const override + { + return std::make_unique(trace_); + } + + void + add(std::string request_port, std::string response_port) + { + trace_.push(request_port); + trace_.push(response_port); + } + + void + remove() + { + trace_.pop(); // Remove the response port name. + trace_.pop(); // Remove the request port name. + } + + bool empty() { return trace_.empty(); } + std::stack& getTrace() { return trace_; } + + private: + std::stack trace_; +}; + /** * A RequestPort is a specialisation of a Port, which * implements the default protocol for the three different level of @@ -266,6 +307,10 @@ class RequestPort: public Port, public AtomicRequestProtocol, { panic("%s was not expecting a snoop retry.\n", name()); } + + private: + void addTrace(PacketPtr pkt) const; + void removeTrace(PacketPtr pkt) const; }; class [[deprecated]] MasterPort : public RequestPort @@ -393,7 +438,11 @@ class ResponsePort : public Port, public AtomicResponseProtocol, sendTimingResp(PacketPtr pkt) { try { - return TimingResponseProtocol::sendResp(_requestPort, pkt); + _requestPort->removeTrace(pkt); + bool succ = TimingResponseProtocol::sendResp(_requestPort, pkt); + if (!succ) + _requestPort->addTrace(pkt); + return succ; } catch (UnboundPortException) { reportUnbound(); } @@ -487,7 +536,10 @@ inline Tick RequestPort::sendAtomic(PacketPtr pkt) { try { - return AtomicRequestProtocol::send(_responsePort, pkt); + addTrace(pkt); + Tick tick = AtomicRequestProtocol::send(_responsePort, pkt); + removeTrace(pkt); + return tick; } catch (UnboundPortException) { reportUnbound(); } @@ -497,8 +549,11 @@ inline Tick RequestPort::sendAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor) { try { - return AtomicRequestProtocol::sendBackdoor(_responsePort, - pkt, backdoor); + addTrace(pkt); + Tick tick = AtomicRequestProtocol::sendBackdoor(_responsePort, + pkt, backdoor); + removeTrace(pkt); + return tick; } catch (UnboundPortException) { reportUnbound(); } @@ -508,7 +563,9 @@ inline void RequestPort::sendFunctional(PacketPtr pkt) const { try { - return FunctionalRequestProtocol::send(_responsePort, pkt); + addTrace(pkt); + FunctionalRequestProtocol::send(_responsePort, pkt); + removeTrace(pkt); } catch (UnboundPortException) { reportUnbound(); } @@ -530,7 +587,11 @@ inline bool RequestPort::sendTimingReq(PacketPtr pkt) { try { - return TimingRequestProtocol::sendReq(_responsePort, pkt); + addTrace(pkt); + bool succ = TimingRequestProtocol::sendReq(_responsePort, pkt); + if (!succ) + removeTrace(pkt); + return succ; } catch (UnboundPortException) { reportUnbound(); }