diff --git a/src/dev/copy_engine.cc b/src/dev/copy_engine.cc index 3c759ac1d..feb0342de 100644 --- a/src/dev/copy_engine.cc +++ b/src/dev/copy_engine.cc @@ -110,7 +110,8 @@ CopyEngine::CopyEngineChannel::init() { Port *peer; - cePort = new DmaPort(ce, ce->sys); + cePort = new DmaPort(ce, ce->sys, ce->params()->min_backoff_delay, + ce->params()->max_backoff_delay); peer = ce->dmaPort->getPeer()->getOwner()->getPort(""); peer->setPeer(cePort); cePort->setPeer(peer); diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc index cdba171a6..b3054a6ee 100644 --- a/src/dev/io_device.cc +++ b/src/dev/io_device.cc @@ -99,10 +99,11 @@ BasicPioDevice::addressRanges(AddrRangeList &range_list) } -DmaPort::DmaPort(DmaDevice *dev, System *s) +DmaPort::DmaPort(MemObject *dev, System *s, Tick min_backoff, Tick max_backoff) : Port(dev->name() + "-dmaport", dev), device(dev), sys(s), pendingCount(0), actionInProgress(0), drainEvent(NULL), - backoffTime(0), inRetry(false), backoffEvent(this) + backoffTime(0), minBackoffDelay(min_backoff), + maxBackoffDelay(max_backoff), inRetry(false), backoffEvent(this) { } bool @@ -112,9 +113,9 @@ DmaPort::recvTiming(PacketPtr pkt) DPRINTF(DMA, "Received nacked %s addr %#x\n", pkt->cmdString(), pkt->getAddr()); - if (backoffTime < device->minBackoffDelay) - backoffTime = device->minBackoffDelay; - else if (backoffTime < device->maxBackoffDelay) + if (backoffTime < minBackoffDelay) + backoffTime = minBackoffDelay; + else if (backoffTime < maxBackoffDelay) backoffTime <<= 1; reschedule(backoffEvent, curTick + backoffTime, true); @@ -138,10 +139,12 @@ DmaPort::recvTiming(PacketPtr pkt) state->numBytes += pkt->req->getSize(); assert(state->totBytes >= state->numBytes); if (state->totBytes == state->numBytes) { - if (state->delay) - schedule(state->completionEvent, curTick + state->delay); - else - state->completionEvent->process(); + if (state->completionEvent) { + if (state->delay) + schedule(state->completionEvent, curTick + state->delay); + else + state->completionEvent->process(); + } delete state; } delete pkt->req; @@ -159,8 +162,7 @@ DmaPort::recvTiming(PacketPtr pkt) } DmaDevice::DmaDevice(const Params *p) - : PioDevice(p), dmaPort(NULL), minBackoffDelay(p->min_backoff_delay), - maxBackoffDelay(p->max_backoff_delay) + : PioDevice(p), dmaPort(NULL) { } @@ -221,8 +223,6 @@ void DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, uint8_t *data, Tick delay) { - assert(event); - assert(device->getState() == SimObject::Running); DmaReqState *reqState = new DmaReqState(event, this, size, delay); @@ -313,11 +313,14 @@ DmaPort::sendDma() DPRINTF(DMA, "--Received response for DMA for addr: %#x size: %d nb: %d, tot: %d sched %d\n", pkt->req->getPaddr(), pkt->req->getSize(), state->numBytes, - state->totBytes, state->completionEvent->scheduled()); + state->totBytes, + state->completionEvent ? state->completionEvent->scheduled() : 0 ); if (state->totBytes == state->numBytes) { - assert(!state->completionEvent->scheduled()); - schedule(state->completionEvent, curTick + lat + state->delay); + if (state->completionEvent) { + assert(!state->completionEvent->scheduled()); + schedule(state->completionEvent, curTick + lat + state->delay); + } delete state; delete pkt->req; } diff --git a/src/dev/io_device.hh b/src/dev/io_device.hh index 54128e48f..9ed287589 100644 --- a/src/dev/io_device.hh +++ b/src/dev/io_device.hh @@ -92,13 +92,14 @@ class DmaPort : public Port /** 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) {} }; - DmaDevice *device; + MemObject *device; std::list transmitList; /** The system that device/port are in. This is used to select which mode @@ -119,6 +120,12 @@ class DmaPort : public Port * recived, decreases as responses are recived. */ Tick backoffTime; + /** Minimum time that device should back off for after failed sendTiming */ + Tick minBackoffDelay; + + /** Maximum time that device should back off for after failed sendTiming */ + Tick maxBackoffDelay; + /** If the port is currently waiting for a retry before it can send whatever * it is that it's sending. */ bool inRetry; @@ -145,7 +152,7 @@ class DmaPort : public Port EventWrapper backoffEvent; public: - DmaPort(DmaDevice *dev, System *s); + DmaPort(MemObject *dev, System *s, Tick min_backoff, Tick max_backoff); void dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, uint8_t *data, Tick delay); @@ -256,8 +263,6 @@ class DmaDevice : public PioDevice { protected: DmaPort *dmaPort; - Tick minBackoffDelay; - Tick maxBackoffDelay; public: typedef DmaDeviceParams Params; @@ -298,7 +303,8 @@ class DmaDevice : public PioDevice if (dmaPort != NULL) fatal("%s: dma port already connected to %s", name(), dmaPort->getPeer()->name()); - dmaPort = new DmaPort(this, sys); + dmaPort = new DmaPort(this, sys, params()->min_backoff_delay, + params()->max_backoff_delay); return dmaPort; } else return NULL;