summaryrefslogtreecommitdiff
path: root/src/dev/io_device.cc
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2012-05-23 09:15:45 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2012-05-23 09:15:45 -0400
commitd4847fe6ea63a1122ed14e6ac6d10ef0a8469194 (patch)
treeb0f2b009c004210e3866e2f1514e55b7eac3785a /src/dev/io_device.cc
parent5b36cf623cd065eea4f7b5e8b892dc904c030d56 (diff)
downloadgem5-d4847fe6ea63a1122ed14e6ac6d10ef0a8469194.tar.xz
DMA: Split the DMA device and IO device into seperate files
This patch moves the DMA device to its own set of files, splitting it from the IO device. There are no behavioural changes associated with this patch. The patch also grabs the opportunity to do some very minor tidying up, including some white space removal and pruning some redundant parameters. Besides the immediate benefits of the separation-of-concerns, this patch also makes upcoming changes more streamlined as it split the devices that are only slaves and the DMA device that also acts as a master. --HG-- rename : src/dev/io_device.cc => src/dev/dma_device.cc rename : src/dev/io_device.hh => src/dev/dma_device.hh
Diffstat (limited to 'src/dev/io_device.cc')
-rw-r--r--src/dev/io_device.cc275
1 files changed, 1 insertions, 274 deletions
diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc
index 83d3af095..100c04828 100644
--- a/src/dev/io_device.cc
+++ b/src/dev/io_device.cc
@@ -41,19 +41,16 @@
* Nathan Binkert
*/
-#include "base/chunk_generator.hh"
#include "base/trace.hh"
#include "debug/BusAddrRanges.hh"
-#include "debug/DMA.hh"
#include "dev/io_device.hh"
#include "sim/system.hh"
PioPort::PioPort(PioDevice *dev)
- : SimpleTimingPort(dev->name() + "-pioport", dev), device(dev)
+ : SimpleTimingPort(dev->name() + "-pio", dev), device(dev)
{
}
-
Tick
PioPort::recvAtomic(PacketPtr pkt)
{
@@ -66,7 +63,6 @@ PioPort::getAddrRanges()
return device->getAddrRanges();
}
-
PioDevice::PioDevice(const Params *p)
: MemObject(p), sys(p->system), pioPort(this)
{}
@@ -118,272 +114,3 @@ BasicPioDevice::getAddrRanges()
ranges.push_back(RangeSize(pioAddr, pioSize));
return ranges;
}
-
-
-DmaPort::DmaPort(MemObject *dev, System *s, Tick min_backoff, Tick max_backoff)
- : MasterPort(dev->name() + "-dma", dev), device(dev), sys(s),
- masterId(s->getMasterId(dev->name())),
- pendingCount(0), actionInProgress(0), drainEvent(NULL),
- backoffTime(0), minBackoffDelay(min_backoff),
- maxBackoffDelay(max_backoff), inRetry(false),
- backoffEvent(this)
-{ }
-
-bool
-DmaPort::recvTimingResp(PacketPtr pkt)
-{
- if (pkt->wasNacked()) {
- DPRINTF(DMA, "Received nacked %s addr %#x\n",
- pkt->cmdString(), pkt->getAddr());
-
- if (backoffTime < minBackoffDelay)
- backoffTime = minBackoffDelay;
- else if (backoffTime < maxBackoffDelay)
- backoffTime <<= 1;
-
- device->reschedule(backoffEvent, curTick() + backoffTime, true);
-
- DPRINTF(DMA, "Backoff time set to %d ticks\n", backoffTime);
-
- pkt->reinitNacked();
- queueDma(pkt, true);
- } else if (pkt->senderState) {
- DmaReqState *state;
- backoffTime >>= 2;
-
- DPRINTF(DMA, "Received response %s addr %#x size %#x\n",
- pkt->cmdString(), pkt->getAddr(), pkt->req->getSize());
- state = dynamic_cast<DmaReqState*>(pkt->senderState);
- pendingCount--;
-
- assert(pendingCount >= 0);
- assert(state);
-
- // We shouldn't ever get a block in ownership state
- assert(!(pkt->memInhibitAsserted() && !pkt->sharedAsserted()));
-
- state->numBytes += pkt->req->getSize();
- assert(state->totBytes >= state->numBytes);
- if (state->totBytes == state->numBytes) {
- if (state->completionEvent) {
- if (state->delay)
- device->schedule(state->completionEvent,
- curTick() + state->delay);
- else
- state->completionEvent->process();
- }
- delete state;
- }
- delete pkt->req;
- delete pkt;
-
- if (pendingCount == 0 && drainEvent) {
- drainEvent->process();
- drainEvent = NULL;
- }
- } else {
- panic("Got packet without sender state... huh?\n");
- }
-
- return true;
-}
-
-DmaDevice::DmaDevice(const Params *p)
- : PioDevice(p), dmaPort(this, sys, params()->min_backoff_delay,
- params()->max_backoff_delay)
-{ }
-
-void
-DmaDevice::init()
-{
- if (!dmaPort.isConnected())
- panic("DMA port of %s not connected to anything!", name());
- PioDevice::init();
-}
-
-unsigned int
-DmaDevice::drain(Event *de)
-{
- unsigned int count;
- count = pioPort.drain(de) + dmaPort.drain(de);
- if (count)
- changeState(Draining);
- else
- changeState(Drained);
- return count;
-}
-
-unsigned int
-DmaPort::drain(Event *de)
-{
- if (pendingCount == 0)
- return 0;
- drainEvent = de;
- return 1;
-}
-
-
-void
-DmaPort::recvRetry()
-{
- assert(transmitList.size());
- bool result = true;
- do {
- PacketPtr pkt = transmitList.front();
- DPRINTF(DMA, "Retry on %s addr %#x\n",
- pkt->cmdString(), pkt->getAddr());
- result = sendTimingReq(pkt);
- if (result) {
- DPRINTF(DMA, "-- Done\n");
- transmitList.pop_front();
- inRetry = false;
- } else {
- inRetry = true;
- DPRINTF(DMA, "-- Failed, queued\n");
- }
- } while (!backoffTime && result && transmitList.size());
-
- if (transmitList.size() && backoffTime && !inRetry) {
- DPRINTF(DMA, "Scheduling backoff for %d\n", curTick()+backoffTime);
- if (!backoffEvent.scheduled())
- device->schedule(backoffEvent, backoffTime + curTick());
- }
- DPRINTF(DMA, "TransmitList: %d, backoffTime: %d inRetry: %d es: %d\n",
- transmitList.size(), backoffTime, inRetry,
- backoffEvent.scheduled());
-}
-
-
-void
-DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
- uint8_t *data, Tick delay, Request::Flags flag)
-{
- assert(device->getState() == SimObject::Running);
-
- DmaReqState *reqState = new DmaReqState(event, this, size, delay);
-
-
- DPRINTF(DMA, "Starting DMA for addr: %#x size: %d sched: %d\n", addr, size,
- event ? event->scheduled() : -1 );
- for (ChunkGenerator gen(addr, size, peerBlockSize());
- !gen.done(); gen.next()) {
- Request *req = new Request(gen.addr(), gen.size(), flag, masterId);
- PacketPtr pkt = new Packet(req, cmd);
-
- // Increment the data pointer on a write
- if (data)
- pkt->dataStatic(data + gen.complete());
-
- pkt->senderState = reqState;
-
- assert(pendingCount >= 0);
- pendingCount++;
- DPRINTF(DMA, "--Queuing DMA for addr: %#x size: %d\n", gen.addr(),
- gen.size());
- queueDma(pkt);
- }
-
-}
-
-void
-DmaPort::queueDma(PacketPtr pkt, bool front)
-{
-
- if (front)
- transmitList.push_front(pkt);
- else
- transmitList.push_back(pkt);
- sendDma();
-}
-
-
-void
-DmaPort::sendDma()
-{
- // some kind of selction between access methods
- // more work is going to have to be done to make
- // switching actually work
- assert(transmitList.size());
- PacketPtr pkt = transmitList.front();
-
- Enums::MemoryMode state = sys->getMemoryMode();
- if (state == Enums::timing) {
- if (backoffEvent.scheduled() || inRetry) {
- DPRINTF(DMA, "Can't send immediately, waiting for retry or backoff timer\n");
- return;
- }
-
- DPRINTF(DMA, "Attempting to send %s addr %#x\n",
- pkt->cmdString(), pkt->getAddr());
-
- bool result;
- do {
- result = sendTimingReq(pkt);
- if (result) {
- transmitList.pop_front();
- DPRINTF(DMA, "-- Done\n");
- } else {
- inRetry = true;
- DPRINTF(DMA, "-- Failed: queued\n");
- }
- } while (result && !backoffTime && transmitList.size());
-
- if (transmitList.size() && backoffTime && !inRetry &&
- !backoffEvent.scheduled()) {
- DPRINTF(DMA, "-- Scheduling backoff timer for %d\n",
- backoffTime+curTick());
- device->schedule(backoffEvent, backoffTime + curTick());
- }
- } else if (state == Enums::atomic) {
- transmitList.pop_front();
-
- Tick lat;
- DPRINTF(DMA, "--Sending DMA for addr: %#x size: %d\n",
- pkt->req->getPaddr(), pkt->req->getSize());
- lat = sendAtomic(pkt);
- assert(pkt->senderState);
- DmaReqState *state = dynamic_cast<DmaReqState*>(pkt->senderState);
- assert(state);
- state->numBytes += pkt->req->getSize();
-
- 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 ? state->completionEvent->scheduled() : 0 );
-
- if (state->totBytes == state->numBytes) {
- if (state->completionEvent) {
- assert(!state->completionEvent->scheduled());
- device->schedule(state->completionEvent,
- curTick() + lat + state->delay);
- }
- delete state;
- delete pkt->req;
- }
- pendingCount--;
- assert(pendingCount >= 0);
- delete pkt;
-
- if (pendingCount == 0 && drainEvent) {
- drainEvent->process();
- drainEvent = NULL;
- }
-
- } else
- panic("Unknown memory command state.");
-}
-
-DmaDevice::~DmaDevice()
-{
-}
-
-
-MasterPort &
-DmaDevice::getMasterPort(const std::string &if_name, int idx)
-{
- if (if_name == "dma") {
- return dmaPort;
- }
- return PioDevice::getMasterPort(if_name, idx);
-}
-