DMA: Make DmaPort generic enough to be used other places
This commit is contained in:
parent
1546d8208b
commit
f246be4cbc
3 changed files with 32 additions and 22 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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<PacketPtr> 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<DmaPort, &DmaPort::sendDma> 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;
|
||||
|
|
Loading…
Reference in a new issue