arm: Wire up the GIC with the platform in the base class
[gem5.git] / src / dev / copy_engine.cc
index 33994cfde02ccbde406c1b43870b55f768205c7a..a3d73b634a71226a8adecbb96f70c6288e388824 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * 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.
  *
@@ -37,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"
@@ -47,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;
@@ -65,10 +78,11 @@ CopyEngine::CopyEngine(const Params *p)
 
 
 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),
+    completionDataReg(0), nextState(Idle), drainManager(NULL),
     fetchCompleteEvent(this), addrCompleteEvent(this),
     readCompleteEvent(this), writeCompleteEvent(this),
     statusCompleteEvent(this)
@@ -94,27 +108,28 @@ CopyEngine::CopyEngineChannel::~CopyEngineChannel()
 {
     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 PciDevice::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
@@ -125,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;
@@ -167,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
     ///
@@ -439,9 +452,9 @@ CopyEngine::CopyEngineChannel::fetchDescriptor(Addr address)
     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;
 }
 
@@ -483,8 +496,8 @@ CopyEngine::CopyEngineChannel::readCopyBytes()
     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
@@ -505,8 +518,8 @@ CopyEngine::CopyEngineChannel::writeCopyBytes()
            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]++;
@@ -574,9 +587,10 @@ CopyEngine::CopyEngineChannel::writeCompletionStatus()
             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
@@ -592,9 +606,10 @@ CopyEngine::CopyEngineChannel::fetchNextAddr(Addr address)
     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
@@ -620,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));
@@ -674,7 +689,7 @@ CopyEngine::serialize(std::ostream &os)
 void
 CopyEngine::unserialize(Checkpoint *cp, const std::string &section)
 {
-    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));
@@ -743,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();