diff --git a/src/mem/dram_interface.hh b/src/mem/dram_interface.hh index fa9d319a0c..e20e33faf9 100644 --- a/src/mem/dram_interface.hh +++ b/src/mem/dram_interface.hh @@ -380,7 +380,18 @@ class DRAMInterface : public MemInterface * @param Return true if the rank is idle from a bank * and power point of view */ - bool inPwrIdleState() const { return pwrState == PWR_IDLE; } + bool + inPwrIdleState() const + { + // If powerdown is not enabled, then the ranks never go to idle + // states. In that case return true here to prevent checkpointing + // from getting stuck waiting for DRAM to be idle. + if (!dram.enableDRAMPowerdown) { + return true; + } + + return pwrState == PWR_IDLE; + } /** * Trigger a self-refresh exit if there are entries enqueued diff --git a/src/mem/mem_ctrl.cc b/src/mem/mem_ctrl.cc index 543d6373d9..290db3ebe7 100644 --- a/src/mem/mem_ctrl.cc +++ b/src/mem/mem_ctrl.cc @@ -908,6 +908,13 @@ MemCtrl::processNextReqEvent(MemInterface* mem_intr, } } + if (drainState() == DrainState::Draining && !totalWriteQueueSize && + !totalReadQueueSize && respQEmpty() && allIntfDrained()) { + + DPRINTF(Drain, "MemCtrl controller done draining\n"); + signalDrainDone(); + } + // updates current state busState = busStateNext; @@ -1411,8 +1418,8 @@ MemCtrl::drain() { // if there is anything in any of our internal queues, keep track // of that as well - if (!(!totalWriteQueueSize && !totalReadQueueSize && respQueue.empty() && - allIntfDrained())) { + if (totalWriteQueueSize || totalReadQueueSize || !respQueue.empty() || + !allIntfDrained()) { DPRINTF(Drain, "Memory controller not drained, write: %d, read: %d," " resp: %d\n", totalWriteQueueSize, totalReadQueueSize, @@ -1420,7 +1427,8 @@ MemCtrl::drain() // the only queue that is not drained automatically over time // is the write queue, thus kick things into action if needed - if (!totalWriteQueueSize && !nextReqEvent.scheduled()) { + if (totalWriteQueueSize && !nextReqEvent.scheduled()) { + DPRINTF(Drain,"Scheduling nextReqEvent from drain\n"); schedule(nextReqEvent, curTick()); }