X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fdev%2Fcopy_engine.cc;h=a3d73b634a71226a8adecbb96f70c6288e388824;hb=0a2ee7761617355dd981ce255aa082102d7316b4;hp=7b17a86a342cb55e0b35c099c3e6b5f681af5e88;hpb=1031b824b975cec999c37cabc8c05c485a4ae5ca;p=gem5.git diff --git a/src/dev/copy_engine.cc b/src/dev/copy_engine.cc index 7b17a86a3..a3d73b634 100644 --- a/src/dev/copy_engine.cc +++ b/src/dev/copy_engine.cc @@ -49,6 +49,7 @@ #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" @@ -59,7 +60,7 @@ using namespace CopyEngineReg; CopyEngine::CopyEngine(const Params *p) - : PciDev(p) + : PciDevice(p) { // All Reg regs are initialized to 0 by default regs.chanCount = p->ChanCnt; @@ -77,12 +78,11 @@ CopyEngine::CopyEngine(const Params *p) CopyEngine::CopyEngineChannel::CopyEngineChannel(CopyEngine *_ce, int cid) - : cePort(_ce, _ce->sys, _ce->params()->min_backoff_delay, - _ce->params()->max_backoff_delay), + : 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), + completionDataReg(0), nextState(Idle), drainManager(NULL), fetchCompleteEvent(this), addrCompleteEvent(this), readCompleteEvent(this), writeCompleteEvent(this), statusCompleteEvent(this) @@ -110,21 +110,26 @@ CopyEngine::CopyEngineChannel::~CopyEngineChannel() delete [] copyBuffer; } -Port * -CopyEngine::getPort(const std::string &if_name, int idx) +BaseMasterPort & +CopyEngine::getMasterPort(const std::string &if_name, PortID idx) { - if (if_name == "dma") { - if (idx < chan.size()) - return chan[idx]->getPort(); + if (if_name != "dma") { + // pass it along to our super class + return PciDevice::getMasterPort(if_name, idx); + } else { + if (idx >= static_cast(chan.size())) { + panic("CopyEngine::getMasterPort: unknown index %d\n", idx); + } + + return chan[idx]->getMasterPort(); } - return PciDev::getPort(if_name, idx); } -Port * -CopyEngine::CopyEngineChannel::getPort() +BaseMasterPort & +CopyEngine::CopyEngineChannel::getMasterPort() { - return &cePort; + return cePort; } void @@ -135,12 +140,12 @@ CopyEngine::CopyEngineChannel::recvCommand() cr.status.dma_transfer_status(0); nextState = DescriptorFetch; fetchAddress = cr.descChainAddr; - if (ce->getState() == SimObject::Running) + if (ce->getDrainState() == Drainable::Running) fetchDescriptor(cr.descChainAddr); } else if (cr.command.append_dma()) { if (!busy) { nextState = AddressFetch; - if (ce->getState() == SimObject::Running) + if (ce->getDrainState() == Drainable::Running) fetchNextAddr(lastDescriptorAddr); } else refreshNext = true; @@ -177,8 +182,6 @@ CopyEngine::read(PacketPtr pkt) DPRINTF(DMACopyEngine, "Read device register %#X size: %d\n", daddr, size); - pkt->allocate(); - /// /// Handle read of register here /// @@ -632,50 +635,50 @@ CopyEngine::CopyEngineChannel::fetchAddrComplete() bool CopyEngine::CopyEngineChannel::inDrain() { - if (ce->getState() == SimObject::Draining) { - DPRINTF(DMACopyEngine, "processing drain\n"); - assert(drainEvent); - drainEvent->process(); - drainEvent = NULL; + if (ce->getDrainState() == Drainable::Draining) { + DPRINTF(Drain, "CopyEngine done draining, processing drain event\n"); + assert(drainManager); + drainManager->signalDrainDone(); + drainManager = NULL; } - return ce->getState() != SimObject::Running; + return ce->getDrainState() != Drainable::Running; } unsigned int -CopyEngine::CopyEngineChannel::drain(Event *de) +CopyEngine::CopyEngineChannel::drain(DrainManager *dm) { - if (nextState == Idle || ce->getState() != SimObject::Running) + if (nextState == Idle || ce->getDrainState() != Drainable::Running) return 0; unsigned int count = 1; - count += cePort.drain(de); + count += cePort.drain(dm); - DPRINTF(DMACopyEngine, "unable to drain, returning %d\n", count); - drainEvent = de; + DPRINTF(Drain, "CopyEngineChannel not drained\n"); + this->drainManager = dm; return count; } unsigned int -CopyEngine::drain(Event *de) +CopyEngine::drain(DrainManager *dm) { unsigned int count; - count = pioPort.drain(de) + dmaPort.drain(de) + configPort.drain(de); + count = pioPort.drain(dm) + dmaPort.drain(dm) + configPort.drain(dm); for (int x = 0;x < chan.size(); x++) - count += chan[x]->drain(de); + count += chan[x]->drain(dm); if (count) - changeState(Draining); + setDrainState(Draining); else - changeState(Drained); + setDrainState(Drained); - DPRINTF(DMACopyEngine, "call to CopyEngine::drain() returning %d\n", count); + DPRINTF(Drain, "CopyEngine not drained\n"); return count; } void CopyEngine::serialize(std::ostream &os) { - PciDev::serialize(os); + PciDevice::serialize(os); regs.serialize(os); for (int x =0; x < chan.size(); x++) { nameOut(os, csprintf("%s.channel%d", name(), x)); @@ -686,7 +689,7 @@ CopyEngine::serialize(std::ostream &os) void CopyEngine::unserialize(Checkpoint *cp, const std::string §ion) { - PciDev::unserialize(cp, section); + PciDevice::unserialize(cp, section); regs.unserialize(cp, section); for (int x = 0; x < chan.size(); x++) chan[x]->unserialize(cp, csprintf("%s.channel%d", section, x)); @@ -755,16 +758,16 @@ CopyEngine::CopyEngineChannel::restartStateMachine() } void -CopyEngine::resume() +CopyEngine::drainResume() { - SimObject::resume(); + Drainable::drainResume(); for (int x = 0;x < chan.size(); x++) - chan[x]->resume(); + chan[x]->drainResume(); } void -CopyEngine::CopyEngineChannel::resume() +CopyEngine::CopyEngineChannel::drainResume() { DPRINTF(DMACopyEngine, "Restarting state machine at state %d\n", nextState); restartStateMachine();