Add the ability for a DMA to tack on an extra delay after the DMA is actually finished.
authorAli Saidi <saidi@eecs.umich.edu>
Wed, 13 Aug 2008 21:41:56 +0000 (17:41 -0400)
committerAli Saidi <saidi@eecs.umich.edu>
Wed, 13 Aug 2008 21:41:56 +0000 (17:41 -0400)
src/dev/io_device.cc
src/dev/io_device.hh

index 527397ed899d2156198b0f8cc8e5234d27c8cf3f..b86a2d313a9668f717a28c613e2cb497b306026b 100644 (file)
@@ -138,7 +138,10 @@ DmaPort::recvTiming(PacketPtr pkt)
         state->numBytes += pkt->req->getSize();
         assert(state->totBytes >= state->numBytes);
         if (state->totBytes == state->numBytes) {
-            state->completionEvent->process();
+            if (state->delay)
+                state->completionEvent->schedule(state->delay + curTick);
+            else
+                state->completionEvent->process();
             delete state;
         }
         delete pkt->req;
@@ -216,13 +219,13 @@ DmaPort::recvRetry()
 
 void
 DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
-                   uint8_t *data)
+                   uint8_t *data, Tick delay)
 {
     assert(event);
 
     assert(device->getState() == SimObject::Running);
 
-    DmaReqState *reqState = new DmaReqState(event, this, size);
+    DmaReqState *reqState = new DmaReqState(event, this, size, delay);
 
 
     DPRINTF(DMA, "Starting DMA for addr: %#x size: %d sched: %d\n", addr, size,
@@ -314,7 +317,7 @@ DmaPort::sendDma()
 
         if (state->totBytes == state->numBytes) {
             assert(!state->completionEvent->scheduled());
-            state->completionEvent->schedule(curTick + lat);
+            state->completionEvent->schedule(curTick + lat + state->delay);
             delete state;
             delete pkt->req;
         }
index 44aa01798717d70d5194a7f1db6fe3e64ef0b300..1e2e623f17c3432107112eea53033b963d36701a 100644 (file)
@@ -89,8 +89,12 @@ class DmaPort : public Port
         /** Number of bytes that have been acked for this transaction. */
         Addr numBytes;
 
-        DmaReqState(Event *ce, Port *p, Addr tb)
-            : completionEvent(ce), outPort(p), totBytes(tb), numBytes(0)
+        /** Amount to delay completion of dma by */
+        Tick delay;
+
+        DmaReqState(Event *ce, Port *p, Addr tb, Tick _delay)
+            : completionEvent(ce), outPort(p), totBytes(tb), numBytes(0),
+              delay(_delay)
         {}
     };
 
@@ -144,7 +148,7 @@ class DmaPort : public Port
     DmaPort(DmaDevice *dev, System *s);
 
     void dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
-                   uint8_t *data = NULL);
+                   uint8_t *data, Tick delay);
 
     bool dmaPending() { return pendingCount > 0; }
 
@@ -265,14 +269,14 @@ class DmaDevice : public PioDevice
         return dynamic_cast<const Params *>(_params);
     }
 
-    void dmaWrite(Addr addr, int size, Event *event, uint8_t *data)
+    void dmaWrite(Addr addr, int size, Event *event, uint8_t *data, Tick delay = 0)
     {
-        dmaPort->dmaAction(MemCmd::WriteReq, addr, size, event, data);
+        dmaPort->dmaAction(MemCmd::WriteReq, addr, size, event, data, delay);
     }
 
-    void dmaRead(Addr addr, int size, Event *event, uint8_t *data)
+    void dmaRead(Addr addr, int size, Event *event, uint8_t *data, Tick delay = 0)
     {
-        dmaPort->dmaAction(MemCmd::ReadReq, addr, size, event, data);
+        dmaPort->dmaAction(MemCmd::ReadReq, addr, size, event, data, delay);
     }
 
     bool dmaPending() { return dmaPort->dmaPending(); }