50 #include "debug/DMACopyEngine.hh"
51 #include "debug/Drain.hh"
54 #include "params/CopyEngine.hh"
62 copyEngineStats(this,
p.ChanCnt)
70 fatal(
"CopyEngine interface doesn't support more than 64 DMA engines\n");
80 : cePort(_ce, _ce->sys),
81 ce(_ce), channelId(cid), busy(false), underReset(false),
82 refreshNext(false), latBeforeBegin(
ce->params().latBeforeBegin),
83 latAfterCompletion(
ce->params().latAfterCompletion),
84 completionDataReg(0), nextState(Idle),
86 addrCompleteEvent([
this]{ fetchAddrComplete(); },
name()),
87 readCompleteEvent([
this]{ readCopyBytesComplete(); },
name()),
88 writeCompleteEvent([
this]{ writeCopyBytesComplete(); },
name()),
89 statusCompleteEvent([
this]{ writeStatusComplete(); },
name())
92 cr.status.dma_transfer_status(3);
94 cr.completionAddr = 0;
97 memset(curDmaDesc, 0,
sizeof(
DmaDesc));
98 copyBuffer =
new uint8_t[
ce->params().XferCap];
103 for (
int x = 0;
x <
chan.size();
x++) {
111 delete [] copyBuffer;
117 if (if_name !=
"dma") {
121 if (idx >=
static_cast<int>(
chan.size())) {
122 panic(
"CopyEngine::getPort: unknown index %d\n", idx);
125 return chan[idx]->getPort();
139 if (cr.command.start_dma()) {
141 cr.status.dma_transfer_status(0);
142 nextState = DescriptorFetch;
143 fetchAddress = cr.descChainAddr;
145 fetchDescriptor(cr.descChainAddr);
146 }
else if (cr.command.append_dma()) {
148 nextState = AddressFetch;
150 fetchNextAddr(lastDescriptorAddr);
153 }
else if (cr.command.reset_dma()) {
157 cr.status.dma_transfer_status(3);
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");
173 panic(
"Invalid PCI memory access to unmapped memory.\n");
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());
184 DPRINTF(DMACopyEngine,
"Read device register %#X size: %d\n", daddr, size);
201 assert(size ==
sizeof(uint8_t));
211 panic(
"Read request to unknown register number: %#x\n", daddr);
221 while (daddr >= 0x80) {
227 panic(
"Access to channel %d (device only configured for %d channels)",
233 chan[chanid]->channelRead(pkt, daddr, size);
244 assert(size ==
sizeof(uint16_t));
245 pkt->
setLE<uint16_t>(cr.ctrl());
249 assert(size ==
sizeof(uint64_t));
250 pkt->
setLE<uint64_t>(cr.status() | (busy ? 0 : 1));
253 assert(size ==
sizeof(uint64_t) || size ==
sizeof(uint32_t));
254 if (size ==
sizeof(uint64_t))
255 pkt->
setLE<uint64_t>(cr.descChainAddr);
257 pkt->
setLE<uint32_t>(
bits(cr.descChainAddr,0,31));
260 assert(size ==
sizeof(uint32_t));
261 pkt->
setLE<uint32_t>(
bits(cr.descChainAddr,32,63));
264 assert(size ==
sizeof(uint8_t));
265 pkt->
setLE<uint32_t>(cr.command());
268 assert(size ==
sizeof(uint64_t) || size ==
sizeof(uint32_t));
269 if (size ==
sizeof(uint64_t))
270 pkt->
setLE<uint64_t>(cr.completionAddr);
272 pkt->
setLE<uint32_t>(
bits(cr.completionAddr,0,31));
275 assert(size ==
sizeof(uint32_t));
276 pkt->
setLE<uint32_t>(
bits(cr.completionAddr,32,63));
279 assert(size ==
sizeof(uint32_t));
280 pkt->
setLE<uint32_t>(cr.error());
283 panic(
"Read request to unknown channel register number: (%d)%#x\n",
297 panic(
"Invalid PCI memory access to unmapped memory.\n");
308 if (size ==
sizeof(uint64_t)) {
309 M5_VAR_USED uint64_t
val = pkt->
getLE<uint64_t>();
310 DPRINTF(DMACopyEngine,
"Wrote device register %#X value %#X\n",
312 }
else if (size ==
sizeof(uint32_t)) {
313 M5_VAR_USED uint32_t
val = pkt->
getLE<uint32_t>();
314 DPRINTF(DMACopyEngine,
"Wrote device register %#X value %#X\n",
316 }
else if (size ==
sizeof(uint16_t)) {
317 M5_VAR_USED uint16_t
val = pkt->
getLE<uint16_t>();
318 DPRINTF(DMACopyEngine,
"Wrote device register %#X value %#X\n",
320 }
else if (size ==
sizeof(uint8_t)) {
321 M5_VAR_USED uint8_t
val = pkt->
getLE<uint8_t>();
322 DPRINTF(DMACopyEngine,
"Wrote device register %#X value %#X\n",
325 panic(
"Unknown size for MMIO access: %d\n", size);
333 DPRINTF(DMACopyEngine,
"Warning, ignorning write to register %x\n",
340 panic(
"Read request to unknown register number: %#x\n", daddr);
349 while (daddr >= 0x80) {
355 panic(
"Access to channel %d (device only configured for %d channels)",
361 chan[chanid]->channelWrite(pkt, daddr, size);
372 assert(size ==
sizeof(uint16_t));
374 old_int_disable = cr.ctrl.interrupt_disable();
375 cr.ctrl(pkt->
getLE<uint16_t>());
376 if (cr.ctrl.interrupt_disable())
377 cr.ctrl.interrupt_disable(0);
379 cr.ctrl.interrupt_disable(old_int_disable);
382 assert(size ==
sizeof(uint64_t));
383 DPRINTF(DMACopyEngine,
"Warning, ignorning write to register %x\n",
387 assert(size ==
sizeof(uint64_t) || size ==
sizeof(uint32_t));
388 if (size ==
sizeof(uint64_t))
389 cr.descChainAddr = pkt->
getLE<uint64_t>();
391 cr.descChainAddr = (uint64_t)pkt->
getLE<uint32_t>() |
392 (cr.descChainAddr & ~
mask(32));
393 DPRINTF(DMACopyEngine,
"Chain Address %x\n", cr.descChainAddr);
396 assert(size ==
sizeof(uint32_t));
397 cr.descChainAddr = ((uint64_t)pkt->
getLE<uint32_t>() << 32) |
398 (cr.descChainAddr &
mask(32));
399 DPRINTF(DMACopyEngine,
"Chain Address %x\n", cr.descChainAddr);
402 assert(size ==
sizeof(uint8_t));
403 cr.command(pkt->
getLE<uint8_t>());
407 assert(size ==
sizeof(uint64_t) || size ==
sizeof(uint32_t));
408 if (size ==
sizeof(uint64_t))
409 cr.completionAddr = pkt->
getLE<uint64_t>();
411 cr.completionAddr = pkt->
getLE<uint32_t>() |
412 (cr.completionAddr & ~
mask(32));
415 assert(size ==
sizeof(uint32_t));
416 cr.completionAddr = ((uint64_t)pkt->
getLE<uint32_t>() <<32) |
417 (cr.completionAddr &
mask(32));
420 assert(size ==
sizeof(uint32_t));
421 cr.error(~pkt->
getLE<uint32_t>() & cr.error());
424 panic(
"Read request to unknown channel register number: (%d)%#x\n",
431 const uint8_t &channel_count)
434 "Number of bytes copied by each engine"),
436 "Number of copies processed by each engine")
451 DPRINTF(DMACopyEngine,
"Reading descriptor from at memory location %#x(%#x)\n",
452 address,
ce->pciToDma(address));
456 DPRINTF(DMACopyEngine,
"dmaAction: %#x, %d bytes, to addr %#x\n",
457 ce->pciToDma(address),
sizeof(
DmaDesc), curDmaDesc);
460 sizeof(
DmaDesc), &fetchCompleteEvent,
461 (uint8_t*)curDmaDesc, latBeforeBegin);
462 lastDescriptorAddr = address;
468 DPRINTF(DMACopyEngine,
"Read of descriptor complete\n");
471 DPRINTF(DMACopyEngine,
"Got NULL descriptor, skipping\n");
474 panic(
"Shouldn't be able to get here\n");
475 nextState = CompletionWrite;
476 if (inDrain())
return;
477 writeCompletionStatus();
487 panic(
"Descriptor has flag other that completion status set\n");
490 if (inDrain())
return;
497 DPRINTF(DMACopyEngine,
"Reading %d bytes from buffer to memory location %#x(%#x)\n",
498 curDmaDesc->len, curDmaDesc->dest,
499 ce->pciToDma(curDmaDesc->src));
501 curDmaDesc->len, &readCompleteEvent, copyBuffer, 0);
507 DPRINTF(DMACopyEngine,
"Read of bytes to copy complete\n");
509 nextState = DMAWrite;
510 if (inDrain())
return;
517 DPRINTF(DMACopyEngine,
"Writing %d bytes from buffer to memory location %#x(%#x)\n",
518 curDmaDesc->len, curDmaDesc->dest,
519 ce->pciToDma(curDmaDesc->dest));
522 curDmaDesc->len, &writeCompleteEvent, copyBuffer, 0);
524 ce->copyEngineStats.bytesCopied[channelId] += curDmaDesc->len;
525 ce->copyEngineStats.copiesProcessed[channelId]++;
531 DPRINTF(DMACopyEngine,
"Write of bytes to copy complete user1: %#x\n",
534 cr.status.compl_desc_addr(lastDescriptorAddr >> 6);
535 completionDataReg = cr.status() | 1;
538 nextState = CompletionWrite;
539 if (inDrain())
return;
540 writeCompletionStatus();
544 continueProcessing();
560 if (curDmaDesc->next) {
561 nextState = DescriptorFetch;
562 fetchAddress = curDmaDesc->next;
563 if (inDrain())
return;
564 fetchDescriptor(curDmaDesc->next);
565 }
else if (refreshNext) {
566 nextState = AddressFetch;
568 if (inDrain())
return;
569 fetchNextAddr(lastDescriptorAddr);
579 DPRINTF(DMACopyEngine,
"Writing completion status %#x to address %#x(%#x)\n",
580 completionDataReg, cr.completionAddr,
581 ce->pciToDma(cr.completionAddr));
584 ce->pciToDma(cr.completionAddr),
585 sizeof(completionDataReg), &statusCompleteEvent,
586 (uint8_t*)&completionDataReg, latAfterCompletion);
592 DPRINTF(DMACopyEngine,
"Writing completion status complete\n");
593 continueProcessing();
599 DPRINTF(DMACopyEngine,
"Fetching next address...\n");
602 ce->pciToDma(address + offsetof(
DmaDesc, next)),
603 sizeof(
Addr), &addrCompleteEvent,
604 (uint8_t*)curDmaDesc + offsetof(
DmaDesc, next), 0);
610 DPRINTF(DMACopyEngine,
"Fetching next address complete: %#x\n",
612 if (!curDmaDesc->next) {
613 DPRINTF(DMACopyEngine,
"Got NULL descriptor, nothing more to do\n");
619 nextState = DescriptorFetch;
620 fetchAddress = curDmaDesc->next;
621 if (inDrain())
return;
622 fetchDescriptor(curDmaDesc->next);
629 DPRINTF(Drain,
"CopyEngine done draining, processing drain event\n");
642 DPRINTF(Drain,
"CopyEngineChannel not drained\n");
652 for (
int x =0;
x <
chan.size();
x++)
661 for (
int x = 0;
x <
chan.size();
x++)
675 int nextState = this->nextState;
706 fetchNextAddr(lastDescriptorAddr);
708 case DescriptorFetch:
709 fetchDescriptor(fetchAddress);
717 case CompletionWrite:
718 writeCompletionStatus();
723 panic(
"Unknown state for CopyEngineChannel\n");
730 DPRINTF(DMACopyEngine,
"Restarting state machine at state %d\n", nextState);
731 restartStateMachine();