硬件开发——PCIe
小狼@http://blog.csdn.net/xiaolangyangyang
一、引脚定义
- SMBUS:10kHz~100KHz,用于传输PCIe卡信息(如智能电源管理)
- JTAG:
- 设插拔:PRSNT1#和PRSNT2#用于PCIe热插拔,在PCIe卡上,PRSNT1#和PRSNT2#短接,而在处理器主板中,PRSNT1#信号接地,PRSNT2#信号通过上拉电阻拉高,PCIe卡插入时,处理器端的PRSNT2#被接地,拔出时,PRSNT2#被电阻上拉。如下图所示:
二、配置空间及枚举过程
- 访问配置寄存器
- x86 I/O访问(CAM模式):使用CONFIG_ ADDRESS(0xCF8)、CONFIG_ DATA(0xCFC)寄存器进行访问,x86一般在BIOS阶段进行枚举和地址分配;
- ARM MMIO访问(ECAM模式): IO端口只能访问256(2^6)字节的配置空间,PCIe的配置空间扩展到4K,IO端口的方法无法访问到扩展的配置空间,所以使用一段MMIO空间(一般为256MB(256bus * 32dev * 8func * 4k)空间给ECAM机)用来访问配置空间,大小256M(256*256*4096),ARM一般在Linux内核进行枚举和地址分配。
CONFIG _ ADDRESS(0xCF8)寄存器定义
ECAM空间地址定义
- 配置空间枚举过程
枚举的意义:
- 树形结构的连接线分配总线号;
- 对PCIe Device 和 Bridge 分配BDF (Bus: Device. Function);
- 为PCIe bridge分配primary、secondary、subordinate bus number。
枚举的过程:
- 首先,以BDF=0:0.0 读取设备A的配置空间寄存器vendor ID和device ID(软件通过配置空间读取得方式判断PCIe设备是否存在);
- 如果设备A的Vendor ID和device ID有效,继续读设备A的配置空间寄存器header type;判断设备C是Bridge还是endpoint,该示例为桥设备,桥设备则初始化设备A配置空间寄存器Primary bus=0,Secondary bus=1,Subordinate bus=255(注意Subordinate bus 后面会修改为正确值);
- 以BDF=1:0.0 读取设备C的配置空间寄存器 vendor ID和device ID;
- 设备C的vendor ID和device ID有效,继续读设备C的配置空间寄存器header type,判断设备C是桥设备还是endpoint,该示例为桥设备,桥设备则初始化设备C配置空间寄存器Primary bus=1,Secondary bus=2,Subordinate bus=255;
- 以BDF=2:0.0 读取设备D的配置空间寄存器vendor ID和device ID;
- 设备D的vendor ID和device ID有效,继续读设备D的配置空间寄存器header type,判断设备D是桥设备还是endpoint,该示例为桥设备,桥设备则初始化设备D配置空间寄存器Primary bus=2,Secondary bus=3,Subordinate bus=255;
- 以BDF=3:0.0 读取设备的配置空间寄存器vendor ID和device ID,设备的vendor ID和device ID有效,继续读设备的配置空间寄存器header type,判断设备是桥设备还是endpoint,该示例为endpoint,继续读设备的配置空间判断是single-function设备还是multi-function设备;
- 编号7中的设备为multi-function,然后以BDF=3:0.1 读取设备的配置空间寄存器vendor ID和device ID,设备的vendor ID和device ID有效,然后做一些初始化操作;
- Bus 3 的设备遍历结束之后,发现桥设备D下最大的bus number为3,则将设备D的配置空间寄存器Subordinate bus=3;
- Bus3遍历结束后,回到Bus 2,以BDF=2:1.0 读取设备E,和步骤5类似;
- 步骤11和步骤6类似,步骤12和步骤7类似,步骤13&14&15和步骤9类似。
- BAR寄存器初始化
向BAR寄存器写入0xFFFF_FFFF,如果读出是0xFFF0_0000,BAR的[19:0]写不进数据,说明BAR需要的Size是1M,此时:
BAR初始化为0x0000_0000,则占用PCIe域0x0000_0000~0x000F_FFFF的1M空间;
BAR初始化为0x0010_0000,则占用PCIe域0x0010_0000~0x001F_FFFF的1M空间;
可见初始化的BAR地址要与BAR Size整数倍对齐。
- 地址映射
使用inbound/outbound
如果仅需RC访问EP的MEM(包括读写/DMA),则需要配置RC的outbound+EP的inbound
如果仅需EP访问RC的DDR(包括读写/DMA),则需要配置RC的inbound+RC的outbound
- 数据传输
RC和EP访问映射过后的CPU域地址即可,访问指令会被PCIe IP转换成TLP包在PCI域进行传输,TLP传输时的地址是PCI域的地址,在RC端和EP端都会进行地址映射。
三、协议(TLP包传输)
1、TLP结构
TLP Header基本结构