主要说明
Kernel版本:4.14ARM64处理器一、PCI概述
从本文开始,将会针对PCIe专题来展开,涉及的内容包括:
PCI/PCIe总线硬件;LinuxPCI驱动核心框架;LinuxPCIHost控制器驱动;
不排除会包含PCIe外设驱动模块,一切随缘。
作为专题的第一篇,其实会先从硬件总线入手。
步入主题前,先讲点背景知识。
在PC时代,随着处理器的发展,经历了几代I/O总线的发展,解决的问题都是CPU显存提高与外部设备访问速率的问题:
第一代总线包含ISA、EISA、VESA和MicroChannel等;第二代总线包含PCI、AGP、PCI-X等;第三代总线包含PCIe、mPCIe、m.2等;
PCIe(PCIExpress)是目前PC和嵌入式系统中最常用的高速总线,PCIe在PCI的基础上发展而至,在软件上PCIe与PCI是后向兼容的,PCI的系统软件可以用在PCIe系统中。
二、PCILocalBus2.1PCI总线组成
先来看一下PCILocalBus的系统构架图:
从图中看,与PCI总线相关的模块包括:
HostBridge,例如PC中常见的NorthBridge(南桥);
图中处理器、Cache、内存子系统通过HostBridge联接到PCI上,HostBridge管理PCI总线域,是联系处理器和PCI设备的桥梁,完成处理器与PCI设备间的数据交换。其中数据交换,包含处理器访问PCI设备的地址空间和PCI设备使用DMA机制访问寻址储器,在PCI设备用DMA访问储存器时,会存在Cache一致性问题,这个也是HostBridge设计时须要考虑的;
据悉,HostBridge还可选的支持仲裁机制,热拔插等;PCILocalBus;
PCI总线,由HostBridge或则PCI-to-PCIBridge管理,拿来联接各种设备,例如声卡、网卡、IDE插口等。可以通过PCI-to-PCIBridge来扩充PCI总线,并构成多级总线的总线树,例如图中的PCILocalBus#0和PCILocalBus#1两条PCI总线就构成一颗总线树,同属一个总线域;PCI-To-PCIBridge;
PCI桥,用于扩充PCI总线,使采用PCI总线进行大规模系统互联成为可能,管理下游总线,并转发上下游总线之间的事务;PCIDevice;
PCI总线中有三类设备:PCI从设备,PCI主设备,桥设备。
PCI从设备:被动接收来自HostBridge或则其他PCI设备的读写恳求;
PCI主设备:可以通过总线仲裁获得PCI总线的使用权,主动向其他PCI设备或寻址储器发起读写恳求;
桥设备:管理下游的PCI总线,并转发上下游总线之间的总线事务,包括PCI桥、PCI-to-ISA桥、PCI-to-Cardbus桥等。
2.2PCI总线讯号定义
PCI总线是一条共享总线,可以挂接多个PCI设备,PCI设备通过一系列讯号与PCI总线相连linux 串口驱动分析,包括:地址/数据讯号、接口控制讯号、仲裁讯号、中断讯号等。如右图:
看一下C/BE[3:0]都有什么命令吧:
2.3PCI事务模型
PCI使用三种模型用于数据的传输:
ProgrammedI/O:通过IO读写访问PCI设备空间;DMA:PIO的方法比较低效,DMA的方法可以直接去访问寻址储器而无需CPU干预,效率更高;Peer-to-peer:两台PCI设备之间直接传送数据;2.4PCI总线地址空间映射
PCI体系构架支持三种地址空间:
memory空间:
针对32bit主存,支持4G的地址空间,针对64bit主存,支持16EB的地址空间;I/O空间
PCI最大支持4G的IO空间,但受限于x86处理器的IO空间(16bits带宽),好多平台将PCI的IO地址空间限定在64KB;配置空间
x86CPU可以直接访问memory空间和I/O空间,而配置空间则不能直接访问;
每位PCI功能最多可以有256字节的配置空间;
PCI总线在进行配置的时侯,采用ID解调形式,使用设备的ID号,包括BusNumber红旗linux官网,DeviceNumber,FunctionNumber和RegisterNumber,每位系统支持256条总线,每条总线支持32个设备,每位设备支持8个功能,因为每位功能最多有256字节的配置空间,因而总的配置空间大小为:256B*8*32*256=16M;
有必要再进一步介绍一下配置空间:
x86CPU难以直接访问配置空间,通过IO映射的数据端口和地址端口间接访问PCI的配置空间,其中地址端口映射到0CF8h-0CFBh,数据端口映射到0CFCh-0CFFh;
CPU写CF8h端口,其中写的内容如图所示linux之家,BUS,Device,Function能标示出特定的设备功能,Doubleword来指定配置空间的具体某个寄存器;CPU可以IO读写CFCh端口,用于读取步骤1中的指定寄存器内容,或则写入指定寄存器内容。这个过程有点类似于通过I2C去配置外接芯片;
那具体的配置空间寄存器都是哪些样的呢?每位功能256Byte,后面64Byte是Header,剩余的192Byte支持可选功能。有种类型的PCI功能:Bridge和Device,二者的Header都不一样。
Device
配置空间中有个寄存器数组须要说明一下:BaseAddressRegister,也就是BAR空间,当PCI设备的配置空间被初始化后,该设备在PCI总线上都会拥有一个独立的PCI总线地址空间,这个空间就是BAR空间,BAR空间可以储存IO地址空间,也可以储存储存器地址空间。
三、PCIExpress3.1PCIe体系结构
先看一下PCIe构架的组成图:
前文提及过,PCIe在软件上保持了后向兼容性,这么在PCIe的设计上,须要考虑在PCI总线上的软件视角,例如RootComplex的实现可能就如右图所示,因而看上去与PCI总线相差无异:
而Switch的实现可能如右图所示:
3.2PCIe数据传输
PCIe规范定义了分层的构架设计,包含三层:
Transaction层
数据包的封装与解封装,与网路包的创建与解析很类似,如右图:
来一个更详尽的PCIe分层图:
3.3PCIe设备的配置空间
为了兼容PCI软件,PCIe保留了256Byte的配置空间,如右图:
据悉,在这个基础中将配置空间扩充到了4KB,还进行了功能的扩充linux 串口驱动分析,诸如Capability、PowerManagement、MSI中断等:
《PCIExpressTechnology3.0》
《pcilocalbusspecificationrevision3.0》
《PCIe体系结构导读》
《PCIExpress系统体系结构标准教材》