PCI总线树的枚举由pci_scan_child_bus函数完成,该函数的主要作用是分配PCI总线树的PCI总线号,而并不初始化PCI设备使用的BAR空间。subordinate总线号记载当前PCI总线树中最后一个PCI总线号,因此只有完成了对PCI总线树的枚举后,才能获得该参数。值得注意的是,在Linux系统中,许多PCIe设备并没有提供该结构。PCI总线规范规定了获取BAR空间的标准实现方法。......
2023-10-20
本篇主要讲述Linux系统与PCI/PCIe总线相关的一些内容,其重点在于Linux系统PCI/PCIe总线驱动程序的实现。并以此为基础说明PCI总线控制器及其相关设备在系统软件的初始化过程。本篇并不会拘泥于Linux系统的实现细节,但是仍将介绍一些与Linux系统相关的基本知识。本篇内容基于Linux 2.6.31.6内核。
值得注意的是,在不同处理器体系结构中,Linux系统初始化PCI总线的过程并不相同。如在Linux x86系统中,BIOS为PCI总线的初始化做出了许多辅助工作,而在Linux PowerPC或者Linux ARM中使用的Firmware,如U-Boot,并没有做类似的工作。
从系统软件的角度来看,PCI总线与PCIe总线的初始化过程和资源分配较为类似,为节约篇幅,本篇将PCI和PCIe总线统称为PCI总线,并将Linux系统的PCI和PCIe子系统简称为Linux PCI。
在第12.3节中讲述了一个最基本的、基于PCI总线的Linux设备驱动程序。这个PCI设备驱动程序使用了一些Linux系统提供的标准API和数据结构,例如使用pci_re source_start和pci_resource_len函数获得该设备BAR空间的基地址和长度,并在request_irq函数中使用pci_dev→irq参数注册该设备使用的中断服务例程。
该PCI设备(Capric卡)在驱动程序中使用的这些存储器资源,由系统软件对PCI总线进行初始化时确定,而中断资源在使能相应的PCI设备时由系统软件分配。这个系统软件包括操作系统和Firmware[1]。
与其他处理器系统相比,x86处理器作为一个通用处理器平台,始终强调向前兼容的重要性。而实现向前兼容需要做出许多牺牲,这也造成了Linux x86对PCI总线的初始化过程最为复杂也最为繁琐,x86处理器在引入了ACPI(Advanced Configuration and Power Interface Specification)机制之后,方便了处理器系统对“不规范外部设备”的管理,但是使得PCI总线的初始化过程更为复杂。(www.chuimin.cn)
下文将以Linux x86为主线说明PCI总线的初始化过程。Linux x86在对PCI总线进行初始化之前,BIOS对PCI总线做出了部分初始化工作,如创建ACPI表、预先分配PCI设备使用的存储器资源,并执行PCI设备ROM中的初始化代码等一系列步骤。
Linux x86将继承BIOS对PCI总线的初始化成果,并在此基础上进行Linux PCI子系统的初始化,并执行PCI设备的Linux驱动程序的初始化模块。在Linux x86中,PCI总线的初始化由一系列模块协调完成。
Linux x86首先使用“make menuconfig”命令对内核进行必要的配置,然后产生.config文件。假定在.config文件中,CONFIG_PCI、CONFIG_PCI_MSI、CONFIG_PCI_GOANY、CONFIG_PCI_BIOS、CONFIG_PCI_DIRECT、CONFIG_PCI_MMCONFIG等一些必要的参数为“y”,即使能PCI总线驱动、使能MSI中断请求机制等,而且对x86处理器非常重要的CON-FIG_ACPI参数也为“y”。
在Linux PCI中,有两个常用的数据结构,分别为pci_dev和pci_bus结构。这两个数据结构的定义在./include/linux/pci.h文件中。其中pci_dev结构描述PCI设备,包括这个PCI设备的配置寄存器信息,使用的中断资源,还有一些和SR-IOV相关的参数。而pci_bus结构描述PCI桥,包括这个PCI桥的配置寄存器信息和一些状态信息。该结构中self参数值得注意,pci_bus→self指向一个pci_dev结构,该结构用于PCI桥的上游总线访问PCI桥,此时PCI桥被当作一个设备。
有关PCI Express体系结构导读的文章
PCI总线树的枚举由pci_scan_child_bus函数完成,该函数的主要作用是分配PCI总线树的PCI总线号,而并不初始化PCI设备使用的BAR空间。subordinate总线号记载当前PCI总线树中最后一个PCI总线号,因此只有完成了对PCI总线树的枚举后,才能获得该参数。值得注意的是,在Linux系统中,许多PCIe设备并没有提供该结构。PCI总线规范规定了获取BAR空间的标准实现方法。......
2023-10-20
表11-4 PCI桥使用的数据访问顺序1.Posted存储器写通过PCI桥时需要按序完成Posted存储器写通过PCI桥时需要遵循“先进先出”的原则,否则将会引发数据完整性问题。......
2023-10-20
PCI总线是由Intel公司提出的。PCI总线不是由ANSI通过的标准,但由于它是由厂家自发制定执行的标准,具有众多的优点,拥护者,执行者众多,成了事实上的标准。PCI总线共有100个引脚,如果只作为目标设备,至少需要47条,如作为主设备则需要49条。本设计使用位命令字,其定义如下:3.PCI总线基本协议PCI上的基本总线传输机制是突发成组传输。......
2023-11-22
图2-14 PCI总线设备号的分配PCI总线推荐了一种Device Number字段与AD[31∶16]之间的映射关系。其中PCI设备0与Device Number字段的0b00000对应;PCI设备1与Device Number字段的0b00001对应,并以此类推,PCI设备15与De vice Number字段的0b01111对应。在一个处理器系统的设计中,如果在一条PCI总线上使用的PCI插槽少于4个时,笔者建议优先使用AD[17∶20]信号与PCI设备的IDSEL信号连接。......
2023-10-20
PCI总线规范定义了一系列与Cache相关的总线事务,以提高PCI设备与主存储器进行数据交换的效率,即DMA读写的效率。PCI设备与主存储器进行的Cache共享一致性增加了HOST主桥的设计复杂度。在高性能处理器中Cache状态机的转换模型十分复杂。因为Cache一致性操作不仅与HOST主桥的设计相关,而且主要与处理器和Cache Memory系统设计密切相关。因为x86处理器重点优化的是PCIe设备,目前x86处理器使用的IOAT技术,显著提高了PCIe设备与主存储器进行数据通信的效率。......
2023-10-20
假设在一个32位处理器中,存储器域的0xF000-0000~0xF7FF-FFFF这段物理地址空间与PCI总线的地址空间存在映射关系。图3-1 存储器域与PCI总线域的映射关系当PCI设备使用DMA机制访问存储器域地址空间时,处理器系统同样需要将存储器域的地址空间反向映射到PCI总线地址空间。本章采用图3-1的映射关系,虽然增加了映射复杂度,却便于读者深入理解存储器域到PCI总线域之间的映射关系。......
2023-10-20
本章主要讲述在PCI/PCIe总线中,数据传送的“序”与可能出现的死锁。在PCI/PCIe总线中,序与生产/消费者模型密切相关。生产/消费者模型是一种并发协作模型,PCI/PCIe设备使用该模型进行数据传递。在PCI/PCIe总线中,访问“序”的安排必须保证生产/消费者模型的正确运转,这也意味着在PCI/PCIe总线中,数据的传送规则需要与生产/消费者模型一致。而PCI/PCIe总线针对的就是这样的一个通用处理器系统。本章将在第11.3节介绍PCI总线的序,并在第11.4节详细介绍PCIe总线的序。......
2023-10-20
PCI桥的引入使PCI总线极具扩展性,也极大地增加了PCI总线的复杂度。如图2-8所示,PCI桥1的上游总线为PCI总线x0,而PCI桥1的下游总线为PCI总线x1。这两条总线间的数据通信需要通过PCI桥1。如PCI设备21与PCI设备22之间的数据通信仅占用PCI总线x2的带宽,而不会影响PCI总线x0、x1与x3,这也是引入PCI桥的一个重要原因。许多处理器系统使用的PCI设备较少,因而并不需要使用PCI桥。即便如此读者也需要深入理解PCI桥的知识。......
2023-10-20
相关推荐