Ruby: remove reference to g_system_ptr from class Message
[gem5.git] / src / mem / simple_dram.cc
index 42c97977a4704eedc0afb225aa9e566b127d9326..62825d13905e93189a7c06e8f37b3faa9f1798ed 100644 (file)
@@ -38,6 +38,8 @@
  *          Ani Udipi
  */
 
+#include "base/trace.hh"
+#include "debug/Drain.hh"
 #include "debug/DRAM.hh"
 #include "debug/DRAMWR.hh"
 #include "mem/simple_dram.hh"
@@ -474,6 +476,13 @@ SimpleDRAM::printQs() const {
 bool
 SimpleDRAM::recvTimingReq(PacketPtr pkt)
 {
+    /// @todo temporary hack to deal with memory corruption issues until
+    /// 4-phase transactions are complete
+    for (int x = 0; x < pendingDelete.size(); x++)
+        delete pendingDelete[x];
+    pendingDelete.clear();
+
+
     // This is where we enter from the outside world
     DPRINTF(DRAM, "Inside recvTimingReq: request %s addr %lld size %d\n",
             pkt->cmdString(),pkt->getAddr(), pkt->getSize());
@@ -495,7 +504,7 @@ SimpleDRAM::recvTimingReq(PacketPtr pkt)
     // simply drop inhibited packets for now
     if (pkt->memInhibitAsserted()) {
         DPRINTF(DRAM,"Inhibited packet -- Dropping it now\n");
-        delete pkt;
+        pendingDelete.push_back(pkt);
         return true;
     }
 
@@ -927,15 +936,18 @@ SimpleDRAM::scheduleNextReq()
     DPRINTF(DRAM, "Reached scheduleNextReq()\n");
 
     // Figure out which request goes next, and move it to front()
-    if (!chooseNextReq())
-        return;
-
-    doDRAMAccess(dramReadQueue.front());
+    if (!chooseNextReq()) {
+        // In the case there is no read request to go next, see if we
+        // are asked to drain, and if so trigger writes, this also
+        // ensures that if we hit the write limit we will do this
+        // multiple times until we are completely drained
+        if (drainManager && !dramWriteQueue.empty() && !writeEvent.scheduled())
+            triggerWrites();
+    } else {
+        doDRAMAccess(dramReadQueue.front());
+    }
 }
 
-
-
-
 Tick
 SimpleDRAM::maxBankFreeAt() const
 {
@@ -1205,8 +1217,18 @@ SimpleDRAM::drain(DrainManager *dm)
     // of that as well
     if (!(dramWriteQueue.empty() && dramReadQueue.empty() &&
           dramRespQueue.empty())) {
+        DPRINTF(Drain, "DRAM controller not drained, write: %d, read: %d,"
+                " resp: %d\n", dramWriteQueue.size(), dramReadQueue.size(),
+                dramRespQueue.size());
         ++count;
         drainManager = dm;
+        // the only part that is not drained automatically over time
+        // is the write queue, thus trigger writes if there are any
+        // waiting and no reads waiting, otherwise wait until the
+        // reads are done
+        if (dramReadQueue.empty() && !dramWriteQueue.empty() &&
+            !writeEvent.scheduled())
+            triggerWrites();
     }
 
     if (count)