From d2beb1ffc8b2e826c9b54b4e02370bcab5db4c64 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 12 Jun 2020 21:33:51 -0700 Subject: [PATCH] mem: Use the new unbound port reporting mechanism in the mem ports. There was an add-hoc check added to getAddrRanges, but the other methods would just segfault if they tried to talk to their peers. This change wraps all the calls in try blocks and catches the exception which the peer will throw if it's the default and the port is not actually connected to anything. Change-Id: Ie46be0230f33f74305c599b251ca319a65ba008d Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/30296 Reviewed-by: Nikos Nikoleris Maintainer: Nikos Nikoleris Tested-by: kokoro --- src/mem/port.cc | 82 +++++++++++++++++++++++++++++++++++++++------- src/mem/port.hh | 87 +++++++++++++++++++++++++++++++++++++------------ 2 files changed, 137 insertions(+), 32 deletions(-) diff --git a/src/mem/port.cc b/src/mem/port.cc index 883b59256..47e94f471 100644 --- a/src/mem/port.cc +++ b/src/mem/port.cc @@ -47,11 +47,72 @@ #include "base/trace.hh" #include "sim/sim_object.hh" +namespace +{ + +class DefaultMasterPort : public MasterPort +{ + protected: + [[noreturn]] void + blowUp() const + { + throw UnboundPortException(); + } + + public: + DefaultMasterPort() : MasterPort("default_master_port", nullptr) {} + + // Atomic protocol. + Tick recvAtomicSnoop(PacketPtr) override { blowUp(); } + + // Timing protocol. + bool recvTimingResp(PacketPtr) override { blowUp(); } + void recvTimingSnoopReq(PacketPtr) override { blowUp(); } + void recvReqRetry() override { blowUp(); } + void recvRetrySnoopResp() override { blowUp(); } + + // Functional protocol. + void recvFunctionalSnoop(PacketPtr) override { blowUp(); } +}; + +class DefaultSlavePort : public SlavePort +{ + protected: + [[noreturn]] void + blowUp() const + { + throw UnboundPortException(); + } + + public: + DefaultSlavePort() : SlavePort("default_slave_port", nullptr) {} + + // Atomic protocol. + Tick recvAtomic(PacketPtr) override { blowUp(); } + + // Timing protocol. + bool recvTimingReq(PacketPtr) override { blowUp(); } + bool tryTiming(PacketPtr) override { blowUp(); } + bool recvTimingSnoopResp(PacketPtr) override { blowUp(); } + void recvRespRetry() override { blowUp(); } + + // Functional protocol. + void recvFunctional(PacketPtr) override { blowUp(); } + + // General. + AddrRangeList getAddrRanges() const override { return AddrRangeList(); } +}; + +DefaultMasterPort defaultMasterPort; +DefaultSlavePort defaultSlavePort; + +} // anonymous namespace + /** * Master port */ MasterPort::MasterPort(const std::string& name, SimObject* _owner, PortID _id) - : Port(name, _id), _slavePort(NULL), owner(*_owner) + : Port(name, _id), _slavePort(&defaultSlavePort), owner(*_owner) { } @@ -63,10 +124,8 @@ void MasterPort::bind(Port &peer) { auto *slave_port = dynamic_cast(&peer); - if (!slave_port) { - fatal("Attempt to bind port %s to non-slave port %s.", - name(), peer.name()); - } + fatal_if(!slave_port, "Can't bind port %s to non-slave port %s.", + name(), peer.name()); // master port keeps track of the slave port _slavePort = slave_port; Port::bind(peer); @@ -77,11 +136,10 @@ MasterPort::bind(Port &peer) void MasterPort::unbind() { - if (_slavePort == NULL) - panic("Attempting to unbind master port %s that is not connected\n", - name()); + panic_if(!isConnected(), "Can't unbind master port %s which is not bound.", + name()); _slavePort->slaveUnbind(); - _slavePort = nullptr; + _slavePort = &defaultSlavePort; Port::unbind(); } @@ -108,8 +166,8 @@ MasterPort::printAddr(Addr a) * Slave port */ SlavePort::SlavePort(const std::string& name, SimObject* _owner, PortID id) - : Port(name, id), _masterPort(NULL), defaultBackdoorWarned(false), - owner(*_owner) + : Port(name, id), _masterPort(&defaultMasterPort), + defaultBackdoorWarned(false), owner(*_owner) { } @@ -120,7 +178,7 @@ SlavePort::~SlavePort() void SlavePort::slaveUnbind() { - _masterPort = NULL; + _masterPort = &defaultMasterPort; Port::unbind(); } diff --git a/src/mem/port.hh b/src/mem/port.hh index d84e46f20..eadf7f44a 100644 --- a/src/mem/port.hh +++ b/src/mem/port.hh @@ -258,6 +258,7 @@ class SlavePort : public Port, public AtomicResponseProtocol, private: MasterPort* _masterPort; + bool defaultBackdoorWarned; protected: @@ -278,13 +279,7 @@ class SlavePort : public Port, public AtomicResponseProtocol, /** * Called by the owner to send a range change */ - void - sendRangeChange() const - { - fatal_if(!_masterPort, - "%s cannot sendRangeChange() without master port.", name()); - _masterPort->recvRangeChange(); - } + void sendRangeChange() const { _masterPort->recvRangeChange(); } /** * Get a list of the non-overlapping address ranges the owner is @@ -316,7 +311,11 @@ class SlavePort : public Port, public AtomicResponseProtocol, Tick sendAtomicSnoop(PacketPtr pkt) { - return AtomicResponseProtocol::sendSnoop(_masterPort, pkt); + try { + return AtomicResponseProtocol::sendSnoop(_masterPort, pkt); + } catch (UnboundPortException) { + reportUnbound(); + } } public: @@ -332,7 +331,11 @@ class SlavePort : public Port, public AtomicResponseProtocol, void sendFunctionalSnoop(PacketPtr pkt) const { - FunctionalResponseProtocol::sendSnoop(_masterPort, pkt); + try { + FunctionalResponseProtocol::sendSnoop(_masterPort, pkt); + } catch (UnboundPortException) { + reportUnbound(); + } } public: @@ -352,7 +355,11 @@ class SlavePort : public Port, public AtomicResponseProtocol, bool sendTimingResp(PacketPtr pkt) { - return TimingResponseProtocol::sendResp(_masterPort, pkt); + try { + return TimingResponseProtocol::sendResp(_masterPort, pkt); + } catch (UnboundPortException) { + reportUnbound(); + } } /** @@ -365,7 +372,11 @@ class SlavePort : public Port, public AtomicResponseProtocol, void sendTimingSnoopReq(PacketPtr pkt) { - TimingResponseProtocol::sendSnoopReq(_masterPort, pkt); + try { + TimingResponseProtocol::sendSnoopReq(_masterPort, pkt); + } catch (UnboundPortException) { + reportUnbound(); + } } /** @@ -375,7 +386,11 @@ class SlavePort : public Port, public AtomicResponseProtocol, void sendRetryReq() { - TimingResponseProtocol::sendRetryReq(_masterPort); + try { + TimingResponseProtocol::sendRetryReq(_masterPort); + } catch (UnboundPortException) { + reportUnbound(); + } } /** @@ -385,7 +400,11 @@ class SlavePort : public Port, public AtomicResponseProtocol, void sendRetrySnoopResp() { - TimingResponseProtocol::sendRetrySnoopResp(_masterPort); + try { + TimingResponseProtocol::sendRetrySnoopResp(_masterPort); + } catch (UnboundPortException) { + reportUnbound(); + } } protected: @@ -422,43 +441,71 @@ class SlavePort : public Port, public AtomicResponseProtocol, inline Tick MasterPort::sendAtomic(PacketPtr pkt) { - return AtomicRequestProtocol::send(_slavePort, pkt); + try { + return AtomicRequestProtocol::send(_slavePort, pkt); + } catch (UnboundPortException) { + reportUnbound(); + } } inline Tick MasterPort::sendAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor) { - return AtomicRequestProtocol::sendBackdoor(_slavePort, pkt, backdoor); + try { + return AtomicRequestProtocol::sendBackdoor(_slavePort, pkt, backdoor); + } catch (UnboundPortException) { + reportUnbound(); + } } inline void MasterPort::sendFunctional(PacketPtr pkt) const { - return FunctionalRequestProtocol::send(_slavePort, pkt); + try { + return FunctionalRequestProtocol::send(_slavePort, pkt); + } catch (UnboundPortException) { + reportUnbound(); + } } inline bool MasterPort::sendTimingReq(PacketPtr pkt) { - return TimingRequestProtocol::sendReq(_slavePort, pkt); + try { + return TimingRequestProtocol::sendReq(_slavePort, pkt); + } catch (UnboundPortException) { + reportUnbound(); + } } inline bool MasterPort::tryTiming(PacketPtr pkt) const { - return TimingRequestProtocol::trySend(_slavePort, pkt); + try { + return TimingRequestProtocol::trySend(_slavePort, pkt); + } catch (UnboundPortException) { + reportUnbound(); + } } inline bool MasterPort::sendTimingSnoopResp(PacketPtr pkt) { - return TimingRequestProtocol::sendSnoopResp(_slavePort, pkt); + try { + return TimingRequestProtocol::sendSnoopResp(_slavePort, pkt); + } catch (UnboundPortException) { + reportUnbound(); + } } inline void MasterPort::sendRetryResp() { - TimingRequestProtocol::sendRetryResp(_slavePort); + try { + TimingRequestProtocol::sendRetryResp(_slavePort); + } catch (UnboundPortException) { + reportUnbound(); + } } #endif //__MEM_PORT_HH__ -- 2.30.2