往期内容
本文章相关专栏往期内容,PCI/PCIe子系统专栏:
Uart子系统专栏:
- 专栏地址:Uart子系统
- Linux内核早期打印机制与RS485通信技术
– 末片,有专栏内容观看顺序interrupt子系统专栏:
- 专栏地址:interrupt子系统
- Linux 链式与层级中断控制器讲解:原理与驱动开发
– 末片,有专栏内容观看顺序pinctrl和gpio子系统专栏:
专栏地址:pinctrl和gpio子系统
编写虚拟的GPIO控制器的驱动程序:和pinctrl的交互使用
– 末片,有专栏内容观看顺序
input子系统专栏:
- 专栏地址:input子系统
- input角度:I2C触摸屏驱动分析和编写一个简单的I2C驱动程序
– 末片,有专栏内容观看顺序I2C子系统专栏:
- 专栏地址:IIC子系统
- 具体芯片的IIC控制器驱动程序分析:i2c-imx.c-CSDN博客
– 末篇,有专栏内容观看顺序总线和设备树专栏:
- 专栏地址:总线和设备树
- 设备树与 Linux 内核设备驱动模型的整合-CSDN博客
– 末篇,有专栏内容观看顺序
目录
1.PCI设备的访问方法_桥设备(type1)
参考文档:
1.1 PCI桥设备的地址空间
在上面讲过,对于一个PIC硬件设备的配置寄存器有256个字节,它分为64 byte的头标区(如上图中所示,固定不变),无论是桥设备还是普通的PCI设备,而其中的Header Typer就是分辨是设备的位置,如下
- 00h:PCI Agent,真正的PCI设备(比如网卡),是PCI树的最末端
- 01h:PCI Bridge,桥,用来扩展PCI设备,必定有一个Root Bridge,下面还可以有其他Bridge。
- 02h:Cardbus Bridge
下图是PCI Bridge设备的配置寄存器地址空间:
1.2 配置过程
1.2.1 怎么经过PCI Bridge去选择后面的PCI Agent
- 配置PCI桥
- 跟一般的PCI设备一样,通过IDSEL来选中它
- 通过type 0配置命令读取配置空间,发现它是PCI桥设备,把分配的总线号写给它
将bus 1写入桥设备配置空间中的Secondary Bus Number处,表示是总线1
- 配置桥后的PCI设备
主桥bus0发起一个type 1的配置命令
通过Bus Number访问到PCI桥
PCI桥根据Device Number去驱动IDSEL,选中下一级的PCI设备
将type1的命令转化为type0的命令,通过Function Number、Register Number访问PCI设备的配置空间
1.2.2 如果是经过两个PCI Bridge呢?
主桥发出的type1又是如何在两PCI bridge之间转发的?
- Primary Bus Number:上级桥的number
- Secondary Bus Number:本桥的number
- Subordinate Bus Number:下属桥的最大number
假设主桥发出了type1命令为:Bus Number为3,Device Number为31,Function Number为0~7,Register Number为0~255:
bus number = 3,会转发给所有接在PCI总线为0上的桥设备,进行搜索:
假设经过PCI桥片4,Secondary Bus Number为4,Subordinate Bus Number为4,3不在二者之间,可以知道想要搜索的桥不在该桥的下属桥中
假设经过PCI桥片2,Secondary Bus Number为1,Subordinate Bus Number为3,要搜索的桥在该桥设备的下属乔中,PCI桥片2进一步转化Type1命令给底下的桥设备(桥片)
接下来同理,轮到桥片2进行检测转发到给底下的桥设备
直到Secondary Bus Number = 3就说明找到了该桥设备,也就是PCI桥片3
接下来桥片3就会将Type1命令给转为type0,去配置PCI设备31
-
- 用AD31去选中PCI设备的IDSEL,但要注意的是,这里是Bus3的AD信号不是root bridge的AD信号,也不是其他Bus的AD信号,每个桥都有自己的AD信号,不同桥的AD信号并不联通
1.3 访问PCI设备
- CPU发出addr_cpu,被PCI Host桥转换为addr_pci
- 某个PCI设备发现这个addr_pci是自己的,就驱动DEVSEL#,表示说:是我是我
- PCI设备参与传输:接收数据、返回数据
1.4 问题
在上面有关配置设备中,都是提到了用AD31开始来选中一个设备,为什么不能是AD0呢?
比如type0命令:
在配置设备中,11–0是必不可少的,而31–11中这个因为是处理配置阶段,是不需要用到的,因此常用AD11来选中一个设备,AD10 – AD0则是要配置选中设备的不可缺少的内容
但现在很多配置中,经常用AD16来选中第一个设备,因为type1:
15–0都是选中设备有关的,找到某个桥后,再去找该桥下的某个设备,桥设备会将type1转为type0,我估计type0中的Reserved中的15-11存放的是该桥下的哪个设备,因此现在常用AD16-AD31来选中一个设备去进行配置
注意是PCI接口是并行连接的
2.从软件角度看PCIe设备的硬件结构
2.1 PCIe接口引脚
参考文件:01_pcie接口引脚电路示例_AX99100.pdf
PCI接口的引脚时并行的,PCIe的是串行的,每个方向的数据使用2条差分信号线来传输,发送/接收两个方向就需要4条线,这被称为1个Lane:
PCIe设备的接口上,可以有多个Lane:
- 两个PCIe设备之间有一个Link
- 一个Link中有1对或多对"发送/接收"引脚,每对"发送/接收"引脚被称为"Lane"
- 一个Lane:有发送、接收两个方向,每个方向用2条差分信号线,所以1个Lane有4条线
- 一个Link最多可以有32 Lane
PCIe(Peripheral Component Interconnect Express)是一种高速串行计算机扩展总线标准,它是PCI的改进版本,广泛用于连接显卡、网卡、固态硬盘等硬件设备。PCIe的主要特点是通过点对点串行通信,提供比传统PCI并行总线更高的传输速度和更好的扩展性。
PCIe接口的关键特点:
点对点通信:PCIe不再是共享的并行总线结构,而是采用点对点的串行连接,每个设备都有专用的通道(链路),可以避免总线争用,提高了总线的效率和带宽。
链路:PCIe链路由双向差分信号对组成,每对信号线用于数据的发送和接收。PCIe通道的带宽可以通过增加链路的数量来扩展,通常使用x1、x4、x8、x16等配置,x16为最高的配置,可以提供非常高的传输带宽。
分层协议:PCIe协议分为三层结构:
- 事务层:处理高层的通信请求,例如读写数据和设备管理。
- 数据链路层:负责数据的可靠传输,通过纠错机制确保数据的完整性。
- 物理层:负责传输数据的电信号,包括编码和信号传输。
高速传输:PCIe使用高速串行通信来实现大数据传输。随着PCIe版本的迭代,带宽显著提升,例如:
- PCIe 3.0:每条通道提供8 GT/s(Giga transfers per second)的传输速率,x16通道可以提供128 Gbps的带宽。
- PCIe 4.0:每条通道提供16 GT/s。
- PCIe 5.0:每条通道提供32 GT/s。
热插拔支持:PCIe支持设备的热插拔,即设备可以在系统运行时连接或断开,而不会影响其他设备的工作。
2.2 差分信号
差分信号(Differential Signaling)是一种传输信号的方式,用来减少电气干扰和噪声对信号的影响。在差分信号传输中,信号通过两根线来传输,一根线上发送原始信号,另一根线上发送这个信号的反相信号。接收端通过比较两根线的电压差来恢复原始信号。
差分信号的优点:
- 抗干扰能力强:由于两条信号线上的信号是相反的,外界的电磁干扰对两根线产生的影响几乎相同(共模干扰)。接收端通过检测电压差来恢复信号,而这种差值与共模噪声无关,因此差分信号的抗干扰能力很强。
- 信号完整性好:差分信号可以传输更高的频率和更远的距离,特别适合高速信号的传输。例如,PCIe使用差分信号来传输高速数据,有效提高了信号质量。
- 减少电磁辐射:由于两条信号线上的电流方向相反,它们产生的电磁场可以相互抵消,从而减少了电磁辐射。这在高速信号传输的场合非常重要,特别是在PCIe等高速接口中。
差分信号的应用:
差分信号被广泛用于高速接口和通信标准中,例如:
- PCIe:所有数据传输都基于差分对。
- USB:数据传输采用差分信号方式。
- 以太网(Ethernet):高速以太网接口中也采用差分信号来提高传输质量。
差分信号在PCIe中的作用
PCIe接口使用差分信号来实现高速和可靠的数据传输。每条链路由两对差分信号组成:
- 一对用于发送(Tx+ 和 Tx-),
- 一对用于接收(Rx+ 和 Rx-)。
通过差分信号,PCIe能够在高速情况下保持低噪声、高信号完整性,并降低信号传输过程中的电磁干扰。
总结来说,PCIe接口通过差分信号传输实现了高速、可靠的数据传输,这使得PCIe能够满足现代计算设备对大带宽和高性能的需求。
2.3 从软件角度理解硬件接口(三层)
PCIe地址的转换和前面提到的PCI地址的转化是相同的,不在地址转换后的数据传输上就有所差别。
既然PCIe是串行信号,那只能在"包"里传输地址、数据了。
- 需要定义包的格式:类型(Mem R/W) + 地址 + 数据
- 包怎么传递给对方、怎么确保不出错?有重传机制、有检验码
- 包怎么通过差分线传送出去?
在 PCIe(Peripheral Component Interconnect Express) 协议中,数据的传输是通过分层协议来实现的。PCIe协议栈分为三层,每一层有不同的职责,并在数据传输时不断进行封装。三层包括:
- PCIe协议的数据传输通过三层协议进行封装,每层有不同的格式与功能:
- 事务层(Transaction Layer)生成TLP(事务层数据包),包含具体的读写请求或消息。
- 数据链路层(Data Link Layer)封装DLLP(数据链路层数据包),并确保TLP的可靠传输。
- 物理层(Physical Layer)对TLP或DLLP进行编码和封装,通过差分信号传输物理层包。
整个数据封装和传输过程如下:
TLP → DLLP → PHY Layer Frame → 传输到目标设备
1. 事务层(Transaction Layer) — 下面有专点会详细讲解
事务层负责生成事务层数据包(TLP, Transaction Layer Packet),用于执行读写请求、消息传递等功能。
事务层的主要功能:
- 管理PCIe设备之间的读/写请求
- 管理内存映射(MMIO)和配置空间的访问
- 支持消息传递和中断
事务层数据包(TLP)格式:
TLP是事务层生成的核心数据包,用于读写或发送消息。
TLP格式一般包括以下字段:
Header(头部):32~96位,具体大小取决于TLP类型。头部包含:
- Type:标识TLP的类型(如Memory Read/Write、IO Read/Write等)
- Length:数据部分的长度
- Requester ID:发起TLP的设备ID
- Target ID:目标设备的ID
- Address:内存地址或I/O地址
- Tag:用于跟踪TLP事务的标签
Data:可选字段,长度可达4096字节,包含需要传输的实际数据。data/addr_pice
ECRC(可选):32位的纠错码(End-to-End CRC),用于检测数据包传输错误。
常见的TLP类型包括:
- Memory Read/Write:用于读取或写入系统内存。
- IO Read/Write:用于访问I/O地址空间(在现代系统中较少使用)。
- Configuration Read/Write:用于访问设备的配置空间。
- Message TLP:用于传输PCIe消息(如中断)。
TLP格式示例:
假设我们进行一次内存读取操作,TLP结构可能如下:
| TLP Header (Type=Memory Read) | Address | Data (optional) | ECRC (optional) |
2. 数据链路层(Data Link Layer)
数据链路层负责确保事务层的数据(TLP)能够可靠地在两个设备之间传输,并处理错误检测和数据包确认。链路层生成的**数据链路层数据包(DLLP, Data Link Layer Packet)**用于传输协议控制信息。
数据链路层的主要功能:
- 确保TLP正确传输,使用ACK/NAK机制来确认接收。
- 提供重传功能,确保数据可靠性。
- 管理链路状态、流控等功能。
DLLP数据包格式:
DLLP是链路层生成的数据包,主要用于传输协议控制信息。DLLP较小,一般只有几字节,主要用来传输以下内容:
- ACK/NAK:确认接收到的TLP是否正确传输。ACK表示成功接收,NAK表示需要重传。
- Flow Control(流控):用于管理链路上的数据流,防止缓冲区溢出。
DLLP包含以下字段:
- Type:表示DLLP类型(ACK、NAK、Flow Control等)。
- Sequence Number:用于追踪TLP的顺序,防止数据包乱序。
- Flow Control Info:告知发送方接收方的缓冲状态,以便控制数据传输速率。
DLLP较短,与TLP一起工作,确保数据传输的完整性和流控。
3. 物理层(Physical Layer)
物理层是最底层,负责将数据转换为电气信号并通过物理链路进行传输。物理层数据格式包括物理层包(Physical Packet, PHY Layer Packet),并通过差分信号进行传输。
物理层的主要功能:
- 将数据封装成物理帧(PHY Layer Frame)。
- 提供8b/10b或128b/130b的编码机制,增加数据冗余,以便更好地同步和检测错误。
- 进行信号的电气传输和接收。
物理层包(PHY Layer Packet)格式:
物理层包包含从上层传递下来的TLP或DLLP,进行编码并加上物理层包头,用于低层的传输。
物理层包封装过程:
- 数据包加前缀和后缀:物理层包加上前导码(Start-of-Packet,SOP)和结束符(End-of-Packet,EOP),以标识包的开始和结束。
- 编码:物理层对数据进行编码(例如8b/10b编码或128b/130b编码),以确保数据传输的同步性和纠错能力。
- 传输:通过PCIe的差分信号对进行电气传输。
物理层包示例:
| SOP | Encoded Data (TLP or DLLP) | EOP |
在PCIe 3.0及更高版本中,PCIe物理层使用128b/130b编码,该编码效率更高,减少了额外的开销。
2.4 PCIe系统的硬件框图
在PCI系统里,多个PCI设备都链接到相同总线上。
在PCIe系统里,是点对点传输的:
- 一条PCIe总线只能接一个PCIe设备
- 要接多个PCIe设备,必须使用Switch进行扩展