Add the ability for a DMA to tack on an extra delay after the DMA is actually finished.

This commit is contained in:
Ali Saidi 2008-08-13 17:41:56 -04:00
parent 05954e1ba7
commit 549c43b2d0
2 changed files with 18 additions and 11 deletions

View 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;
}

View 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(); }