gem5  v22.1.0.0
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 
41 /* @file
42  * Device model for Intel's I/O AT DMA copy engine.
43  */
44 
45 #include "dev/pci/copy_engine.hh"
46 
47 #include <algorithm>
48 
49 #include "base/compiler.hh"
50 #include "base/trace.hh"
51 #include "debug/DMACopyEngine.hh"
52 #include "debug/Drain.hh"
53 #include "mem/packet.hh"
54 #include "mem/packet_access.hh"
55 #include "params/CopyEngine.hh"
56 #include "sim/stats.hh"
57 #include "sim/system.hh"
58 
59 namespace gem5
60 {
61 
62 using namespace copy_engine_reg;
63 
65  : PciDevice(p),
66  copyEngineStats(this, p.ChanCnt)
67 {
68  // All Reg regs are initialized to 0 by default
69  regs.chanCount = p.ChanCnt;
70  regs.xferCap = findMsbSet(p.XferCap);
71  regs.attnStatus = 0;
72 
73  if (regs.chanCount > 64)
74  fatal("CopyEngine interface doesn't support more than 64 DMA engines\n");
75 
76  for (int x = 0; x < regs.chanCount; x++) {
77  CopyEngineChannel *ch = new CopyEngineChannel(this, x);
78  chan.push_back(ch);
79  }
80 }
81 
82 
84  : cePort(_ce, _ce->sys),
85  ce(_ce), channelId(cid), busy(false), underReset(false),
86  refreshNext(false), latBeforeBegin(ce->params().latBeforeBegin),
87  latAfterCompletion(ce->params().latAfterCompletion),
88  completionDataReg(0), nextState(Idle),
89  fetchCompleteEvent([this]{ fetchDescComplete(); }, name()),
90  addrCompleteEvent([this]{ fetchAddrComplete(); }, name()),
91  readCompleteEvent([this]{ readCopyBytesComplete(); }, name()),
92  writeCompleteEvent([this]{ writeCopyBytesComplete(); }, name()),
93  statusCompleteEvent([this]{ writeStatusComplete(); }, name())
94 
95 {
96  cr.status.dma_transfer_status(3);
97  cr.descChainAddr = 0;
98  cr.completionAddr = 0;
99 
100  curDmaDesc = new DmaDesc;
101  memset(curDmaDesc, 0, sizeof(DmaDesc));
102  copyBuffer = new uint8_t[ce->params().XferCap];
103 }
104 
106 {
107  for (int x = 0; x < chan.size(); x++) {
108  delete chan[x];
109  }
110 }
111 
113 {
114  delete curDmaDesc;
115  delete [] copyBuffer;
116 }
117 
118 Port &
119 CopyEngine::getPort(const std::string &if_name, PortID idx)
120 {
121  if (if_name != "dma") {
122  // pass it along to our super class
123  return PciDevice::getPort(if_name, idx);
124  } else {
125  if (idx >= static_cast<int>(chan.size())) {
126  panic("CopyEngine::getPort: unknown index %d\n", idx);
127  }
128 
129  return chan[idx]->getPort();
130  }
131 }
132 
133 
134 Port &
136 {
137  return cePort;
138 }
139 
140 void
142 {
143  if (cr.command.start_dma()) {
144  assert(!busy);
145  cr.status.dma_transfer_status(0);
146  nextState = DescriptorFetch;
147  fetchAddress = cr.descChainAddr;
148  if (ce->drainState() == DrainState::Running)
149  fetchDescriptor(cr.descChainAddr);
150  } else if (cr.command.append_dma()) {
151  if (!busy) {
152  nextState = AddressFetch;
153  if (ce->drainState() == DrainState::Running)
154  fetchNextAddr(lastDescriptorAddr);
155  } else
156  refreshNext = true;
157  } else if (cr.command.reset_dma()) {
158  if (busy)
159  underReset = true;
160  else {
161  cr.status.dma_transfer_status(3);
162  nextState = Idle;
163  }
164  } else if (cr.command.resume_dma() || cr.command.abort_dma() ||
165  cr.command.suspend_dma())
166  panic("Resume, Abort, and Suspend are not supported\n");
167  cr.command(0);
168 }
169 
170 Tick
172 {
173  int bar;
174  Addr daddr;
175 
176  if (!getBAR(pkt->getAddr(), bar, daddr))
177  panic("Invalid PCI memory access to unmapped memory.\n");
178 
179  // Only Memory register BAR is allowed
180  assert(bar == 0);
181 
182  int size = pkt->getSize();
183  if (size != sizeof(uint64_t) && size != sizeof(uint32_t) &&
184  size != sizeof(uint16_t) && size != sizeof(uint8_t)) {
185  panic("Unknown size for MMIO access: %d\n", pkt->getSize());
186  }
187 
188  DPRINTF(DMACopyEngine, "Read device register %#X size: %d\n", daddr, size);
189 
193 
194  if (daddr < 0x80) {
195  switch (daddr) {
196  case GEN_CHANCOUNT:
197  assert(size == sizeof(regs.chanCount));
198  pkt->setLE<uint8_t>(regs.chanCount);
199  break;
200  case GEN_XFERCAP:
201  assert(size == sizeof(regs.xferCap));
202  pkt->setLE<uint8_t>(regs.xferCap);
203  break;
204  case GEN_INTRCTRL:
205  assert(size == sizeof(uint8_t));
206  pkt->setLE<uint8_t>(regs.intrctrl());
207  regs.intrctrl.master_int_enable(0);
208  break;
209  case GEN_ATTNSTATUS:
210  assert(size == sizeof(regs.attnStatus));
211  pkt->setLE<uint32_t>(regs.attnStatus);
212  regs.attnStatus = 0;
213  break;
214  default:
215  panic("Read request to unknown register number: %#x\n", daddr);
216  }
217  pkt->makeAtomicResponse();
218  return pioDelay;
219  }
220 
221 
222  // Find which channel we're accessing
223  int chanid = 0;
224  daddr -= 0x80;
225  while (daddr >= 0x80) {
226  chanid++;
227  daddr -= 0x80;
228  }
229 
230  if (chanid >= regs.chanCount)
231  panic("Access to channel %d (device only configured for %d channels)",
232  chanid, regs.chanCount);
233 
237  chan[chanid]->channelRead(pkt, daddr, size);
238 
239  pkt->makeAtomicResponse();
240  return pioDelay;
241 }
242 
243 void
245 {
246  switch (daddr) {
247  case CHAN_CONTROL:
248  assert(size == sizeof(uint16_t));
249  pkt->setLE<uint16_t>(cr.ctrl());
250  cr.ctrl.in_use(1);
251  break;
252  case CHAN_STATUS:
253  assert(size == sizeof(uint64_t));
254  pkt->setLE<uint64_t>(cr.status() | (busy ? 0 : 1));
255  break;
256  case CHAN_CHAINADDR:
257  assert(size == sizeof(uint64_t) || size == sizeof(uint32_t));
258  if (size == sizeof(uint64_t))
259  pkt->setLE<uint64_t>(cr.descChainAddr);
260  else
261  pkt->setLE<uint32_t>(bits(cr.descChainAddr,0,31));
262  break;
263  case CHAN_CHAINADDR_HIGH:
264  assert(size == sizeof(uint32_t));
265  pkt->setLE<uint32_t>(bits(cr.descChainAddr,32,63));
266  break;
267  case CHAN_COMMAND:
268  assert(size == sizeof(uint8_t));
269  pkt->setLE<uint32_t>(cr.command());
270  break;
271  case CHAN_CMPLNADDR:
272  assert(size == sizeof(uint64_t) || size == sizeof(uint32_t));
273  if (size == sizeof(uint64_t))
274  pkt->setLE<uint64_t>(cr.completionAddr);
275  else
276  pkt->setLE<uint32_t>(bits(cr.completionAddr,0,31));
277  break;
278  case CHAN_CMPLNADDR_HIGH:
279  assert(size == sizeof(uint32_t));
280  pkt->setLE<uint32_t>(bits(cr.completionAddr,32,63));
281  break;
282  case CHAN_ERROR:
283  assert(size == sizeof(uint32_t));
284  pkt->setLE<uint32_t>(cr.error());
285  break;
286  default:
287  panic("Read request to unknown channel register number: (%d)%#x\n",
288  channelId, daddr);
289  }
290 }
291 
292 
293 Tick
295 {
296  int bar;
297  Addr daddr;
298 
299 
300  if (!getBAR(pkt->getAddr(), bar, daddr))
301  panic("Invalid PCI memory access to unmapped memory.\n");
302 
303  // Only Memory register BAR is allowed
304  assert(bar == 0);
305 
306  int size = pkt->getSize();
307 
311 
312  if (size == sizeof(uint64_t)) {
313  [[maybe_unused]] uint64_t val = pkt->getLE<uint64_t>();
314  DPRINTF(DMACopyEngine, "Wrote device register %#X value %#X\n",
315  daddr, val);
316  } else if (size == sizeof(uint32_t)) {
317  [[maybe_unused]] uint32_t val = pkt->getLE<uint32_t>();
318  DPRINTF(DMACopyEngine, "Wrote device register %#X value %#X\n",
319  daddr, val);
320  } else if (size == sizeof(uint16_t)) {
321  [[maybe_unused]] uint16_t val = pkt->getLE<uint16_t>();
322  DPRINTF(DMACopyEngine, "Wrote device register %#X value %#X\n",
323  daddr, val);
324  } else if (size == sizeof(uint8_t)) {
325  [[maybe_unused]] uint8_t val = pkt->getLE<uint8_t>();
326  DPRINTF(DMACopyEngine, "Wrote device register %#X value %#X\n",
327  daddr, val);
328  } else {
329  panic("Unknown size for MMIO access: %d\n", size);
330  }
331 
332  if (daddr < 0x80) {
333  switch (daddr) {
334  case GEN_CHANCOUNT:
335  case GEN_XFERCAP:
336  case GEN_ATTNSTATUS:
337  DPRINTF(DMACopyEngine, "Warning, ignorning write to register %x\n",
338  daddr);
339  break;
340  case GEN_INTRCTRL:
341  regs.intrctrl.master_int_enable(bits(pkt->getLE<uint8_t>(), 0, 1));
342  break;
343  default:
344  panic("Read request to unknown register number: %#x\n", daddr);
345  }
346  pkt->makeAtomicResponse();
347  return pioDelay;
348  }
349 
350  // Find which channel we're accessing
351  int chanid = 0;
352  daddr -= 0x80;
353  while (daddr >= 0x80) {
354  chanid++;
355  daddr -= 0x80;
356  }
357 
358  if (chanid >= regs.chanCount)
359  panic("Access to channel %d (device only configured for %d channels)",
360  chanid, regs.chanCount);
361 
365  chan[chanid]->channelWrite(pkt, daddr, size);
366 
367  pkt->makeAtomicResponse();
368  return pioDelay;
369 }
370 
371 void
373 {
374  switch (daddr) {
375  case CHAN_CONTROL:
376  assert(size == sizeof(uint16_t));
377  int old_int_disable;
378  old_int_disable = cr.ctrl.interrupt_disable();
379  cr.ctrl(pkt->getLE<uint16_t>());
380  if (cr.ctrl.interrupt_disable())
381  cr.ctrl.interrupt_disable(0);
382  else
383  cr.ctrl.interrupt_disable(old_int_disable);
384  break;
385  case CHAN_STATUS:
386  assert(size == sizeof(uint64_t));
387  DPRINTF(DMACopyEngine, "Warning, ignorning write to register %x\n",
388  daddr);
389  break;
390  case CHAN_CHAINADDR:
391  assert(size == sizeof(uint64_t) || size == sizeof(uint32_t));
392  if (size == sizeof(uint64_t))
393  cr.descChainAddr = pkt->getLE<uint64_t>();
394  else
395  cr.descChainAddr = (uint64_t)pkt->getLE<uint32_t>() |
396  (cr.descChainAddr & ~mask(32));
397  DPRINTF(DMACopyEngine, "Chain Address %x\n", cr.descChainAddr);
398  break;
399  case CHAN_CHAINADDR_HIGH:
400  assert(size == sizeof(uint32_t));
401  cr.descChainAddr = ((uint64_t)pkt->getLE<uint32_t>() << 32) |
402  (cr.descChainAddr & mask(32));
403  DPRINTF(DMACopyEngine, "Chain Address %x\n", cr.descChainAddr);
404  break;
405  case CHAN_COMMAND:
406  assert(size == sizeof(uint8_t));
407  cr.command(pkt->getLE<uint8_t>());
408  recvCommand();
409  break;
410  case CHAN_CMPLNADDR:
411  assert(size == sizeof(uint64_t) || size == sizeof(uint32_t));
412  if (size == sizeof(uint64_t))
413  cr.completionAddr = pkt->getLE<uint64_t>();
414  else
415  cr.completionAddr = pkt->getLE<uint32_t>() |
416  (cr.completionAddr & ~mask(32));
417  break;
418  case CHAN_CMPLNADDR_HIGH:
419  assert(size == sizeof(uint32_t));
420  cr.completionAddr = ((uint64_t)pkt->getLE<uint32_t>() <<32) |
421  (cr.completionAddr & mask(32));
422  break;
423  case CHAN_ERROR:
424  assert(size == sizeof(uint32_t));
425  cr.error(~pkt->getLE<uint32_t>() & cr.error());
426  break;
427  default:
428  panic("Read request to unknown channel register number: (%d)%#x\n",
429  channelId, daddr);
430  }
431 }
432 
435  const uint8_t &channel_count)
436  : statistics::Group(parent, "CopyEngine"),
437  ADD_STAT(bytesCopied, statistics::units::Byte::get(),
438  "Number of bytes copied by each engine"),
439  ADD_STAT(copiesProcessed, statistics::units::Count::get(),
440  "Number of copies processed by each engine")
441 {
443  .init(channel_count)
445  ;
447  .init(channel_count)
449  ;
450 }
451 
452 void
454 {
455  DPRINTF(DMACopyEngine, "Reading descriptor from at memory location %#x(%#x)\n",
456  address, ce->pciToDma(address));
457  assert(address);
458  busy = true;
459 
460  DPRINTF(DMACopyEngine, "dmaAction: %#x, %d bytes, to addr %#x\n",
461  ce->pciToDma(address), sizeof(DmaDesc), curDmaDesc);
462 
463  cePort.dmaAction(MemCmd::ReadReq, ce->pciToDma(address),
464  sizeof(DmaDesc), &fetchCompleteEvent,
465  (uint8_t*)curDmaDesc, latBeforeBegin);
466  lastDescriptorAddr = address;
467 }
468 
469 void
471 {
472  DPRINTF(DMACopyEngine, "Read of descriptor complete\n");
473 
474  if ((curDmaDesc->command & DESC_CTRL_NULL)) {
475  DPRINTF(DMACopyEngine, "Got NULL descriptor, skipping\n");
476  assert(!(curDmaDesc->command & DESC_CTRL_CP_STS));
477  if (curDmaDesc->command & DESC_CTRL_CP_STS) {
478  panic("Shouldn't be able to get here\n");
479  nextState = CompletionWrite;
480  if (inDrain()) return;
481  writeCompletionStatus();
482  } else {
483  busy = false;
484  nextState = Idle;
485  inDrain();
486  }
487  return;
488  }
489 
490  if (curDmaDesc->command & ~DESC_CTRL_CP_STS)
491  panic("Descriptor has flag other that completion status set\n");
492 
493  nextState = DMARead;
494  if (inDrain()) return;
495  readCopyBytes();
496 }
497 
498 void
500 {
501  DPRINTF(DMACopyEngine, "Reading %d bytes from buffer to memory location %#x(%#x)\n",
502  curDmaDesc->len, curDmaDesc->dest,
503  ce->pciToDma(curDmaDesc->src));
504  cePort.dmaAction(MemCmd::ReadReq, ce->pciToDma(curDmaDesc->src),
505  curDmaDesc->len, &readCompleteEvent, copyBuffer, 0);
506 }
507 
508 void
510 {
511  DPRINTF(DMACopyEngine, "Read of bytes to copy complete\n");
512 
513  nextState = DMAWrite;
514  if (inDrain()) return;
515  writeCopyBytes();
516 }
517 
518 void
520 {
521  DPRINTF(DMACopyEngine, "Writing %d bytes from buffer to memory location %#x(%#x)\n",
522  curDmaDesc->len, curDmaDesc->dest,
523  ce->pciToDma(curDmaDesc->dest));
524 
525  cePort.dmaAction(MemCmd::WriteReq, ce->pciToDma(curDmaDesc->dest),
526  curDmaDesc->len, &writeCompleteEvent, copyBuffer, 0);
527 
528  ce->copyEngineStats.bytesCopied[channelId] += curDmaDesc->len;
529  ce->copyEngineStats.copiesProcessed[channelId]++;
530 }
531 
532 void
534 {
535  DPRINTF(DMACopyEngine, "Write of bytes to copy complete user1: %#x\n",
536  curDmaDesc->user1);
537 
538  cr.status.compl_desc_addr(lastDescriptorAddr >> 6);
539  completionDataReg = cr.status() | 1;
540 
541  if (curDmaDesc->command & DESC_CTRL_CP_STS) {
542  nextState = CompletionWrite;
543  if (inDrain()) return;
544  writeCompletionStatus();
545  return;
546  }
547 
548  continueProcessing();
549 }
550 
551 void
553 {
554  busy = false;
555 
556  if (underReset) {
557  underReset = false;
558  refreshNext = false;
559  busy = false;
560  nextState = Idle;
561  return;
562  }
563 
564  if (curDmaDesc->next) {
565  nextState = DescriptorFetch;
566  fetchAddress = curDmaDesc->next;
567  if (inDrain()) return;
568  fetchDescriptor(curDmaDesc->next);
569  } else if (refreshNext) {
570  nextState = AddressFetch;
571  refreshNext = false;
572  if (inDrain()) return;
573  fetchNextAddr(lastDescriptorAddr);
574  } else {
575  inDrain();
576  nextState = Idle;
577  }
578 }
579 
580 void
582 {
583  DPRINTF(DMACopyEngine, "Writing completion status %#x to address %#x(%#x)\n",
584  completionDataReg, cr.completionAddr,
585  ce->pciToDma(cr.completionAddr));
586 
587  cePort.dmaAction(MemCmd::WriteReq,
588  ce->pciToDma(cr.completionAddr),
589  sizeof(completionDataReg), &statusCompleteEvent,
590  (uint8_t*)&completionDataReg, latAfterCompletion);
591 }
592 
593 void
595 {
596  DPRINTF(DMACopyEngine, "Writing completion status complete\n");
597  continueProcessing();
598 }
599 
600 void
602 {
603  DPRINTF(DMACopyEngine, "Fetching next address...\n");
604  busy = true;
605  cePort.dmaAction(MemCmd::ReadReq,
606  ce->pciToDma(address + offsetof(DmaDesc, next)),
607  sizeof(Addr), &addrCompleteEvent,
608  (uint8_t*)curDmaDesc + offsetof(DmaDesc, next), 0);
609 }
610 
611 void
613 {
614  DPRINTF(DMACopyEngine, "Fetching next address complete: %#x\n",
615  curDmaDesc->next);
616  if (!curDmaDesc->next) {
617  DPRINTF(DMACopyEngine, "Got NULL descriptor, nothing more to do\n");
618  busy = false;
619  nextState = Idle;
620  inDrain();
621  return;
622  }
623  nextState = DescriptorFetch;
624  fetchAddress = curDmaDesc->next;
625  if (inDrain()) return;
626  fetchDescriptor(curDmaDesc->next);
627 }
628 
629 bool
631 {
632  if (drainState() == DrainState::Draining) {
633  DPRINTF(Drain, "CopyEngine done draining, processing drain event\n");
634  signalDrainDone();
635  }
636 
637  return ce->drainState() != DrainState::Running;
638 }
639 
642 {
643  if (nextState == Idle || ce->drainState() != DrainState::Running) {
644  return DrainState::Drained;
645  } else {
646  DPRINTF(Drain, "CopyEngineChannel not drained\n");
647  return DrainState::Draining;
648  }
649 }
650 
651 void
653 {
655  regs.serialize(cp);
656  for (int x =0; x < chan.size(); x++)
657  chan[x]->serializeSection(cp, csprintf("channel%d", x));
658 }
659 
660 void
662 {
664  regs.unserialize(cp);
665  for (int x = 0; x < chan.size(); x++)
666  chan[x]->unserializeSection(cp, csprintf("channel%d", x));
667 }
668 
669 void
671 {
672  SERIALIZE_SCALAR(channelId);
673  SERIALIZE_SCALAR(busy);
674  SERIALIZE_SCALAR(underReset);
675  SERIALIZE_SCALAR(refreshNext);
676  SERIALIZE_SCALAR(lastDescriptorAddr);
677  SERIALIZE_SCALAR(completionDataReg);
678  SERIALIZE_SCALAR(fetchAddress);
679  int nextState = this->nextState;
680  SERIALIZE_SCALAR(nextState);
681  arrayParamOut(cp, "curDmaDesc", (uint8_t*)curDmaDesc, sizeof(DmaDesc));
682  SERIALIZE_ARRAY(copyBuffer, ce->params().XferCap);
683  cr.serialize(cp);
684 
685 }
686 void
688 {
689  UNSERIALIZE_SCALAR(channelId);
690  UNSERIALIZE_SCALAR(busy);
691  UNSERIALIZE_SCALAR(underReset);
692  UNSERIALIZE_SCALAR(refreshNext);
693  UNSERIALIZE_SCALAR(lastDescriptorAddr);
694  UNSERIALIZE_SCALAR(completionDataReg);
695  UNSERIALIZE_SCALAR(fetchAddress);
696  int nextState;
697  UNSERIALIZE_SCALAR(nextState);
698  this->nextState = (ChannelState)nextState;
699  arrayParamIn(cp, "curDmaDesc", (uint8_t*)curDmaDesc, sizeof(DmaDesc));
700  UNSERIALIZE_ARRAY(copyBuffer, ce->params().XferCap);
701  cr.unserialize(cp);
702 
703 }
704 
705 void
707 {
708  switch(nextState) {
709  case AddressFetch:
710  fetchNextAddr(lastDescriptorAddr);
711  break;
712  case DescriptorFetch:
713  fetchDescriptor(fetchAddress);
714  break;
715  case DMARead:
716  readCopyBytes();
717  break;
718  case DMAWrite:
719  writeCopyBytes();
720  break;
721  case CompletionWrite:
722  writeCompletionStatus();
723  break;
724  case Idle:
725  break;
726  default:
727  panic("Unknown state for CopyEngineChannel\n");
728  }
729 }
730 
731 void
733 {
734  DPRINTF(DMACopyEngine, "Restarting state machine at state %d\n", nextState);
735  restartStateMachine();
736 }
737 
738 } // namespace gem5
#define DPRINTF(x,...)
Definition: trace.hh:186
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: copy_engine.cc:687
CopyEngineChannel(CopyEngine *_ce, int cid)
Definition: copy_engine.cc:83
void channelWrite(PacketPtr pkt, Addr daddr, int size)
Definition: copy_engine.cc:372
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
Definition: copy_engine.cc:641
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: copy_engine.cc:670
void drainResume() override
Resume execution after a successful drain.
Definition: copy_engine.cc:732
void channelRead(PacketPtr pkt, Addr daddr, int size)
Definition: copy_engine.cc:244
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: copy_engine.cc:294
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: copy_engine.cc:171
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: copy_engine.cc:661
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: copy_engine.cc:652
std::vector< CopyEngineChannel * > chan
Definition: copy_engine.hh:165
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
Definition: copy_engine.cc:119
CopyEngine(const Params &params)
Definition: copy_engine.cc:64
copy_engine_reg::Regs regs
Definition: copy_engine.hh:162
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
Definition: dma_device.cc:363
DmaDeviceParams Params
Definition: dma_device.hh:209
virtual std::string name() const
Definition: named.hh:47
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:294
Addr getAddr() const
Definition: packet.hh:805
void setLE(T v)
Set the value in the data pointer to v as little endian.
unsigned getSize() const
Definition: packet.hh:815
void makeAtomicResponse()
Definition: packet.hh:1071
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
PCI device, base implementation is only config space.
Definition: device.hh:270
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
Definition: device.cc:464
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
Definition: device.cc:401
bool getBAR(Addr addr, int &num, Addr &offs)
Which base address register (if any) maps the given address?
Definition: device.hh:320
Ports are used to interface objects to each other.
Definition: port.hh:62
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Definition: statistics.hh:358
Statistics container.
Definition: group.hh:94
Derived & init(size_type size)
Set this vector to have the given size.
Definition: statistics.hh:1040
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:75
constexpr int findMsbSet(uint64_t val)
Returns the bit position of the MSB that is set in the input.
Definition: bitfield.hh:260
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition: bitfield.hh:76
constexpr uint64_t mask(unsigned nbits)
Generate a 64-bit mask of 'nbits' 1s, right justified.
Definition: bitfield.hh:63
void signalDrainDone() const
Signal that an object is drained.
Definition: drain.hh:305
DrainState drainState() const
Return the current drain state of an object.
Definition: drain.hh:324
DrainState
Object drain/handover states.
Definition: drain.hh:75
@ Draining
Draining buffers pending serialization/handover.
@ Running
Running normally.
@ Drained
Buffers drained, ready for serialization/handover.
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:190
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
Definition: serialize.cc:74
decltype(std::begin(std::declval< const T & >()), std::end(std::declval< const T & >()), void()) arrayParamOut(CheckpointOut &os, const std::string &name, const T &param)
Definition: serialize.hh:409
#define UNSERIALIZE_ARRAY(member, size)
Definition: serialize.hh:618
#define SERIALIZE_ARRAY(member, size)
Definition: serialize.hh:610
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
Definition: serialize.cc:81
Bitfield< 29, 28 > ce
Bitfield< 4 > x
Definition: pagetable.hh:61
Bitfield< 54 > p
Definition: pagetable.hh:70
static RegIndex cr(int index)
Definition: misc.hh:421
Bitfield< 63 > val
Definition: misc.hh:776
const uint32_t GEN_XFERCAP
const uint32_t DESC_CTRL_NULL
const uint32_t CHAN_STATUS
const uint32_t DESC_CTRL_CP_STS
const uint32_t GEN_ATTNSTATUS
const uint32_t GEN_CHANCOUNT
const uint32_t CHAN_CMPLNADDR_HIGH
const uint32_t CHAN_CONTROL
const uint32_t CHAN_CMPLNADDR
const uint32_t CHAN_CHAINADDR
const uint32_t CHAN_CHAINADDR_HIGH
const uint32_t GEN_INTRCTRL
const uint32_t CHAN_ERROR
const uint32_t CHAN_COMMAND
const FlagsType total
Print the total.
Definition: info.hh:60
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::ostream CheckpointOut
Definition: serialize.hh:66
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:245
uint64_t Tick
Tick count type.
Definition: types.hh:58
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161
void arrayParamIn(CheckpointIn &cp, const std::string &name, CircleBuf< T > &param)
Definition: circlebuf.hh:257
Declaration of the Packet class.
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:568
statistics::Vector copiesProcessed
Definition: copy_engine.hh:158
CopyEngineStats(statistics::Group *parent, const uint8_t &channel_count)
Definition: copy_engine.cc:434
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void serialize(CheckpointOut &cp) const override
Serialize an object.

Generated on Wed Dec 21 2022 10:22:34 for gem5 by doxygen 1.9.1