diff options
author | Ali Saidi <saidi@eecs.umich.edu> | 2008-08-13 17:41:56 -0400 |
---|---|---|
committer | Ali Saidi <saidi@eecs.umich.edu> | 2008-08-13 17:41:56 -0400 |
commit | 549c43b2d0cd2411f7c8eda3f89ce1fd695c17e9 (patch) | |
tree | ef5161f366d27d4a333f0527bcaeef89cc1e1741 | |
parent | 05954e1ba7bb35674b0d12428788998d699f25cb (diff) | |
download | gem5-549c43b2d0cd2411f7c8eda3f89ce1fd695c17e9.tar.xz |
Add the ability for a DMA to tack on an extra delay after the DMA is actually finished.
-rw-r--r-- | src/dev/io_device.cc | 11 | ||||
-rw-r--r-- | src/dev/io_device.hh | 18 |
2 files changed, 18 insertions, 11 deletions
diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc index 527397ed8..b86a2d313 100644 --- a/src/dev/io_device.cc +++ b/src/dev/io_device.cc @@ -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; } diff --git a/src/dev/io_device.hh b/src/dev/io_device.hh index 44aa01798..1e2e623f1 100644 --- a/src/dev/io_device.hh +++ b/src/dev/io_device.hh @@ -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(); } |