summaryrefslogtreecommitdiff
path: root/src/dev
diff options
context:
space:
mode:
authorAli Saidi <Ali.Saidi@ARM.com>2010-06-02 12:58:16 -0500
committerAli Saidi <Ali.Saidi@ARM.com>2010-06-02 12:58:16 -0500
commitf246be4cbc27b4173f6917b430a31b9a39cdb380 (patch)
tree20a36c989e5040445534ecd58ceae3d13ee152f7 /src/dev
parent1546d8208b2013af1dc1951f7cb35857f2e50897 (diff)
downloadgem5-f246be4cbc27b4173f6917b430a31b9a39cdb380.tar.xz
DMA: Make DmaPort generic enough to be used other places
Diffstat (limited to 'src/dev')
-rw-r--r--src/dev/copy_engine.cc3
-rw-r--r--src/dev/io_device.cc35
-rw-r--r--src/dev/io_device.hh16
3 files changed, 32 insertions, 22 deletions
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<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;