作者
付汉杰 hankf@amd.com
致谢
覃柱胜
王亮
测试环境:
Vivado 2024.1,
Vitis Classic 2024.1,
Avnet UltraZed Board.
AMD R2000 R2544 Board,
Ubuntu 20.04
客户需求
客户要求AMD MPSoC 的 PS 部分的 PCIe 能访问 PL的AXI BRAM。
Vivado设计
从Avnet 借了 UltraZed Board,得到了Vivado工程。设置BRAM的地址为0x8000-0000,BRAM大小为64KB。为了验证PL的AXI BRAM的访问,在Block Design中增加了System ILA,用于抓取PCIe访问AXI BRAM时的波形。
其它部分,没有更改。其中PCIe 的Serdes设置如下:
PCIe 的参考时钟设置如下:
PCIe 的设备类型、IO BAR、中断设置如下:
编译Vivado工程,导出XSA文件。
AMD MPSoC 软件
得到XSA文件后,在Vitis Classic 2024.1 里以“Hello World”为模板创建工程,删除“hellworld.c”。
再把目录“Xilinx\Vitis\2024.1\data\embeddedsw\XilinxProcessorIPLib\drivers\pciepsu_v1_7\examples”中的文件“xpciepsu_ingress_ep_enable_example.c”复制到工程中。编译System工程,得到对应的ELF文件和启动文件BOOT.BIN。
编译后的文件结构如下。
把启动文件BOOT.BIN,复制到TF卡,插入UltraZed Board,单板能正常启动。如果没有插入X86 PCIe插槽,串口打印如下:
Zynq MP First Stage Boot Loader
Release 2024.1 Jun 26 2024 - 15:00:05
PMU-FW is not running, certain applications may not be supported.
Waiting for PCIe Link up
如果插入X86 PCIe插槽,串口增加的打印如下:
PCIe Link up...
Bridge Init done...
Host driver indicated ready
pcie_psu: BAR2 LO configured by host 0xC0900000
pcie_psu: BAR2 HI configured by host 0x00000000
pcie_psu: Done writing the Ingress Src registers
pcie_psu: Done writing the Ingress Dst registers
pcie_psu: Read Ingress Control register
pcie_psu: Done setting up the ingress trasnslation registers
PCIE Ingress Test done
X86 R2544 Ubuntu 20 软件
从github复制代码
git clone git@github.com:Xilinx/zynqmp-pspcie-epdma.git
按README.md编译。编译命令:
cd zynqmp_ep_ps_pcie_dma
make
sudo make insert
编译日志:
xilinx@xilinx-Bilby-RV1:~/zynqmp-pspcie-epdma$ uname -a
Linux xilinx-Bilby-RV1 5.15.0-113-generic #123~20.04.1-Ubuntu SMP Wed Jun 12 17:33:13 UTC 2024 x86_64 x86_6GNU/Linux
xilinx@xilinx-Bilby-RV1:~/zynqmp-pspcie-epdma$ make
Compiling PS PCIe DMA Driver
make[1]: Entering directory '/home/xilinx/zynqmp-pspcie-epdma/driver'
make -C /lib/modules/5.15.0-113-generic/build M=/home/xilinx/zynqmp-pspcie-epdma/driver SUBDIRS= modules
make[2]: Entering directory '/usr/src/linux-headers-5.15.0-113-generic'
CC [M] /home/xilinx/zynqmp-pspcie-epdma/driver/ps_pcie_dma.o
......
......
......
CC [M] /home/xilinx/zynqmp-pspcie-epdma/driver/ps_pcie_dma.mod.o
LD [M] /home/xilinx/zynqmp-pspcie-epdma/driver/ps_pcie_dma.ko
BTF [M] /home/xilinx/zynqmp-pspcie-epdma/driver/ps_pcie_dma.ko
Skipping BTF generation for /home/xilinx/zynqmp-pspcie-epdma/driver/ps_pcie_dma.ko due to unavailability of
make[2]: Leaving directory '/usr/src/linux-headers-5.15.0-113-generic'
make[1]: Leaving directory '/home/xilinx/zynqmp-pspcie-epdma/driver'
***** Driver Compiled *****
Compiling Test Applications
make[1]: Entering directory '/home/xilinx/zynqmp-pspcie-epdma/apps'
gcc -c -O3 -Os -I /home/xilinx/zynqmp-pspcie-epdma -I ../common/ sync_test.c -o sync_test.o
gcc -O3 -Os -I /home/xilinx/zynqmp-pspcie-epdma sync_test.o -lpthread -o simple_test
gcc -c -O3 -Os -I /home/xilinx/zynqmp-pspcie-epdma -I ../common/ pci_pio_test.c -o pci_pio_test.o
gcc -O3 -Os -I /home/xilinx/zynqmp-pspcie-epdma pci_pio_test.o -lpthread -o pio_test
make[1]: Leaving directory '/home/xilinx/zynqmp-pspcie-epdma/apps'
***** Applications Compiled *****
xilinx@xilinx-Bilby-RV1:~/zynqmp-pspcie-epdma$ find -name "*.ko"
./driver/ps_pcie_dma.ko
安装驱动后,内核输出内容:
xilinx@xilinx-Bilby-RV1:~/zynqmp-pspcie-epdma$ sudo make insert
[sudo] password for xilinx:
Inserting PS PCIe DMA Driver
***** Driver Loaded *****
xilinx@xilinx-Bilby-RV1:~/zynqmp-pspcie-epdma$ dmesg | tail -n 30
......
......
[ 6011.393878] ps_pcie_dma: loading out-of-tree module taints kernel.
[ 6011.393942] ps_pcie_dma: module verification failed: signature and/or required key missing - tainting ke
[ 6011.394437] ps_pcie_dma init()
[ 6011.394491] ps_pcie_dma 0000:01:00.0: PS PCIe DMA PCIe Driver probe
[ 6011.394625] ps_pcie_dma 0000:01:00.0: PS PCIe DMA PCIe 64bit access capable
[ 6011.475001] ps_pcie_dma 0000:01:00.0: MSI/MSI-X not detected - using legacy interrupts
[ 6011.475304] ps_pcie_dma 0000:01:00.0: PS PCIe DMA driver successfully probed
安装驱动后,设备节点信息:
xilinx@xilinx-Bilby-RV1:~/zynqmp-pspcie-epdma$ ls /dev/ps_pcie_* -l
crwxrwxrwx 1 root root 510, 0 6月 27 15:55 /dev/ps_pcie_dmachan0_0
crwxrwxrwx 1 root root 510, 1 6月 27 15:55 /dev/ps_pcie_dmachan1_0
crwxrwxrwx 1 root root 510, 2 6月 27 15:55 /dev/ps_pcie_dmachan2_0
crwxrwxrwx 1 root root 510, 3 6月 27 15:55 /dev/ps_pcie_dmachan3_0
crwxrwxrwx 1 root root 509, 0 6月 27 15:55 /dev/ps_pcie_pio_0
X86 R2544 Ubuntu 20.04 测试
运行命令“simple_test”,能发起DMA访问16KB和64KB数据。注意,通过参数“-a 0x80000000”指定PL BRAM的地址。
xilinx@xilinx-Bilby-RV1:~/zynqmp-pspcie-epdma/apps$ ./simple_test -c 0 -a 0x80000000 -l 16384 -d s2c
write return value is 16384
Total time taken for transferring 16384 bytes of data is 115 micro seconds
xilinx@xilinx-Bilby-RV1:~/zynqmp-pspcie-epdma/apps$ ./simple_test -c 0 -a 0x80000000 -l 65536 -d s2c
write return value is 65536
Total time taken for transferring 65536 bytes of data is 271 micro seconds
通过System ILA,可以看到单板硬件上有AXI访问波形。
运行命令“simple_test”,故意访问64KB+8Byte数据,由于超过了BRAM大小(64KB),就会挂死系统,程序一直不结束。这是正常的。
xilinx@xilinx-Bilby-RV1:~/zynqmp-pspcie-epdma/apps$ ./simple_test -c 0 -a 0x80000000 -l 131072 -d s2c
^C^C
可以添加AXI Firewall检查超时的AXI访问,并自动结束错误的AXI访问,从而能避免上述系统挂死的情况。
文章来源:博客园