gem5 v24.0.0.0
Loading...
Searching...
No Matches
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
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
59namespace gem5
60{
61
62using 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
118Port &
119CopyEngine::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
134Port &
136{
137 return cePort;
138}
139
140void
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
170Tick
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
243void
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;
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;
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
293Tick
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
371void
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;
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;
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
452void
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
469void
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
498void
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
508void
510{
511 DPRINTF(DMACopyEngine, "Read of bytes to copy complete\n");
512
513 nextState = DMAWrite;
514 if (inDrain()) return;
515 writeCopyBytes();
516}
517
518void
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
532void
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
551void
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
580void
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
593void
595{
596 DPRINTF(DMACopyEngine, "Writing completion status complete\n");
597 continueProcessing();
598}
599
600void
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
611void
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
629bool
631{
633 DPRINTF(Drain, "CopyEngine done draining, processing drain event\n");
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");
648 }
649}
650
651void
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
660void
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
669void
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}
686void
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
705void
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
731void
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:210
void unserialize(CheckpointIn &cp) override
Unserialize an object.
CopyEngineChannel(CopyEngine *_ce, int cid)
void channelWrite(PacketPtr pkt, Addr daddr, int size)
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
void serialize(CheckpointOut &cp) const override
Serialize an object.
void drainResume() override
Resume execution after a successful drain.
void channelRead(PacketPtr pkt, Addr daddr, int size)
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void serialize(CheckpointOut &cp) const override
Serialize an object.
std::vector< CopyEngineChannel * > chan
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
CopyEngine(const Params &params)
copy_engine_reg::Regs regs
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
DmaDeviceParams Params
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
Addr getAddr() const
Definition packet.hh:807
void setLE(T v)
Set the value in the data pointer to v as little endian.
unsigned getSize() const
Definition packet.hh:817
void makeAtomicResponse()
Definition packet.hh:1074
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.
Statistics container.
Definition group.hh:93
Derived & init(size_type size)
Set this vector to have the given size.
#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:279
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:79
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:188
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:200
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
Definition serialize.cc:74
#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< 3, 0 > mask
Definition pcstate.hh:63
Bitfield< 29, 28 > ce
Bitfield< 0 > p
Bitfield< 3 > x
Definition pagetable.hh:73
Bitfield< 63 > val
Definition misc.hh:804
const uint32_t DESC_CTRL_NULL
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_COMMAND
const FlagsType total
Print the total.
Definition info.hh:59
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
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
void arrayParamOut(CheckpointOut &cp, const std::string &name, const CircleBuf< T > &param)
Definition circlebuf.hh:247
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
CopyEngineStats(statistics::Group *parent, const uint8_t &channel_count)
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void serialize(CheckpointOut &cp) const override
Serialize an object.
const std::string & name()
Definition trace.cc:48

Generated on Tue Jun 18 2024 16:24:03 for gem5 by doxygen 1.11.0