diff options
Diffstat (limited to 'src/mem')
-rw-r--r-- | src/mem/ruby/system/DMASequencer.cc | 8 | ||||
-rw-r--r-- | src/mem/ruby/system/RubyPort.cc | 24 |
2 files changed, 23 insertions, 9 deletions
diff --git a/src/mem/ruby/system/DMASequencer.cc b/src/mem/ruby/system/DMASequencer.cc index fbaf5f1d1..e8e279043 100644 --- a/src/mem/ruby/system/DMASequencer.cc +++ b/src/mem/ruby/system/DMASequencer.cc @@ -116,9 +116,13 @@ DMASequencer::issueNext() assert(m_is_busy == true); active_request.bytes_completed = active_request.bytes_issued; if (active_request.len == active_request.bytes_completed) { - DPRINTF(RubyDma, "DMA request completed\n"); - ruby_hit_callback(active_request.pkt); + // + // Must unset the busy flag before calling back the dma port because + // the callback may cause a previously nacked request to be reissued + // + DPRINTF(RubyDma, "DMA request completed\n"); m_is_busy = false; + ruby_hit_callback(active_request.pkt); return; } diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc index f4bc5c95c..c79154566 100644 --- a/src/mem/ruby/system/RubyPort.cc +++ b/src/mem/ruby/system/RubyPort.cc @@ -305,16 +305,26 @@ RubyPort::ruby_hit_callback(PacketPtr pkt) // likely has free resources now. // if (waitingOnSequencer) { - for (std::list<M5Port*>::iterator i = retryList.begin(); - i != retryList.end(); ++i) { - (*i)->sendRetry(); - (*i)->onRetryList(false); - DPRINTF(MemoryAccess, + // + // 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. + // + std::list<M5Port*> curRetryList(retryList); + + retryList.clear(); + waitingOnSequencer = false; + + for (std::list<M5Port*>::iterator i = curRetryList.begin(); + i != curRetryList.end(); ++i) { + DPRINTF(RubyPort, "Sequencer may now be free. SendRetry to port %s\n", (*i)->name()); + (*i)->onRetryList(false); + (*i)->sendRetry(); } - retryList.clear(); - waitingOnSequencer = false; } } |