diff --git a/src/mem/coherent_xbar.cc b/src/mem/coherent_xbar.cc index 8163299a09..74ef1ead36 100644 --- a/src/mem/coherent_xbar.cc +++ b/src/mem/coherent_xbar.cc @@ -159,7 +159,7 @@ CoherentXBar::recvTimingReq(PacketPtr pkt, PortID cpu_side_port_id) assert(is_express_snoop == cache_responding); // determine the destination based on the destination address range - PortID mem_side_port_id = findPort(pkt->getAddrRange()); + PortID mem_side_port_id = findPort(pkt); // test if the crossbar should be considered occupied for the current // port, and exclude express snoops from the check @@ -563,7 +563,7 @@ CoherentXBar::recvTimingSnoopReq(PacketPtr pkt, PortID mem_side_port_id) // device responsible for the address range something is // wrong, hence there is nothing further to do as the packet // would be going back to where it came from - assert(findPort(pkt->getAddrRange()) == mem_side_port_id); + assert(findPort(pkt) == mem_side_port_id); } bool @@ -799,7 +799,7 @@ CoherentXBar::recvAtomicBackdoor(PacketPtr pkt, PortID cpu_side_port_id, // even if we had a snoop response, we must continue and also // perform the actual request at the destination - PortID mem_side_port_id = findPort(pkt->getAddrRange()); + PortID mem_side_port_id = findPort(pkt); if (sink_packet) { DPRINTF(CoherentXBar, "%s: Not forwarding %s\n", __func__, @@ -1035,7 +1035,7 @@ CoherentXBar::recvFunctional(PacketPtr pkt, PortID cpu_side_port_id) } } - PortID dest_id = findPort(pkt->getAddrRange()); + PortID dest_id = findPort(pkt); memSidePorts[dest_id]->sendFunctional(pkt); } diff --git a/src/mem/noncoherent_xbar.cc b/src/mem/noncoherent_xbar.cc index 0a378e2c63..12b62974b7 100644 --- a/src/mem/noncoherent_xbar.cc +++ b/src/mem/noncoherent_xbar.cc @@ -107,8 +107,8 @@ NoncoherentXBar::recvTimingReq(PacketPtr pkt, PortID cpu_side_port_id) // we should never see express snoops on a non-coherent crossbar assert(!pkt->isExpressSnoop()); - // determine the destination based on the address - PortID mem_side_port_id = findPort(pkt->getAddrRange()); + // determine the destination port + PortID mem_side_port_id = findPort(pkt); // test if the layer should be considered occupied for the current // port @@ -255,7 +255,7 @@ NoncoherentXBar::recvAtomicBackdoor(PacketPtr pkt, PortID cpu_side_port_id, unsigned int pkt_cmd = pkt->cmdToIndex(); // determine the destination port - PortID mem_side_port_id = findPort(pkt->getAddrRange()); + PortID mem_side_port_id = findPort(pkt); // stats updates for the request pktCount[cpu_side_port_id][mem_side_port_id]++; @@ -316,7 +316,7 @@ NoncoherentXBar::recvFunctional(PacketPtr pkt, PortID cpu_side_port_id) } // determine the destination port - PortID dest_id = findPort(pkt->getAddrRange()); + PortID dest_id = findPort(pkt); // forward the request to the appropriate destination memSidePorts[dest_id]->sendFunctional(pkt); diff --git a/src/mem/port.cc b/src/mem/port.cc index 2f754c89df..e597255dfb 100644 --- a/src/mem/port.cc +++ b/src/mem/port.cc @@ -197,7 +197,7 @@ RequestPort::addTrace(PacketPtr pkt) const ext = std::make_shared(); pkt->setExtension(ext); } - ext->add(name(), _responsePort->name()); + ext->add(name(), _responsePort->name(), pkt->getAddr()); } void diff --git a/src/mem/port.hh b/src/mem/port.hh index 2555706444..5f977aaab8 100644 --- a/src/mem/port.hh +++ b/src/mem/port.hh @@ -47,6 +47,7 @@ #define __MEM_PORT_HH__ #include +#include #include #include @@ -85,9 +86,9 @@ class TracingExtension : public gem5::Extension } void - add(std::string request_port, std::string response_port) + add(std::string request_port, std::string response_port, gem5::Addr addr) { - trace_.push(request_port); + trace_.push(request_port + csprintf(" addr=%#llx", addr)); trace_.push(response_port); } @@ -100,6 +101,21 @@ class TracingExtension : public gem5::Extension bool empty() { return trace_.empty(); } std::stack& getTrace() { return trace_; } + std::string getTraceInString() + { + std::stringstream port_trace; + std::stack copy_stack = trace_; + port_trace << "Port trace of the Packet (" << std::endl + << "[Destination] "; + while (!copy_stack.empty()) { + if (copy_stack.size() == 1) + port_trace << "[Source] "; + port_trace << copy_stack.top() << std::endl; + copy_stack.pop(); + } + port_trace << ")"; + return port_trace.str(); + } private: std::stack trace_; diff --git a/src/mem/xbar.cc b/src/mem/xbar.cc index e1b2a8b521..0d4b2fca97 100644 --- a/src/mem/xbar.cc +++ b/src/mem/xbar.cc @@ -45,6 +45,9 @@ #include "mem/xbar.hh" +#include +#include + #include "base/logging.hh" #include "base/trace.hh" #include "debug/AddrRanges.hh" @@ -328,7 +331,7 @@ BaseXBar::Layer::recvRetry() } PortID -BaseXBar::findPort(AddrRange addr_range) +BaseXBar::findPort(AddrRange addr_range, PacketPtr pkt) { // we should never see any address lookups before we've got the // ranges of all connected CPU-side-port modules @@ -353,10 +356,17 @@ BaseXBar::findPort(AddrRange addr_range) return defaultPortID; } - // we should use the range for the default port and it did not - // match, or the default port is not set - fatal("Unable to find destination for %s on %s\n", addr_range.to_string(), - name()); + // We should use the range for the default port and it did not match, + // or the default port is not set. Dump out the port trace if possible. + std::string port_trace = ""; + if (pkt) { + std::shared_ptr ext = + pkt->getExtension(); + port_trace = ext ? ext->getTraceInString() : + "Use --debug-flags=PortTrace to see the port trace of the packet."; + } + fatal("Unable to find destination for %s on %s\n%s\n", + addr_range.to_string(), name(), port_trace); } /** Function called by the port when the crossbar is receiving a range change.*/ diff --git a/src/mem/xbar.hh b/src/mem/xbar.hh index 1df8b7ea13..b7f763a15a 100644 --- a/src/mem/xbar.hh +++ b/src/mem/xbar.hh @@ -344,9 +344,16 @@ class BaseXBar : public ClockedObject * given a packet with this address range. * * @param addr_range Address range to find port for. - * @return id of port that the packet should be sent out of. + * @param pkt Packet that containing the address range. + * @return id of port that the packet should be sent ou of. */ - PortID findPort(AddrRange addr_range); + PortID findPort(AddrRange addr_range, PacketPtr pkt=nullptr); + + PortID + findPort(PacketPtr pkt) + { + return findPort(pkt->getAddrRange(), pkt); + } /** * Return the address ranges the crossbar is responsible for.