diff options
Diffstat (limited to 'src/mem/ruby/system')
-rw-r--r-- | src/mem/ruby/system/RubyPort.cc | 60 | ||||
-rw-r--r-- | src/mem/ruby/system/RubyPort.hh | 17 | ||||
-rw-r--r-- | src/mem/ruby/system/Sequencer.cc | 1 | ||||
-rw-r--r-- | src/mem/ruby/system/Sequencer.py | 1 |
4 files changed, 53 insertions, 26 deletions
diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc index b2fb8d72d..95a83873c 100644 --- a/src/mem/ruby/system/RubyPort.cc +++ b/src/mem/ruby/system/RubyPort.cc @@ -11,7 +11,7 @@ * unmodified and in its entirety in all distributions of the software, * modified or unmodified, in source code or in binary form. * - * Copyright (c) 2009 Advanced Micro Devices, Inc. + * Copyright (c) 2009-2013 Advanced Micro Devices, Inc. * Copyright (c) 2011 Mark D. Hill and David A. Wood * All rights reserved. * @@ -58,7 +58,8 @@ RubyPort::RubyPort(const Params *p) pioSlavePort(csprintf("%s.pio-slave-port", name()), this), memMasterPort(csprintf("%s.mem-master-port", name()), this), memSlavePort(csprintf("%s-mem-slave-port", name()), this, - p->ruby_system->getAccessBackingStore(), -1), + p->ruby_system->getAccessBackingStore(), -1, + p->no_retry_on_stall), gotAddrRanges(p->port_master_connection_count) { assert(m_version != -1); @@ -66,7 +67,8 @@ RubyPort::RubyPort(const Params *p) // create the slave ports based on the number of connected ports for (size_t i = 0; i < p->port_slave_connection_count; ++i) { slave_ports.push_back(new MemSlavePort(csprintf("%s.slave%d", name(), - i), this, p->ruby_system->getAccessBackingStore(), i)); + i), this, p->ruby_system->getAccessBackingStore(), + i, p->no_retry_on_stall)); } // create the master ports based on the number of connected ports @@ -156,9 +158,11 @@ RubyPort::MemMasterPort::MemMasterPort(const std::string &_name, } RubyPort::MemSlavePort::MemSlavePort(const std::string &_name, RubyPort *_port, - bool _access_backing_store, PortID id) + bool _access_backing_store, PortID id, + bool _no_retry_on_stall) : QueuedSlavePort(_name, _port, queue, id), queue(*_port, *this), - access_backing_store(_access_backing_store) + access_backing_store(_access_backing_store), + no_retry_on_stall(_no_retry_on_stall) { DPRINTF(RubyPort, "Created slave memport on ruby sequencer %s\n", _name); } @@ -267,21 +271,31 @@ RubyPort::MemSlavePort::recvTimingReq(PacketPtr pkt) return true; } - // - // Unless one is using the ruby tester, record the stalled M5 port for - // later retry when the sequencer becomes free. - // - if (!ruby_port->m_usingRubyTester) { - ruby_port->addToRetryList(this); - } DPRINTF(RubyPort, "Request for address %#x did not issued because %s\n", pkt->getAddr(), RequestStatus_to_string(requestStatus)); + addToRetryList(); + return false; } void +RubyPort::MemSlavePort::addToRetryList() +{ + RubyPort *ruby_port = static_cast<RubyPort *>(&owner); + + // + // Unless the requestor do not want retries (e.g., the Ruby tester), + // record the stalled M5 port for later retry when the sequencer + // becomes free. + // + if (!no_retry_on_stall && !ruby_port->onRetryList(this)) { + ruby_port->addToRetryList(this); + } +} + +void RubyPort::MemSlavePort::recvFunctional(PacketPtr pkt) { DPRINTF(RubyPort, "Functional access for address: %#x\n", pkt->getAddr()); @@ -356,31 +370,33 @@ RubyPort::ruby_hit_callback(PacketPtr pkt) port->hitCallback(pkt); + trySendRetries(); +} + +void +RubyPort::trySendRetries() +{ // // If we had to stall the MemSlavePorts, wake them up because the sequencer // likely has free resources now. // if (!retryList.empty()) { - // - // Record the current list of ports to retry on a temporary list before - // calling sendRetry on those ports. sendRetry will cause an - // immediate retry, which may result in the ports being put back on the - // list. Therefore we want to clear the retryList before calling - // sendRetry. - // + // Record the current list of ports to retry on a temporary list + // before calling sendRetryReq on those ports. sendRetryReq will cause + // an immediate retry, which may result in the ports being put back on + // the list. Therefore we want to clear the retryList before calling + // sendRetryReq. std::vector<MemSlavePort *> curRetryList(retryList); retryList.clear(); for (auto i = curRetryList.begin(); i != curRetryList.end(); ++i) { DPRINTF(RubyPort, - "Sequencer may now be free. SendRetry to port %s\n", + "Sequencer may now be free. SendRetry to port %s\n", (*i)->name()); (*i)->sendRetryReq(); } } - - testDrainComplete(); } void diff --git a/src/mem/ruby/system/RubyPort.hh b/src/mem/ruby/system/RubyPort.hh index 58d2558dd..07e0fde5a 100644 --- a/src/mem/ruby/system/RubyPort.hh +++ b/src/mem/ruby/system/RubyPort.hh @@ -11,7 +11,7 @@ * unmodified and in its entirety in all distributions of the software, * modified or unmodified, in source code or in binary form. * - * Copyright (c) 2009 Advanced Micro Devices, Inc. + * Copyright (c) 2009-2013 Advanced Micro Devices, Inc. * Copyright (c) 2011 Mark D. Hill and David A. Wood * All rights reserved. * @@ -76,10 +76,12 @@ class RubyPort : public MemObject private: RespPacketQueue queue; bool access_backing_store; + bool no_retry_on_stall; public: MemSlavePort(const std::string &_name, RubyPort *_port, - bool _access_backing_store, PortID id); + bool _access_backing_store, + PortID id, bool _no_retry_on_stall); void hitCallback(PacketPtr pkt); void evictionCallback(Addr address); @@ -94,6 +96,8 @@ class RubyPort : public MemObject AddrRangeList getAddrRanges() const { AddrRangeList ranges; return ranges; } + void addToRetryList(); + private: bool isPhysMemAddress(Addr addr) const; }; @@ -164,6 +168,7 @@ class RubyPort : public MemObject DrainState drain() override; protected: + void trySendRetries(); void ruby_hit_callback(PacketPtr pkt); void testDrainComplete(); void ruby_eviction_callback(Addr address); @@ -186,10 +191,14 @@ class RubyPort : public MemObject System* system; private: + bool onRetryList(MemSlavePort * port) + { + return (std::find(retryList.begin(), retryList.end(), port) != + retryList.end()); + } void addToRetryList(MemSlavePort * port) { - if (std::find(retryList.begin(), retryList.end(), port) != - retryList.end()) return; + if (onRetryList(port)) return; retryList.push_back(port); } diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc index 26db6b6f8..50418c700 100644 --- a/src/mem/ruby/system/Sequencer.cc +++ b/src/mem/ruby/system/Sequencer.cc @@ -491,6 +491,7 @@ Sequencer::hitCallback(SequencerRequest* srequest, DataBlock& data, rs->m_cache_recorder->enqueueNextFlushRequest(); } else { ruby_hit_callback(pkt); + testDrainComplete(); } } diff --git a/src/mem/ruby/system/Sequencer.py b/src/mem/ruby/system/Sequencer.py index 7494986e9..7c90eb29c 100644 --- a/src/mem/ruby/system/Sequencer.py +++ b/src/mem/ruby/system/Sequencer.py @@ -45,6 +45,7 @@ class RubyPort(MemObject): mem_slave_port = SlavePort("Ruby memory port") using_ruby_tester = Param.Bool(False, "") + no_retry_on_stall = Param.Bool(False, "") ruby_system = Param.RubySystem(Parent.any, "") system = Param.System(Parent.any, "system object") support_data_reqs = Param.Bool(True, "data cache requests supported") |