designware PCIE
1. PCIE RC 驱动流程
- 开启时钟,初始化PCIE PHY 的状态,打开训练状态,若是训练完成,和EP建立了链接, (在PCIe链路可以正常工作之前,需要对PCIe链路进行链路训练,在这个过程中,就会用LTSSM(Link Training and Status State Machine))LTSSM将会进入L0状态。
- 接下来可以对EP的配置空间进行访问(前置知识,你需要了解PCIE的配置空间,mem空间,io空间),以深度优先的方式开始进行不同的设备的枚举。(不同的PCIE的控制器有不同的配置空间访问的实现方法:1.在CPU地址空间中专门划分出来256MB的空间用作配置空间的访问。2.将EP设备的PCI总线地址配置特殊寄存器来指定要访问的设备。3.和1相似,但是不需要256MB的地址空间,实现方式是每次在访问EP设备的配置空间,都需要去改iATU的映射规则(前置知识,了解iATU是什么,地址映射是什么),这样可以将同样的CPU的地址映射到不同的PCI总线的地址)
- 读到配置和地址空间 (ssdfans.com)VID和DID不为0xFFFF,说明有设备,然后进行读取设备精确信息,配置设备在PCIE总线上的mem地址。
2. PCIE 写配置空间或者MEM的选择
原理是通过 TLP 包的 TYPE 来分辨不同的事务。
-
type = 0x00
Memory Read Request
mem的读写操作 -
type = 0x04
Configuration Type 0 Read Request
操作Endpoint的Configuration空间 -
type = 0x05
Configuration Type 1 Read Request
操作Switch的Configuration空间
实际程序里实现是通过写 IATU_REGION_CTRL_1_VIEWPORT_OFF_OUTBOUND_i(0x904) 寄存器的type来实现切换的
配置不同的region空间
-
通过配置iATU,将CPU的地址空间映射到PCI地址上去,以达到直接操作映射完成的CPU地址间接操作到PCI总线上的地址。像读写本地内存的方式去读写PCI的设备。
-
IATU_VIEWPORT_OFF (0x900)寄存器控制着region_dir 和 region_index. region_dir表示outbound或inbound,两个方向的地址翻译. region_index表示区域的序号(可以改变这个序号,来达到配置多个region目的).
新版本的地址转换有所不同
From 4.80 core version the address translation will be made by unroll
原理和上面类似,但是寄存器的位置有所改变,是从下面这些偏移地址去配置的
/* Register address builder */ #define PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(region) \ ((0x3 << 20) | ((region) << 9)) #define PCIE_GET_ATU_INB_UNR_REG_OFFSET(region) \ ((0x3 << 20) | ((region) << 9) | (0x1 << 8))