Add the ability for a DMA to tack on an extra delay after the DMA is actually finished.
This commit is contained in:
parent
05954e1ba7
commit
549c43b2d0
2 changed files with 18 additions and 11 deletions
|
@ -138,6 +138,9 @@ DmaPort::recvTiming(PacketPtr pkt)
|
|||
state->numBytes += pkt->req->getSize();
|
||||
assert(state->totBytes >= state->numBytes);
|
||||
if (state->totBytes == state->numBytes) {
|
||||
if (state->delay)
|
||||
state->completionEvent->schedule(state->delay + curTick);
|
||||
else
|
||||
state->completionEvent->process();
|
||||
delete state;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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(); }
|
||||
|
|
Loading…
Reference in a new issue