目录
- 1. What is SG DMA
- 2. Descriptor
- 3. Transfer for H2C
- Step 1. The host prepares stored data and creates descriptors in main memory
- Step 2. The host enables DMA interrupts
- Step 2. The driver initializes DMA with descriptor start address
- Step 3. The driver writes a control register to start the DMA transfer
- Step 4. The DMA reads descriptors from the host and starts processing each descriptor.
- Step 4. The DMA fetches data from the host and sends the data to the user side.
- Step 5. After all data is transferred based on the settings, the DMA generates an interrupt to the host.
- Step 6. The driver processes the interrupt to find out channel number and checks status to see if there are any errors.
- Step 7. The driver stops DMA run and return Step 1
XDMA是Xilinx 为了方便不熟悉PCIe用户封装起来的PCIe 易用 IP
回见 XDMA原理
pg195 《DMA/Bridge Subsystem for PCI Express v4.1Product Guide Vivado Design Suite》
1. What is SG DMA
AXI4 Memory Mapped接口是XDMA实现SG DMA的接口,可以配置为多Channel H2C Stream或C2H Stream类型,也可以配置为AXI4 Master用于所有通道共享。此处我们介绍配置为AXI4 Memory Mapped的SG DMA,对应到XDMA IP上其实就是一个M_AXI接口
首先介绍一下什么是SG DMA。SG DMA与普通DMA不同的是 允许每次 DMA 传输访问多个内存空间,所有任务都结束后,才发出中断。 能够提高CPU工作效率。
SG DMA基本原理是主机在主存中开辟一片空间保存H2C链表和C2H链表,链表以 Descriptor 为基本单元。每个Descriptor包含了要进行DMA的起始地址、长度、目标外设地址、下一个Descriptor在内存空间地址等信息。
主机控制SG DMA启动后,先读取第一个Descriptor、解析、执行DMA传输,传输完成后再从主存中读取第二个Descriptor,往复循环上述过程,直到读取到最后一个Descriptor,完成传输发出中断。
对于XDMA来说,XDMA执行SG DMA是基于通过BAR空间对相关DMA寄存器控制 进行的。
基于Xilinx FPGA的AXI Direct Memory Access (Scatter Gather Engine模式) 行为分析及软件操作流程
2. Descriptor
无论是H2C还是C2H,XDMA规定的descriptor格式如下图所示
可以看到一个descriptor占32字节
Len[27:0]单位是字节,Nxt_adj[5:0]表示链表后还剩多少个descriptor。
Src_addr[63:0]表示需要执行DMA的数据源地址,如果是H2C DMA该地址为主机侧PCIe总线域地址,若是C2H DMA该地址为FPGA侧AXI总线域地址。
同理,Dst_addr[63:0]表示需要执行DMA的数据目的地址,如果是H2C DMA该地址为FPGA侧AXI总线域地址,若是C2H DMA该地址为主机侧PCIe总线域地址。
Nxt_addr[63:0]表示下一个descriptor地址,只能是主机侧PCIe总线域地址。
可以在XDMA IP的GUI界面的PCIe: DMA标签下选择Descriptor Bypass for H2C和C2H,就可以通过旁路接口输入descriptor,可以不只从host主存获取
36.XDMA原理详解2-DMA描述符、描述符FIFO、描述符旁路详解
3. Transfer for H2C
XDMA执行SG DMA是基于通过BAR空间对相关DMA寄存器控制 进行的。
下面以H2C为例,介绍XDMA执行SG DMA整个流程
图中一个框出多个箭头表示并行执行。
执行过程如下:
Step 1. The host prepares stored data and creates descriptors in main memory
主机向主存中存储多块连续数据,假设为100块。主机生成100个Descriptor分别指向这100个数据块,形成descriptors链表放入主存中。
注意每个descriptor.Dst_adr[63:0]是FPGA侧的AXI总线域地址
Step 2. The host enables DMA interrupts
主机初始化H2C DMA,开启中断。以H2C通道1(0起始)为例
H2C Channel 1的DMA中断开启包括 H2C通道中断使能掩码0x0190、IRQ模块DMA引擎中断使能掩码0x2010
–
Step 2. The driver initializes DMA with descriptor start address
主机通过MWr TLP命中 XDMA某个H2C Channel的BAR空间,向该Channel的 SG DMA寄存器组写入首descriptor起始地址、首descriptor后的descriptor个数。
分别对应XDMA中BAR空间地址(即MWr TLP中的Address[31:0]字段,下同)为0x4180、0x4184、0x4188寄存器
Step 3. The driver writes a control register to start the DMA transfer
DMA引擎启动,开启对应通道的descriptor获取。
寄存器包括H2C Channel 1Control寄存器0x0104、SGDMA Descriptor Controller 寄存器0x6110等等
Step 4. The DMA reads descriptors from the host and starts processing each descriptor.
XDMA根据H2C Channel 1的SG DMA寄存器组的信息,以及获取的descriptor中Nxt_adr[63:0]信息,不断向主机发送MRd TLP包,获取descriptor缓存入FIFO。
与此同时,XDMA不断从FIFO读出descriptor,每读出一个descriptor,根据descriptor中PCI总线域源地址Src_adr[63:0]和长度Length[27:0]信息向主机发送MRd TLP包,主机从主存中读出待DMA的数据并通过CplD TLP返回给XDMA。
每次向主机请求多少个Descriptor(每个MRd TLP的Length[9:0]字段)与XDMA自身的Max Read Request Size(MRRS)寄存器0x300C和descriptor FIFO容量有关。
MRRS寄存器如下所示,一般为512B或1024B
DMA内部descriptor FIFO深度为 AXI Data Width×512供所有Channel共用,例如2个H2C、2个C2H的Gen3 x8,AXI Data Width=256bit,因此有256bit×5122=16KB=32B×512,可放入512个descriptor。
Step 4. The DMA fetches data from the host and sends the data to the user side.
XDMA收到CplD后,根据descriptor中AXI总线域目的地址Dst_adr[63:0]的信息,通过AXI MM接口进行AXI写握手。待全部数据写握手完毕后,从FIFO中读出下一个descriptor,直到所有descriptors处理完毕
Step 5. After all data is transferred based on the settings, the DMA generates an interrupt to the host.
XDMA使用Msg TLP向主机发送MSI-X中断(需在GUI中设置好)。
Msg TLP中Address以及Data需根据DMA中断向量号寄存器(预先设定好) 0x01A0、0x01A4,以及MSI-X Vector Table and PBA 0x8000-0x8FE0
Step 6. The driver processes the interrupt to find out channel number and checks status to see if there are any errors.
主机先向XDMA发送MRd TLP,读取IRQ模块DMA中断请求寄存器0x2044判断是哪个Channel发出的中断。
之后,主机再发送MWr TLP,写入IRQ模块DMA引擎中断使能掩码0x2010将该Channel中断屏蔽
主机向XDMA发送MRd TLP,读取H2C Channel1状态寄存器0x0144检查DMA过程是否存在错误。
主机向XDMA发送MRd TLP,读取H2C Channel1状态寄存器0x0148检查DMA处理的descriptors数量是否正确。
Step 7. The driver stops DMA run and return Step 1
主机向XDMA发送MWr TLP,写入H2C Channel1状态寄存器0x0104以关闭H2C Channel 1的DMA引擎。