PCIE-XPDMA-Simple DMA传输笔记

    xiaoxiao2022-07-07  171

    声明:所有文章属于个人在工作中所记下和搜集的笔记,不得转载

    参考的手册地址: a). Xilinx PCIe axi memory mapped手册地址链接:https://china.xilinx.com/support/documentation/ip_documentation/axi_pcie/v2_8/pg055-axi-bridge-pcie.pdf b). xapp1171文档PCI Express Endpoint-DMA Initiator Subsystem手册地址链接: https://www.xilinx.com/support/documentation/application_notes/xapp1171-pcie-central-dma-subsystem.pdf c)AXI Central Direct Memory Access (CDMA) 手册地址链接: https://china.xilinx.com/support/documentation/ip_documentation/axi_cdma/v4_1/pg034-axi-cdma.pdf

    昨晚上熬夜写完PCIE调用SGDMA的笔记,今天早上起来再写写Simple DMA的笔记。

    五月底了,长沙的天气还是下雨很多,好在很凉快,早上下了一场大雨,空气清新,结束了这几天闷热的天气。坐在窗户边,透过10楼的窗户,看着窗外的风景,不远处便是岳麓山,写写博客,听听歌。转眼从满是皖A的城市来到满是湘A的城市9个月了,时间过得很快,还是需要加油ya。

    首先搭建好Block模块,使用Simple DMA与使用SG DMA搭建的还是有点区别的: 用了两个interconnect模块,axi_interconnect_0模块连接PCIE_CTL接口、CDMA_LITE接口、PCIE_PIO_M_AXI接口;axi_interconnect_1模块连接AXI_PCIE接口、PCIE_DATA_M_AXI接口。其实一个1x3和一个1x2这两个axi_interconnect模块所消耗的资源加起来比SG模式下用到的3x6的axi_interconnect模块所消耗的资源要少很多。 axi_cdma模块不勾选Enable Scatter Gather,读写数据位宽64,地址位宽33(注意是:33),突发读写大小为256; AXI Memory Mapped To PCI Express模块: PCIEBAR2AXIBAR勾选BAR0,映射基地址为:0x8100_0000,128kilobytes够用了(0x8102_0000); AXIBAR2PCIEBAR勾选BAR0,映射基地址BAR0为:0x0000_0000,用来存放数据; 在添加AXI总线接口的时候Frequency填:125000000,CLK Domain填:design_1_axi_pcie_1_0_axi_aclk_out

    地址分配: 从上图可以看出,在地址分配的时候PCIE的BAR0 AXI总线地址空间分配了整个RC端的CPU内存大小,这样跟前一篇博客讲到的分配8M的地址空间是有区别的; pcie_data_m_axi空间也是分配了很大,这里假设外部挂的是一个4G内存的DDR存储。 pcie的m_axi进行cdma寄存器配置、pcie寄存器配置、外部寄存器配置

    寄存器配置流程 由于采用的是简单DMA模式,所以就不需要描述符这些东西。配置好寄存器后直接就可以工作。 关于详细的寄存器描述请参考pg055和pg034; PCIEBAR2AXIBAR0=0x8100_0000

    1).PCIEBAR2AXIBAR0+0X0000_C000 数据:0x0000_0004;配置CDMA的寄存器,对CDMA复位 2).PCIEBAR2AXIBAR0+0X0000_C000 数据:0x0000_7000;配置CDMA的寄存器,开启DMA传输完成中断,错误中断,启用简单模式 3).PCIEBAR2AXIBAR0+0X0000_8208 数据:0x0000_0000;配置PCIE的寄存器,bar0映射的RC端的高32位物理地址(该值不需修改) 4).PCIEBAR2AXIBAR0+0X0000_820c 数据:0x0000_0000;配置PCIE的寄存器,bar0映射的RC端的低32位物理地址(该值不需修改) 5).PCIEBAR2AXIBAR0+0X0000_c018 数据:32’hxxxx_xxxx;配置CDMA的寄存器,CDMA SA起始读低地址 6).PCIEBAR2AXIBAR0+0X0000_c01c 数据:32’hxxxx_xxxx;配置CDMA的寄存器,CDMA SA_M起始读高地址 7).PCIEBAR2AXIBAR0+0X0000_c020 数据:32’hxxxx_xxxx;配置CDMA的寄存器,CDMA DA起始写低地址 8).PCIEBAR2AXIBAR0+0X0000_c024 数据:32’hxxxx_xxxx;配置CDMA的寄存器,CDMA DA_M起始写高地址 9).PCIEBAR2AXIBAR0+0X0000_c028 数据:32’hxxxx_xxxx;配置CDMA的寄存器,传输的字节数,写入大于4时,启动DMA的数据传输,最大值0x3ef_ffff; 10).写入第九步的寄存器后DMA工作开始,直到读完上面设置的字节个数,完成数据搬移动作后,停止。关于数据的搬移可以看CDMA IP的官方仿真平台。 11).PCIEBAR2AXIBAR0+0X0000_C004 数据:0x0000_7000;因为没有描述符,所以要想知道什么时候传输完成了,建议启用中断,中断发生后需要在CDMA的状态寄存器写1清除中断。 12).跳转到第3步重复之前的步骤就可以连续传输了,根据SA和DA的地址决定了数据传输的方向。

    需要注意的是:因为PCIE的0x208寄存器和0x20c寄存器固定配置成了0,所以BAR1端的地址映射到RC端是从0开始的,那么以PCIE写数据为例:SA地址直接给RC端的物理地址即可,DA端的地址低位直接给DDR的地址,高位必须得给0x0000_0001。

    封装后的Block生成HDL Wrapper和SG DMA的一样,这里不再重复,请参考https://blog.csdn.net/Real003/article/details/90454365

    Sample DMA要求RC端申请的数据地址必须是连续的,而SG DMA因为有描述符的存在,所以可以要求RC端申请的数据地址不连续,但是要求描述符必须要正确,不然取数据会不对。 另外对于字节对齐的问题也同样是需要考虑!

    XPDMA软件驱动 https://github.com/strezh/XPDMA 中貌似没有中断部分,如果需要用到PCIE的中断,这部分代码还得自己去开发,我们的策略是通过自定义的一个状态寄存器来让PCIE通过PIO来轮询读取判断EP端是否有数据供RC端读。

    笔记差不多记完了,如果你也需要开发PCIE memory mapped的驱动,pg055、pg034、xapp1171需要仔细去看看,了解整个工作流程就能跑起来。

    最新回复(0)