/*
+ * Copyright (c) 2012 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2008 The Regents of The University of Michigan
* All rights reserved.
*
#include "base/cp_annotate.hh"
#include "base/trace.hh"
#include "debug/DMACopyEngine.hh"
+#include "debug/Drain.hh"
#include "dev/copy_engine.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
CopyEngine::CopyEngineChannel::CopyEngineChannel(CopyEngine *_ce, int cid)
- : ce(_ce), channelId(cid), busy(false), underReset(false),
+ : cePort(_ce, _ce->sys),
+ ce(_ce), channelId(cid), busy(false), underReset(false),
refreshNext(false), latBeforeBegin(ce->params()->latBeforeBegin),
latAfterCompletion(ce->params()->latAfterCompletion),
completionDataReg(0), nextState(Idle), drainEvent(NULL),
{
delete curDmaDesc;
delete [] copyBuffer;
- delete cePort;
}
-void
-CopyEngine::init()
+BaseMasterPort &
+CopyEngine::getMasterPort(const std::string &if_name, PortID idx)
{
- PciDev::init();
- for (int x = 0; x < chan.size(); x++)
- chan[x]->init();
+ if (if_name != "dma") {
+ // pass it along to our super class
+ return PciDev::getMasterPort(if_name, idx);
+ } else {
+ if (idx >= static_cast<int>(chan.size())) {
+ panic("CopyEngine::getMasterPort: unknown index %d\n", idx);
+ }
+
+ return chan[idx]->getMasterPort();
+ }
}
-void
-CopyEngine::CopyEngineChannel::init()
-{
- Port *peer;
- 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);
+BaseMasterPort &
+CopyEngine::CopyEngineChannel::getMasterPort()
+{
+ return cePort;
}
void
DPRINTF(DMACopyEngine, "dmaAction: %#x, %d bytes, to addr %#x\n",
ce->platform->pciToDma(address), sizeof(DmaDesc), curDmaDesc);
- cePort->dmaAction(MemCmd::ReadReq, ce->platform->pciToDma(address),
- sizeof(DmaDesc), &fetchCompleteEvent, (uint8_t*)curDmaDesc,
- latBeforeBegin);
+ cePort.dmaAction(MemCmd::ReadReq, ce->platform->pciToDma(address),
+ sizeof(DmaDesc), &fetchCompleteEvent,
+ (uint8_t*)curDmaDesc, latBeforeBegin);
lastDescriptorAddr = address;
}
DPRINTF(DMACopyEngine, "Reading %d bytes from buffer to memory location %#x(%#x)\n",
curDmaDesc->len, curDmaDesc->dest,
ce->platform->pciToDma(curDmaDesc->src));
- cePort->dmaAction(MemCmd::ReadReq, ce->platform->pciToDma(curDmaDesc->src),
- curDmaDesc->len, &readCompleteEvent, copyBuffer, 0);
+ cePort.dmaAction(MemCmd::ReadReq, ce->platform->pciToDma(curDmaDesc->src),
+ curDmaDesc->len, &readCompleteEvent, copyBuffer, 0);
}
void
curDmaDesc->len, curDmaDesc->dest,
ce->platform->pciToDma(curDmaDesc->dest));
- cePort->dmaAction(MemCmd::WriteReq, ce->platform->pciToDma(curDmaDesc->dest),
- curDmaDesc->len, &writeCompleteEvent, copyBuffer, 0);
+ cePort.dmaAction(MemCmd::WriteReq, ce->platform->pciToDma(curDmaDesc->dest),
+ curDmaDesc->len, &writeCompleteEvent, copyBuffer, 0);
ce->bytesCopied[channelId] += curDmaDesc->len;
ce->copiesProcessed[channelId]++;
completionDataReg, cr.completionAddr,
ce->platform->pciToDma(cr.completionAddr));
- cePort->dmaAction(MemCmd::WriteReq, ce->platform->pciToDma(cr.completionAddr),
- sizeof(completionDataReg), &statusCompleteEvent,
- (uint8_t*)&completionDataReg, latAfterCompletion);
+ cePort.dmaAction(MemCmd::WriteReq,
+ ce->platform->pciToDma(cr.completionAddr),
+ sizeof(completionDataReg), &statusCompleteEvent,
+ (uint8_t*)&completionDataReg, latAfterCompletion);
}
void
anBegin("FetchNextAddr");
DPRINTF(DMACopyEngine, "Fetching next address...\n");
busy = true;
- cePort->dmaAction(MemCmd::ReadReq, ce->platform->pciToDma(address +
- offsetof(DmaDesc, next)), sizeof(Addr), &addrCompleteEvent,
- (uint8_t*)curDmaDesc + offsetof(DmaDesc, next), 0);
+ cePort.dmaAction(MemCmd::ReadReq,
+ ce->platform->pciToDma(address + offsetof(DmaDesc, next)),
+ sizeof(Addr), &addrCompleteEvent,
+ (uint8_t*)curDmaDesc + offsetof(DmaDesc, next), 0);
}
void
CopyEngine::CopyEngineChannel::inDrain()
{
if (ce->getState() == SimObject::Draining) {
- DPRINTF(DMACopyEngine, "processing drain\n");
+ DPRINTF(Drain, "CopyEngine done draining, processing drain event\n");
assert(drainEvent);
drainEvent->process();
drainEvent = NULL;
if (nextState == Idle || ce->getState() != SimObject::Running)
return 0;
unsigned int count = 1;
- count += cePort->drain(de);
+ count += cePort.drain(de);
- DPRINTF(DMACopyEngine, "unable to drain, returning %d\n", count);
+ DPRINTF(Drain, "CopyEngineChannel not drained\n");
drainEvent = de;
return count;
}
CopyEngine::drain(Event *de)
{
unsigned int count;
- count = pioPort->drain(de) + dmaPort->drain(de) + configPort->drain(de);
+ count = pioPort.drain(de) + dmaPort.drain(de) + configPort.drain(de);
for (int x = 0;x < chan.size(); x++)
count += chan[x]->drain(de);
else
changeState(Drained);
- DPRINTF(DMACopyEngine, "call to CopyEngine::drain() returning %d\n", count);
+ DPRINTF(Drain, "CopyEngine not drained\n");
return count;
}