gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
copy_engine.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Copyright (c) 2008 The Regents of The University of Michigan
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are
19  * met: redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer;
21  * redistributions in binary form must reproduce the above copyright
22  * notice, this list of conditions and the following disclaimer in the
23  * documentation and/or other materials provided with the distribution;
24  * neither the name of the copyright holders nor the names of its
25  * contributors may be used to endorse or promote products derived from
26  * this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  *
40  * Authors: Ali Saidi
41  */
42 
43 /* @file
44  * Device model for Intel's I/O AT DMA copy engine.
45  */
46 
47 #include "dev/pci/copy_engine.hh"
48 
49 #include <algorithm>
50 
51 #include "base/cp_annotate.hh"
52 #include "base/trace.hh"
53 #include "debug/DMACopyEngine.hh"
54 #include "debug/Drain.hh"
55 #include "mem/packet.hh"
56 #include "mem/packet_access.hh"
57 #include "params/CopyEngine.hh"
58 #include "sim/stats.hh"
59 #include "sim/system.hh"
60 
61 using namespace CopyEngineReg;
62 
64  : PciDevice(p)
65 {
66  // All Reg regs are initialized to 0 by default
67  regs.chanCount = p->ChanCnt;
68  regs.xferCap = findMsbSet(p->XferCap);
69  regs.attnStatus = 0;
70 
71  if (regs.chanCount > 64)
72  fatal("CopyEngine interface doesn't support more than 64 DMA engines\n");
73 
74  for (int x = 0; x < regs.chanCount; x++) {
75  CopyEngineChannel *ch = new CopyEngineChannel(this, x);
76  chan.push_back(ch);
77  }
78 }
79 
80 
82  : cePort(_ce, _ce->sys),
83  ce(_ce), channelId(cid), busy(false), underReset(false),
84  refreshNext(false), latBeforeBegin(ce->params()->latBeforeBegin),
85  latAfterCompletion(ce->params()->latAfterCompletion),
86  completionDataReg(0), nextState(Idle),
87  fetchCompleteEvent(this), addrCompleteEvent(this),
88  readCompleteEvent(this), writeCompleteEvent(this),
89  statusCompleteEvent(this)
90 
91 {
92  cr.status.dma_transfer_status(3);
93  cr.descChainAddr = 0;
94  cr.completionAddr = 0;
95 
96  curDmaDesc = new DmaDesc;
97  memset(curDmaDesc, 0, sizeof(DmaDesc));
98  copyBuffer = new uint8_t[ce->params()->XferCap];
99 }
100 
102 {
103  for (int x = 0; x < chan.size(); x++) {
104  delete chan[x];
105  }
106 }
107 
109 {
110  delete curDmaDesc;
111  delete [] copyBuffer;
112 }
113 
115 CopyEngine::getMasterPort(const std::string &if_name, PortID idx)
116 {
117  if (if_name != "dma") {
118  // pass it along to our super class
119  return PciDevice::getMasterPort(if_name, idx);
120  } else {
121  if (idx >= static_cast<int>(chan.size())) {
122  panic("CopyEngine::getMasterPort: unknown index %d\n", idx);
123  }
124 
125  return chan[idx]->getMasterPort();
126  }
127 }
128 
129 
132 {
133  return cePort;
134 }
135 
136 void
138 {
139  if (cr.command.start_dma()) {
140  assert(!busy);
141  cr.status.dma_transfer_status(0);
142  nextState = DescriptorFetch;
143  fetchAddress = cr.descChainAddr;
144  if (ce->drainState() == DrainState::Running)
145  fetchDescriptor(cr.descChainAddr);
146  } else if (cr.command.append_dma()) {
147  if (!busy) {
148  nextState = AddressFetch;
149  if (ce->drainState() == DrainState::Running)
150  fetchNextAddr(lastDescriptorAddr);
151  } else
152  refreshNext = true;
153  } else if (cr.command.reset_dma()) {
154  if (busy)
155  underReset = true;
156  else {
157  cr.status.dma_transfer_status(3);
158  nextState = Idle;
159  }
160  } else if (cr.command.resume_dma() || cr.command.abort_dma() ||
161  cr.command.suspend_dma())
162  panic("Resume, Abort, and Suspend are not supported\n");
163  cr.command(0);
164 }
165 
166 Tick
168 {
169  int bar;
170  Addr daddr;
171 
172  if (!getBAR(pkt->getAddr(), bar, daddr))
173  panic("Invalid PCI memory access to unmapped memory.\n");
174 
175  // Only Memory register BAR is allowed
176  assert(bar == 0);
177 
178  int size = pkt->getSize();
179  if (size != sizeof(uint64_t) && size != sizeof(uint32_t) &&
180  size != sizeof(uint16_t) && size != sizeof(uint8_t)) {
181  panic("Unknown size for MMIO access: %d\n", pkt->getSize());
182  }
183 
184  DPRINTF(DMACopyEngine, "Read device register %#X size: %d\n", daddr, size);
185 
189 
190  if (daddr < 0x80) {
191  switch (daddr) {
192  case GEN_CHANCOUNT:
193  assert(size == sizeof(regs.chanCount));
194  pkt->set<uint8_t>(regs.chanCount);
195  break;
196  case GEN_XFERCAP:
197  assert(size == sizeof(regs.xferCap));
198  pkt->set<uint8_t>(regs.xferCap);
199  break;
200  case GEN_INTRCTRL:
201  assert(size == sizeof(uint8_t));
202  pkt->set<uint8_t>(regs.intrctrl());
203  regs.intrctrl.master_int_enable(0);
204  break;
205  case GEN_ATTNSTATUS:
206  assert(size == sizeof(regs.attnStatus));
207  pkt->set<uint32_t>(regs.attnStatus);
208  regs.attnStatus = 0;
209  break;
210  default:
211  panic("Read request to unknown register number: %#x\n", daddr);
212  }
213  pkt->makeAtomicResponse();
214  return pioDelay;
215  }
216 
217 
218  // Find which channel we're accessing
219  int chanid = 0;
220  daddr -= 0x80;
221  while (daddr >= 0x80) {
222  chanid++;
223  daddr -= 0x80;
224  }
225 
226  if (chanid >= regs.chanCount)
227  panic("Access to channel %d (device only configured for %d channels)",
228  chanid, regs.chanCount);
229 
233  chan[chanid]->channelRead(pkt, daddr, size);
234 
235  pkt->makeAtomicResponse();
236  return pioDelay;
237 }
238 
239 void
241 {
242  switch (daddr) {
243  case CHAN_CONTROL:
244  assert(size == sizeof(uint16_t));
245  pkt->set<uint16_t>(cr.ctrl());
246  cr.ctrl.in_use(1);
247  break;
248  case CHAN_STATUS:
249  assert(size == sizeof(uint64_t));
250  pkt->set<uint64_t>(cr.status() | ~busy);
251  break;
252  case CHAN_CHAINADDR:
253  assert(size == sizeof(uint64_t) || size == sizeof(uint32_t));
254  if (size == sizeof(uint64_t))
255  pkt->set<uint64_t>(cr.descChainAddr);
256  else
257  pkt->set<uint32_t>(bits(cr.descChainAddr,0,31));
258  break;
259  case CHAN_CHAINADDR_HIGH:
260  assert(size == sizeof(uint32_t));
261  pkt->set<uint32_t>(bits(cr.descChainAddr,32,63));
262  break;
263  case CHAN_COMMAND:
264  assert(size == sizeof(uint8_t));
265  pkt->set<uint32_t>(cr.command());
266  break;
267  case CHAN_CMPLNADDR:
268  assert(size == sizeof(uint64_t) || size == sizeof(uint32_t));
269  if (size == sizeof(uint64_t))
270  pkt->set<uint64_t>(cr.completionAddr);
271  else
272  pkt->set<uint32_t>(bits(cr.completionAddr,0,31));
273  break;
274  case CHAN_CMPLNADDR_HIGH:
275  assert(size == sizeof(uint32_t));
276  pkt->set<uint32_t>(bits(cr.completionAddr,32,63));
277  break;
278  case CHAN_ERROR:
279  assert(size == sizeof(uint32_t));
280  pkt->set<uint32_t>(cr.error());
281  break;
282  default:
283  panic("Read request to unknown channel register number: (%d)%#x\n",
284  channelId, daddr);
285  }
286 }
287 
288 
289 Tick
291 {
292  int bar;
293  Addr daddr;
294 
295 
296  if (!getBAR(pkt->getAddr(), bar, daddr))
297  panic("Invalid PCI memory access to unmapped memory.\n");
298 
299  // Only Memory register BAR is allowed
300  assert(bar == 0);
301 
302  int size = pkt->getSize();
303 
307 
308  if (size == sizeof(uint64_t)) {
309  uint64_t val M5_VAR_USED = pkt->get<uint64_t>();
310  DPRINTF(DMACopyEngine, "Wrote device register %#X value %#X\n", daddr, val);
311  } else if (size == sizeof(uint32_t)) {
312  uint32_t val M5_VAR_USED = pkt->get<uint32_t>();
313  DPRINTF(DMACopyEngine, "Wrote device register %#X value %#X\n", daddr, val);
314  } else if (size == sizeof(uint16_t)) {
315  uint16_t val M5_VAR_USED = pkt->get<uint16_t>();
316  DPRINTF(DMACopyEngine, "Wrote device register %#X value %#X\n", daddr, val);
317  } else if (size == sizeof(uint8_t)) {
318  uint8_t val M5_VAR_USED = pkt->get<uint8_t>();
319  DPRINTF(DMACopyEngine, "Wrote device register %#X value %#X\n", daddr, val);
320  } else {
321  panic("Unknown size for MMIO access: %d\n", size);
322  }
323 
324  if (daddr < 0x80) {
325  switch (daddr) {
326  case GEN_CHANCOUNT:
327  case GEN_XFERCAP:
328  case GEN_ATTNSTATUS:
329  DPRINTF(DMACopyEngine, "Warning, ignorning write to register %x\n",
330  daddr);
331  break;
332  case GEN_INTRCTRL:
333  regs.intrctrl.master_int_enable(bits(pkt->get<uint8_t>(),0,1));
334  break;
335  default:
336  panic("Read request to unknown register number: %#x\n", daddr);
337  }
338  pkt->makeAtomicResponse();
339  return pioDelay;
340  }
341 
342  // Find which channel we're accessing
343  int chanid = 0;
344  daddr -= 0x80;
345  while (daddr >= 0x80) {
346  chanid++;
347  daddr -= 0x80;
348  }
349 
350  if (chanid >= regs.chanCount)
351  panic("Access to channel %d (device only configured for %d channels)",
352  chanid, regs.chanCount);
353 
357  chan[chanid]->channelWrite(pkt, daddr, size);
358 
359  pkt->makeAtomicResponse();
360  return pioDelay;
361 }
362 
363 void
365 {
366  switch (daddr) {
367  case CHAN_CONTROL:
368  assert(size == sizeof(uint16_t));
369  int old_int_disable;
370  old_int_disable = cr.ctrl.interrupt_disable();
371  cr.ctrl(pkt->get<uint16_t>());
372  if (cr.ctrl.interrupt_disable())
373  cr.ctrl.interrupt_disable(0);
374  else
375  cr.ctrl.interrupt_disable(old_int_disable);
376  break;
377  case CHAN_STATUS:
378  assert(size == sizeof(uint64_t));
379  DPRINTF(DMACopyEngine, "Warning, ignorning write to register %x\n",
380  daddr);
381  break;
382  case CHAN_CHAINADDR:
383  assert(size == sizeof(uint64_t) || size == sizeof(uint32_t));
384  if (size == sizeof(uint64_t))
385  cr.descChainAddr = pkt->get<uint64_t>();
386  else
387  cr.descChainAddr = (uint64_t)pkt->get<uint32_t>() |
388  (cr.descChainAddr & ~mask(32));
389  DPRINTF(DMACopyEngine, "Chain Address %x\n", cr.descChainAddr);
390  break;
391  case CHAN_CHAINADDR_HIGH:
392  assert(size == sizeof(uint32_t));
393  cr.descChainAddr = ((uint64_t)pkt->get<uint32_t>() <<32) |
394  (cr.descChainAddr & mask(32));
395  DPRINTF(DMACopyEngine, "Chain Address %x\n", cr.descChainAddr);
396  break;
397  case CHAN_COMMAND:
398  assert(size == sizeof(uint8_t));
399  cr.command(pkt->get<uint8_t>());
400  recvCommand();
401  break;
402  case CHAN_CMPLNADDR:
403  assert(size == sizeof(uint64_t) || size == sizeof(uint32_t));
404  if (size == sizeof(uint64_t))
405  cr.completionAddr = pkt->get<uint64_t>();
406  else
407  cr.completionAddr = pkt->get<uint32_t>() |
408  (cr.completionAddr & ~mask(32));
409  break;
410  case CHAN_CMPLNADDR_HIGH:
411  assert(size == sizeof(uint32_t));
412  cr.completionAddr = ((uint64_t)pkt->get<uint32_t>() <<32) |
413  (cr.completionAddr & mask(32));
414  break;
415  case CHAN_ERROR:
416  assert(size == sizeof(uint32_t));
417  cr.error(~pkt->get<uint32_t>() & cr.error());
418  break;
419  default:
420  panic("Read request to unknown channel register number: (%d)%#x\n",
421  channelId, daddr);
422  }
423 }
424 
425 void
427 {
429 
430  using namespace Stats;
433  .name(name() + ".bytes_copied")
434  .desc("Number of bytes copied by each engine")
435  .flags(total)
436  ;
439  .name(name() + ".copies_processed")
440  .desc("Number of copies processed by each engine")
441  .flags(total)
442  ;
443 }
444 
445 void
447 {
448  anDq();
449  anBegin("FetchDescriptor");
450  DPRINTF(DMACopyEngine, "Reading descriptor from at memory location %#x(%#x)\n",
451  address, ce->pciToDma(address));
452  assert(address);
453  busy = true;
454 
455  DPRINTF(DMACopyEngine, "dmaAction: %#x, %d bytes, to addr %#x\n",
456  ce->pciToDma(address), sizeof(DmaDesc), curDmaDesc);
457 
458  cePort.dmaAction(MemCmd::ReadReq, ce->pciToDma(address),
459  sizeof(DmaDesc), &fetchCompleteEvent,
460  (uint8_t*)curDmaDesc, latBeforeBegin);
461  lastDescriptorAddr = address;
462 }
463 
464 void
466 {
467  DPRINTF(DMACopyEngine, "Read of descriptor complete\n");
468 
469  if ((curDmaDesc->command & DESC_CTRL_NULL)) {
470  DPRINTF(DMACopyEngine, "Got NULL descriptor, skipping\n");
471  assert(!(curDmaDesc->command & DESC_CTRL_CP_STS));
472  if (curDmaDesc->command & DESC_CTRL_CP_STS) {
473  panic("Shouldn't be able to get here\n");
474  nextState = CompletionWrite;
475  if (inDrain()) return;
476  writeCompletionStatus();
477  } else {
478  anBegin("Idle");
479  anWait();
480  busy = false;
481  nextState = Idle;
482  inDrain();
483  }
484  return;
485  }
486 
487  if (curDmaDesc->command & ~DESC_CTRL_CP_STS)
488  panic("Descriptor has flag other that completion status set\n");
489 
490  nextState = DMARead;
491  if (inDrain()) return;
492  readCopyBytes();
493 }
494 
495 void
497 {
498  anBegin("ReadCopyBytes");
499  DPRINTF(DMACopyEngine, "Reading %d bytes from buffer to memory location %#x(%#x)\n",
500  curDmaDesc->len, curDmaDesc->dest,
501  ce->pciToDma(curDmaDesc->src));
502  cePort.dmaAction(MemCmd::ReadReq, ce->pciToDma(curDmaDesc->src),
503  curDmaDesc->len, &readCompleteEvent, copyBuffer, 0);
504 }
505 
506 void
508 {
509  DPRINTF(DMACopyEngine, "Read of bytes to copy complete\n");
510 
511  nextState = DMAWrite;
512  if (inDrain()) return;
513  writeCopyBytes();
514 }
515 
516 void
518 {
519  anBegin("WriteCopyBytes");
520  DPRINTF(DMACopyEngine, "Writing %d bytes from buffer to memory location %#x(%#x)\n",
521  curDmaDesc->len, curDmaDesc->dest,
522  ce->pciToDma(curDmaDesc->dest));
523 
524  cePort.dmaAction(MemCmd::WriteReq, ce->pciToDma(curDmaDesc->dest),
525  curDmaDesc->len, &writeCompleteEvent, copyBuffer, 0);
526 
527  ce->bytesCopied[channelId] += curDmaDesc->len;
528  ce->copiesProcessed[channelId]++;
529 }
530 
531 void
533 {
534  DPRINTF(DMACopyEngine, "Write of bytes to copy complete user1: %#x\n",
535  curDmaDesc->user1);
536 
537  cr.status.compl_desc_addr(lastDescriptorAddr >> 6);
538  completionDataReg = cr.status() | 1;
539 
540  anQ("DMAUsedDescQ", channelId, 1);
541  anQ("AppRecvQ", curDmaDesc->user1, curDmaDesc->len);
542  if (curDmaDesc->command & DESC_CTRL_CP_STS) {
543  nextState = CompletionWrite;
544  if (inDrain()) return;
545  writeCompletionStatus();
546  return;
547  }
548 
549  continueProcessing();
550 }
551 
552 void
554 {
555  busy = false;
556 
557  if (underReset) {
558  anBegin("Reset");
559  anWait();
560  underReset = false;
561  refreshNext = false;
562  busy = false;
563  nextState = Idle;
564  return;
565  }
566 
567  if (curDmaDesc->next) {
568  nextState = DescriptorFetch;
569  fetchAddress = curDmaDesc->next;
570  if (inDrain()) return;
571  fetchDescriptor(curDmaDesc->next);
572  } else if (refreshNext) {
573  nextState = AddressFetch;
574  refreshNext = false;
575  if (inDrain()) return;
576  fetchNextAddr(lastDescriptorAddr);
577  } else {
578  inDrain();
579  nextState = Idle;
580  anWait();
581  anBegin("Idle");
582  }
583 }
584 
585 void
587 {
588  anBegin("WriteCompletionStatus");
589  DPRINTF(DMACopyEngine, "Writing completion status %#x to address %#x(%#x)\n",
590  completionDataReg, cr.completionAddr,
591  ce->pciToDma(cr.completionAddr));
592 
593  cePort.dmaAction(MemCmd::WriteReq,
594  ce->pciToDma(cr.completionAddr),
595  sizeof(completionDataReg), &statusCompleteEvent,
596  (uint8_t*)&completionDataReg, latAfterCompletion);
597 }
598 
599 void
601 {
602  DPRINTF(DMACopyEngine, "Writing completion status complete\n");
603  continueProcessing();
604 }
605 
606 void
608 {
609  anBegin("FetchNextAddr");
610  DPRINTF(DMACopyEngine, "Fetching next address...\n");
611  busy = true;
612  cePort.dmaAction(MemCmd::ReadReq,
613  ce->pciToDma(address + offsetof(DmaDesc, next)),
614  sizeof(Addr), &addrCompleteEvent,
615  (uint8_t*)curDmaDesc + offsetof(DmaDesc, next), 0);
616 }
617 
618 void
620 {
621  DPRINTF(DMACopyEngine, "Fetching next address complete: %#x\n",
622  curDmaDesc->next);
623  if (!curDmaDesc->next) {
624  DPRINTF(DMACopyEngine, "Got NULL descriptor, nothing more to do\n");
625  busy = false;
626  nextState = Idle;
627  anWait();
628  anBegin("Idle");
629  inDrain();
630  return;
631  }
632  nextState = DescriptorFetch;
633  fetchAddress = curDmaDesc->next;
634  if (inDrain()) return;
635  fetchDescriptor(curDmaDesc->next);
636 }
637 
638 bool
640 {
641  if (drainState() == DrainState::Draining) {
642  DPRINTF(Drain, "CopyEngine done draining, processing drain event\n");
643  signalDrainDone();
644  }
645 
646  return ce->drainState() != DrainState::Running;
647 }
648 
651 {
652  if (nextState == Idle || ce->drainState() != DrainState::Running) {
653  return DrainState::Drained;
654  } else {
655  DPRINTF(Drain, "CopyEngineChannel not drained\n");
656  return DrainState::Draining;
657  }
658 }
659 
660 void
662 {
664  regs.serialize(cp);
665  for (int x =0; x < chan.size(); x++)
666  chan[x]->serializeSection(cp, csprintf("channel%d", x));
667 }
668 
669 void
671 {
673  regs.unserialize(cp);
674  for (int x = 0; x < chan.size(); x++)
675  chan[x]->unserializeSection(cp, csprintf("channel%d", x));
676 }
677 
678 void
680 {
681  SERIALIZE_SCALAR(channelId);
682  SERIALIZE_SCALAR(busy);
683  SERIALIZE_SCALAR(underReset);
684  SERIALIZE_SCALAR(refreshNext);
685  SERIALIZE_SCALAR(lastDescriptorAddr);
686  SERIALIZE_SCALAR(completionDataReg);
687  SERIALIZE_SCALAR(fetchAddress);
688  int nextState = this->nextState;
689  SERIALIZE_SCALAR(nextState);
690  arrayParamOut(cp, "curDmaDesc", (uint8_t*)curDmaDesc, sizeof(DmaDesc));
691  SERIALIZE_ARRAY(copyBuffer, ce->params()->XferCap);
692  cr.serialize(cp);
693 
694 }
695 void
697 {
698  UNSERIALIZE_SCALAR(channelId);
699  UNSERIALIZE_SCALAR(busy);
700  UNSERIALIZE_SCALAR(underReset);
701  UNSERIALIZE_SCALAR(refreshNext);
702  UNSERIALIZE_SCALAR(lastDescriptorAddr);
703  UNSERIALIZE_SCALAR(completionDataReg);
704  UNSERIALIZE_SCALAR(fetchAddress);
705  int nextState;
706  UNSERIALIZE_SCALAR(nextState);
707  this->nextState = (ChannelState)nextState;
708  arrayParamIn(cp, "curDmaDesc", (uint8_t*)curDmaDesc, sizeof(DmaDesc));
709  UNSERIALIZE_ARRAY(copyBuffer, ce->params()->XferCap);
710  cr.unserialize(cp);
711 
712 }
713 
714 void
716 {
717  switch(nextState) {
718  case AddressFetch:
719  fetchNextAddr(lastDescriptorAddr);
720  break;
721  case DescriptorFetch:
722  fetchDescriptor(fetchAddress);
723  break;
724  case DMARead:
725  readCopyBytes();
726  break;
727  case DMAWrite:
728  writeCopyBytes();
729  break;
730  case CompletionWrite:
731  writeCompletionStatus();
732  break;
733  case Idle:
734  break;
735  default:
736  panic("Unknown state for CopyEngineChannel\n");
737  }
738 }
739 
740 void
742 {
743  DPRINTF(DMACopyEngine, "Restarting state machine at state %d\n", nextState);
744  restartStateMachine();
745 }
746 
747 CopyEngine *
748 CopyEngineParams::create()
749 {
750  return new CopyEngine(this);
751 }
#define DPRINTF(x,...)
Definition: trace.hh:212
void set(T v, ByteOrder endian)
Set the value in the data pointer to v using the specified endianness.
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
Definition: device.cc:490
const Params * params() const
Definition: copy_engine.hh:192
const uint32_t CHAN_CHAINADDR_HIGH
const uint32_t CHAN_CHAINADDR
void fetchDescriptor(Addr address)
Definition: copy_engine.cc:446
DrainState
Object drain/handover states.
Definition: drain.hh:71
void unserialize(CheckpointIn &cp) override
Unserialize an object.
#define panic(...)
Definition: misc.hh:153
Running normally.
const uint32_t DESC_CTRL_CP_STS
PCI device, base implementation is only config space.
Definition: device.hh:70
const uint32_t CHAN_CMPLNADDR_HIGH
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
Definition: serialize.cc:585
const uint32_t CHAN_STATUS
void channelWrite(PacketPtr pkt, Addr daddr, int size)
Definition: copy_engine.cc:364
Bitfield< 29, 28 > ce
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: copy_engine.cc:661
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: copy_engine.cc:679
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: copy_engine.cc:696
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Definition: statistics.hh:311
Derived & init(size_type size)
Set this vector to have the given size.
Definition: statistics.hh:1118
T get(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness.
Bitfield< 63 > val
Definition: misc.hh:770
BaseMasterPort & getMasterPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a master port with a given name and index.
Definition: copy_engine.cc:115
const uint32_t GEN_XFERCAP
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:145
Stats::Vector copiesProcessed
Definition: copy_engine.hh:181
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161
void serialize(CheckpointOut &cp) const override
Serialize an object.
void makeAtomicResponse()
Definition: packet.hh:857
DmaDeviceParams Params
Definition: dma_device.hh:160
uint64_t Tick
Tick count type.
Definition: types.hh:63
const uint32_t CHAN_CONTROL
CopyEngineReg::Regs regs
Definition: copy_engine.hh:184
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
Definition: serialize.cc:578
#define fatal(...)
Definition: misc.hh:163
#define SERIALIZE_ARRAY(member, size)
Definition: serialize.hh:158
void channelRead(PacketPtr pkt, Addr daddr, int size)
Definition: copy_engine.cc:240
int getBAR(Addr addr)
Which base address register (if any) maps the given address?
Definition: device.hh:134
Tick pioDelay
Definition: device.hh:185
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: copy_engine.cc:167
void arrayParamOut(CheckpointOut &cp, const std::string &name, const CircleBuf< T > &param)
Definition: circlebuf.hh:251
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: copy_engine.cc:290
BaseMasterPort & getMasterPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a master port with a given name and index.
Definition: dma_device.cc:263
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
std::vector< CopyEngineChannel * > chan
Definition: copy_engine.hh:187
Draining buffers pending serialization/handover.
CopyEngineReg::ChanRegs cr
Definition: copy_engine.hh:68
const uint32_t DESC_CTRL_NULL
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:245
CopyEngineReg::DmaDesc * curDmaDesc
Definition: copy_engine.hh:70
void regStats() override
Register statistics for this object.
Definition: copy_engine.cc:426
const FlagsType total
Print the total.
Definition: info.hh:49
const uint32_t CHAN_COMMAND
CopyEngineChannel(CopyEngine *_ce, int cid)
Definition: copy_engine.cc:81
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:143
const uint32_t GEN_ATTNSTATUS
void drainResume() override
Resume execution after a successful drain.
Definition: copy_engine.cc:741
#define UNSERIALIZE_ARRAY(member, size)
Definition: serialize.hh:161
static const int NumArgumentRegs M5_VAR_USED
Definition: process.cc:83
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
Definition: statistics.hh:254
int size()
Definition: pagetable.hh:146
virtual const std::string name() const
Definition: sim_object.hh:117
Declaration of the Packet class.
std::ostream CheckpointOut
Definition: serialize.hh:67
const uint32_t GEN_CHANCOUNT
A BaseMasterPort is a protocol-agnostic master port, responsible only for the structural connection t...
Definition: port.hh:115
BaseMasterPort & getMasterPort()
Definition: copy_engine.cc:131
void signalDrainDone() const
Signal that an object is drained.
Definition: drain.hh:267
Stats::Vector bytesCopied
Definition: copy_engine.hh:180
const uint32_t CHAN_ERROR
int findMsbSet(uint64_t val)
Returns the bit position of the MSB that is set in the input.
Definition: bitfield.hh:163
const uint32_t GEN_INTRCTRL
DrainState drainState() const
Return the current drain state of an object.
Definition: drain.hh:282
void arrayParamIn(CheckpointIn &cp, const std::string &name, CircleBuf< T > &param)
Definition: circlebuf.hh:261
Bitfield< 3, 0 > mask
Definition: types.hh:64
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
Definition: statistics.hh:287
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:181
unsigned getSize() const
Definition: packet.hh:649
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...
Definition: bitfield.hh:67
CopyEngine(const Params *params)
Definition: copy_engine.cc:63
Bitfield< 0 > p
const uint32_t CHAN_CMPLNADDR
Bitfield< 1 > x
Definition: types.hh:105
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: copy_engine.cc:670
void regStats() override
Register statistics for this object.
DrainState drain() override
Notify an object that it needs to drain its state.
Definition: copy_engine.cc:650
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
Definition: device.cc:425
void fetchNextAddr(Addr address)
Definition: copy_engine.cc:607
Addr getAddr() const
Definition: packet.hh:639

Generated on Fri Jun 9 2017 13:03:46 for gem5 by doxygen 1.8.6