PCI的DMA操作
参考:PCIe实践之路:DMA机制
PCI设备的DMA写用Posted方式,读使用NON-Posted方式。
RC从EP端读取数据
假设现在RC要从EP mem space读1MB数据,可以有这么两种方式:
- RC发起DMA读;
- EP发起DMA写。
这两种方式结果是等效的,对最后完成中断的方式会不一样,前者通过local interrupt表示自己DMA读完了,后者需要EP发送一笔IMWr来表示DMA读完成了。
SAR和DST
SAR:DMA传输的数据源地址, 这里是从EP 读,所以是EP中某个BAR range内地址。
DST: DMA的目标地址, 这里从EP读数据到DDR,所以是DDR中某个地址。
Max_Payload_Size
DMA读写本质上还是通过拆分成TLP来进行的,每次传输的size就是通过tlp header中的length来确定的,而length由控制器的Max_Payload_Size决定,这个值取EP和RC的capability中相应参数的最小值.
Linked List
EP往RC写:
*DMA写操作流程*
Reg Address RegData
0x1000_7010 0x0000_0001 ;// DMA Write Engine Enable
0x1000_7028 0x0000_0000 ;// DMA Write Interrupt Mask
0x1000_7058 0x0400_0008 ;// DMA Write Channel Control 1 register
/ 传输长度 /
0x1000_7060 0x0000_0400 ;// DMA Write Transfer Size ????-bytes
/ 双方地址 /
0x1000_7064 0x????_0000 ;// DMA Write SAR Low (Local(EP) Memory Address)[高位需要与地址是0x1000_0010的值保持一致][31]需要是1
0x1000_7068 0x???????? ;// DMA Write SAR High(Local(EP) Memory Address)[全部需要与地址是0x10000014的值保持一致]
0x1000_706c 0x???????? ;// DMA Write DAR Low (Remote(PC) Memory Address)
0x10007070 0x???????? ;// DMA Write DAR High(Remote(PC) Memory Address)
/ 开始传输 /
0x1000_7014 0x0000_0000 ;// DMA Write Doorbell
读
0x1000_7024
判断第0位是否为1,若为1则表示传输完成,
写
0x1000_702c 0x0000_0001 ;// DMA Write Interrupt Clear
0x1000_7010 0x0000_0000 ;// DMA Write Engine Disable
*DMA读操作流程*
Reg Address Reg_Data
0x1000_7080 0x0000_0001 ;// DMA Read Engine Enable
0x1000_7098 0x0000_0000 ;// DMA Read Interrupt Mask
0x1000_70cc 0x0400_0008 ;// DMA Read Channel Control 1 register
/ 传输长度 /
0x1000_70d4 0x0000_0400 ;// DMA Read Transfer Size ????-bytes
/ 双方地址 /
0x100070d8 0x???????? ;// DMA Read SAR Low (Remote(PC) Memory Address)
0x100070dc 0x???????? ;// DMA Read SAR High (Remote(PC) Memory Address)
0x100070e0 0x????_0000 ;// DMA Read DAR Low (Local(EP) Memory Address)[高位需要与地址是0x1000_0010的值保持一致][31]需要是1
0x1000_70e4 0x???????? ;// DMA Read DAR High(Local(EP) Memory Address)[全部需要与地址是0x1000_0014的值保持一致]
/ 开始传输 /
0x1000_7084 0x0000_0000 ;// DMA Read Doorbell
读
0x1000_7094
判断第0位是否为1,若为1则表示传输完成,
写
0x1000_709c 0x0000_0001 ;// DMA Read Interrupt Clear
0x1000_7080 0x0000_0000 ;// DMA Read Engine Disable