gpt4 book ai didi

fpga - 从 PC 到 FPGA 的 DMA PCIe 读取传输

转载 作者:行者123 更新时间:2023-12-04 15:42:58 27 4
gpt4 key购买 nike

我正在尝试在 FPGA 和 x86_64 Linux 机器之间进行 DMA 传输。

在 PC 端,我正在做这个初始化:

//driver probe
...
pci_set_master(dev); //set endpoint as master
result = pci_set_dma_mask(dev, 0xffffffffffffffff); //set as 64bit capable
...

//read
pagePointer = __get_free_page(__GFP_HIGHMEM); //get 1 page
temp_addr = dma_map_page(&myPCIDev->dev,pagePointer,0,PAGE_SIZE,DMA_TO_DEVICE);
printk(KERN_WARNING "[%s]Page address: 0x%lx Bus address: 0x%lx\n",DEVICE_NAME,pagePointer,temp_addr);
writeq(cpu_to_be64(temp_addr),bar0Addr); //send address to FPGA
wmb();
writeq(cpu_to_be64(1),bar1Addr); //start trasnfer
wmb();

总线地址是 64 位地址。
在 FPGA 端,我发送的 TLP 用于读取 1 个 DW:
Fmt: "001"
Type: "00000"
R|TC|R|Attr|R|TH : "00000000"
TD|EP|Attr|AT : "000000"
Length : "0000000001"
Requester ID
Tag : "00000000"
Byte Enable : "00001111";
Address : (address from dma map page)

我从 PC 上返回的完成是:
Fmt: "000"
Type: "01010"
R|TC|R|Attr|R|TH : "00000000"
TD|EP|Attr|AT : "000000"
Length : "0000000000"
Completer ID
Compl Status|BCM : "0010"
Length : "0000000000";
Requester ID
Tag : "00000000"
R|Lower address : "00000000"

所以基本上是一个没有数据且状态为 Unsupported Request 的完成。
我不认为 TLP 的构建有问题,但我也看不到驱动程序方面的任何问题。
我使用的内核启用了 PCIe 错误报告,但我在 dmesg 输出中看不到任何内容。
怎么了?或者,有没有办法找出为什么我收到不支持的请求
完成?

马可

最佳答案

这是我的一个设计的摘录(有效!)。它是 VHDL,略有不同,但希望它能帮助你:

-- First dword of TLP Header
tlp_header_0(31 downto 30) <= "01"; -- Format = MemWr
tlp_header_0(29) <= '0' when pcie_addr(63 downto 32) = 0 else '1'; -- 3DW header or 4DW header
tlp_header_0(28 downto 24) <= "00000"; -- Type
tlp_header_0(23) <= '0'; -- Reserved
tlp_header_0(22 downto 20) <= "000"; -- Default traffic class
tlp_header_0(19) <= '0'; -- Reserved
tlp_header_0(18) <= '0'; -- No ID-based ordering
tlp_header_0(17) <= '0'; -- Reserved
tlp_header_0(16) <= '0'; -- No TLP processing hint
tlp_header_0(15) <= '0'; -- No TLP Digest
tlp_header_0(14) <= '0'; -- Not poisoned
tlp_header_0(13 downto 12) <= "00"; -- No PCI-X relaxed ordering, no snooping
tlp_header_0(11 downto 10) <= "00"; -- No address translation
tlp_header_0( 9 downto 0) <= "00" & X"20"; -- Length = 32 dwords

-- Second dword of TLP Header
-- Bits 31 downto 16 are Requester ID, set by hardware PCIe core
tlp_header_1(15 downto 8) <= X"00"; -- Tag, it may have to increment
tlp_header_1( 7 downto 4) <= "1111"; -- Last dword byte enable
tlp_header_1( 3 downto 0) <= "1111"; -- First dword byte enable

-- Third and fourth dwords of TLP Header, fourth is *not* sent when pcie_addr is 32 bits
tlp_header_2 <= std_logic_vector(pcie_addr(31 downto 0)) when pcie_addr(63 downto 32) = 0 else std_logic_vector(pcie_addr(31 downto 0));
tlp_header_3 <= std_logic_vector(pcie_addr(31 downto 0));

让我们忽略我正在表演的明显差异 MemWr 32 个双字,而不是读取双字。第一次这样做时给我带来麻烦的另一个区别是您 如果地址低于 4GB,则必须使用 3DW header .

这意味着您必须检查从主机获得的地址,并确定是否需要使用 3DW header (只有地址的 LSB)或完整的 4DW header 模式。

除非您需要传输大量数据,否则您可以将 dma 地址掩码设置为 32 位以在 3DW 情况下始终保持不变,默认情况下 Linux 应保留大量低于 4GB 的内存位置。

关于fpga - 从 PC 到 FPGA 的 DMA PCIe 读取传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30607667/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com