diff options
Diffstat (limited to 'src/dev/io_device.cc')
-rw-r--r-- | src/dev/io_device.cc | 275 |
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); -} - |