【经验分享】AMD MPSoC PS PCIe 访问PL BRAM的参考设计

AMD MPSoC PS PCIe 访问PL BRAM的参考设计

作者

付汉杰 hankf@amd.com

致谢

覃柱胜
王亮

测试环境:

Vivado 2024.1,
Vitis Classic 2024.1,
Avnet UltraZed Board.
AMD R2000 R2544 Board,
Ubuntu 20.04

UltraZed Board

AMD R2000 R2544 + UltraZed Board

客户需求

客户要求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时的波形。

Block Design

其它部分,没有更改。其中PCIe 的Serdes设置如下:

PCIe 的Serdes设置

PCIe 的参考时钟设置如下:

PCIe 的参考时钟

PCIe 的设备类型、IO BAR、中断设置如下:

PCIe 的设备类型

PCIe 的IO BAR 0

PCIe 的IO BAR 1

PCIe 的IO BAR 2

PCIe 的中断

编译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。

编译后的文件结构如下。

MPSoC 软件文件结构

把启动文件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访问,从而能避免上述系统挂死的情况。

posted @ 2024-06-27 17:41  HankFu  阅读(54)  评论(0编辑  收藏  举报