使用PC作为主机,将Linux驱动程序进行DMA传输到PCIe卡。

8
我正在开发一份DMA例程,用于将数据从PC传输到PCIe卡上的FPGA。我已经阅读了DMA-API.txt和LDD3第15章的详细信息。然而,我无法弄清楚如何在PC与PCIe卡上的一致的iomem块之间进行DMA传输。LDD3中PCI的样例映射了一个缓冲区,然后“告诉卡”执行DMA传输,但我需要PC来执行此操作。
我已经找到的信息:
  1. Request bus master

    pci_set_master(pdev);
    
  2. Set the DMA mask

    if (dma_set_mask(&(pdev->dev), DMA_BIT_MASK(32))) {
        dev_err(&pdev->dev,"No suitable DMA available.\n");
        goto cleanup;
    }
    
  3. Request a DMA channel

    if (request_dma(dmachannel, DRIVER_NAME)) {
        dev_err(&pdev->dev,"Could not reserve DMA channel %d.\n", dmachannel);
        goto cleanup;
    }
    
  4. Map a buffer for DMA transfer

    dma_handle = pci_map_single(pci_dev, buffer, count, DMA_TO_DEVICE);
    

问题:

我需要做什么才能让PC执行DMA传输而不是卡片?

谢谢您的帮助!


首先感谢您的回复。也许我应该更准确地提出我的问题:

  1. 在我看来,PC必须有一个DMA控制器。如何访问此DMA控制器以启动对PCIe卡中内存映射IO区域的传输?
  2. 我们的规格要求PC的DMA控制器启动传输。但是,我只能找到设备执行DMA任务的示例(DMA_mapping.txt,LDD3第15章)。是否有原因,为什么没有人使用PC的DMA控制器(它仍然具有DMA通道)?请求为我们的项目更改规格是否更好?

感谢您的耐心。


1
“从PC传输数据”指的是针对外部设备的,例如“从PC到打印机”。对于内部传输来说,这种说法没有意义。您可能是指主存储器。“让PC执行DMA传输”也没有意义。您可能是指DMA控制器。回答:设置DMAC而不是PCI总线主控制器。 - sawdust
2个回答

6
请查阅DMA_mapping.txt。其中有一段长篇内容告诉您如何设置方向(“DMA direction”,第408行)。
编辑
好的,既然您编辑了您的问题……您的规格是错误的。您可以设置系统DMA控制器,但这是没有意义的,因为它太慢了,正如我在评论中所说。请阅读this thread
您必须更改您的FPGA以支持总线主控。我从事此业务-如果您想要分包,请与我联系。

是的,我看过了。那里的代码告诉我们如何为DMA传输设置缓冲区。相同的结构(pci_map/pci_unmap)在LDD3第15章中也被使用,但是还有激活PCI卡上的DMA控制器的指令。因此,我认为这只是将缓冲区标记为“DMA就绪”,并让设备进行DMA传输。方向只告诉DMA控制器应该读取或写入缓冲区(或两者都有)。它没有告诉我如何激活PC的DMA控制器(或者至少我没有理解到)。 - kohpe
1
不是“激活PC的DMA控制器”。在PCIe上有两种进行DMA的方式:(1)“系统”DMA和(2)“总线主控”DMA。 (1)已经过时了;这不是一个选项。 “系统”DMA控制器仍然在您的PC上,但它在错误的位置并且速度太慢。相反,您的FPGA必须成为总线主控,并突发所需的数据输入或输出。因此,您根据DMA_mapping.txt设置DMA方向,然后写入卡上的寄存器以启动总线主控突发读取(从PC到FPGA)。查看您的FPGA供应商应用说明;从XAPP1052开始。还要注意,LDD3几乎没有用处。 - EML
上方空间不足...编写你的FPGA的人是否了解总线主控操作?你有一个启用总线主控的控制位吗?如果没有,那么你的FPGA在任何方向上都不能进行“DMA”。 - EML
规格已更改。现在FPGA负责DMA工作。问题解决了。谢谢! - kohpe
1
@EML 您提供的链接已失效。您能否简要解释一下为什么PC端的DMA在将数据从CPU侧内存推送到FPGA内存时速度较慢?以及为什么FPGA端的DMA作为总线主机在这种类型的事务中更快? - Mehmet Fide

1
你所说的并不是真正的DMA。DMA是指设备访问内存时CPU本身没有参与(除了现在通常嵌入到PC CPU中的PC内存控制器)。并非所有设备都能够这样做,如果你正在使用FPGA,则肯定需要在设计中使用某种DMA控制器(例如Expresso DMA Core或类似产品)。在你的情况下,你只需使用iowrite调用(例如iowrite32)写入映射的内存区域(即使用ioremap_nocache获得的内存区域),然后再使用写内存屏障wmb()。你需要写入的I/O栏和地址完全取决于你的设备。

希望能对你有所帮助。祝你好运!


2
“你所说的并不是真正的DMA”,“那么你的设计肯定需要某种DMA控制器”--你似乎在提到一个(PCI/PCIe)板执行总线主控。一个外围设备(设计有额外的DMA控制/握手信号)可以利用系统的DMA控制器(包含在IBM PC设计中),通过使用DMA(而不是编程I/O)。 - sawdust
@sawdust 是的,你说得对,总线主控是关键。我有时候对于正确的符号表示很糟糕。我不认为今天的普通个人电脑还有那些DMA控制器,或者它们有吗? - user405725
PC必须具备DMAC才能“兼容IBM PC”。DMA控制器并不昂贵。如果您可以放置一个时钟速度比原始i8088快350倍以上的处理器(并包括数字协处理器)并且具有超过1000倍的内存,则在“商品PC”中可以负担得起DMAC。 - sawdust
@VladLazarenko:是的,我可以向FPGA的内存块写入数据。已经测试过了,它可以正常工作。下一步是让PC的DMA控制器将数据传输到这个内存区域,但我找到的所有示例都是关于保留内存缓冲区并让卡的DMA控制器完成任务(包括DMA_mapping.txt、LDD3 ch. 15)。问题是,如何激活PC的 DMA控制器,因为规范文档说DMA必须来自PC端。 - kohpe
1
“DMA”这个名称表示您的CPU没有进行主动传输。这立即意味着其他东西必须为您完成它。PC中有一个“DMA控制器”,但据我所知,它们只能在ISA速度上工作,并且对于PCI-e没有多大用处。您需要一个DMA控制器,以便为目标设备的速度执行一些有用的操作;通常,您只需将DMA控制器/总线主控添加到FPGA设计中并使用即可。或者,使用相反的方法-让CPU执行主动复制。 - dascandy
在PCI上下文中谈到“DMA”时,它是指CPU / SoC端的DMA(还是外部设备)? - ransh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接