目前流量控制从理论到实现大多基于多通道技术,本节也仅讨论基于多通道的流量控制的基本原理。目前几乎所有流量控制算法的核心都是根据接收端缓冲区的容量,向发送端提供反馈。流量控制针对端到端的数据传递,目前流行的流量控制方法共有两种,分别为Rate-Based机制和Credit-Based机制。......
2023-10-20
setup_arch函数将分别调用acpi_boot_table_init、early_acpi_boot_init和acpi_boot_init函数完成ACPI系统的初始化,这几个函数的源代码在./arch/x86/kernel/acpi/boot.c文件中。
acpi_boot_table_init函数调用acpi_table_init函数在内存中找到RSDP和RSDT/XSDT,从而定位ACPI表。BIOS在系统初始化时将ACPI表放到一块固定物理地址区域中;early_acpi_boot_init函数调用early_acpi_process_madt函数进一步处理MADT;而acpi_boot_init函数依次分析SBFT[14](Simple Boot Flag Table)、FADT和HPET(IA-PC High Precision Event Timer Ta-ble),其中HPET是Intel定义的一个高精度定时器。
setup_arch函数执行完毕后,Linux系统将调用do_initcalls函数执行与ACPI系统相关的一些模块,其中与PCI总线有关的模块有acpi_pci_init、acpi_pci_root_init和acpi_pci_link_init函数。这些函数的说明如下。
1.acpi_pci_init函数
acpi_pci_init函数的执行过程较为简单,该函数在./drivers/pci/pci-acpi.c文件中,如源代码14-19所示。
源代码14-19 acpi_pci_init函数
该函数首先分析“Boot Architecture Flags”字段,确定当前处理器系统是否需要使能MSI中断机制和PCIe设备的ASPM(Active State Power Management)机制,ASPM机制的详细描述见第8.3节,而MSI机制的详细说明见第10章。该函数调用register_acpi_bus_type函数,将acpi_pci_bus结构加入到全局链表bus_type_list,最后调用pci_set_platform_pm函数将全局变量pci_platform_pm赋值为acpi_pci_platform_pm。
2.acpi_pci_root_init函数
acpi_pci_root_init函数调用acpi_pci_root_add和acpi_pci_root_start函数遍历处理器系统中的PCI总线树。在Linux系统中,acpi_pci_root_init函数的调用关系较为复杂,本节仅介绍其调用过程,并不详细介绍其实现机制。
acpi_pci_root_init函数的调用过程如源代码14-20所示。
源代码14-20 acpi_pci_root_init函数的调用过程
acpi_pci_root_init->acpi_bus_register_driver->driver_register
->bus_add_driver->driver_attach->__driver_attach
->driver_probe_device->really_probe->(dev->bus->probe)
由以上过程可见acpi_pci_root_init函数将调用really_probe函数中的(dev->bus->probe)函数,而dev->bus->probe函数在acpi_device_register函数中被赋值为acpi_device_probe函数。(www.chuimin.cn)
acpi_device_probe函数又经过了一系列复杂的调用,最终调用acpi_pci_root_add和acpi_pci_root_start函数,其调用过程如源代码14-21所示。
源代码14-21 acpi_pci_root_init函数的调用过程
其中driver->ops.add函数与acpi_pci_root_add函数对应;而driver->ops.start函数与acpi_pci_root_start函数对应。acpi_pci_root_add函数在./drivers/acpi/pci_root.c文件中,该函数的主要功能是遍历PCI总线树,如源代码14-22~23和源代码14-31所示。
源代码14-22 acpi_pci_root_add函数片段1
这段代码通过ACPI表中的_SEG和_BBN参数获得HOST主桥使用的Segment和Bus号,创建一个acpi_pci_root结构,并对该结构进行初始化,随后将acpi_pci_root结构加入到acpi_pci_roots队列中。acpi_pci_root结构的主要功能是对当前HOST主桥控制器进行描述,而在acpi_pci_roots队列中包含当前x86处理器系统所有HOST主桥[15]的信息。
当x86处理器系统中只有一个HOST主桥时,acpi_pci_root_add函数仅会被Linux调用一次,此时acpi_pci_roots队列中只有一个数据成员,即root,其Segment和Bus号均为0;如果存在多个HOST主桥时,acpi_pci_root_add函数将在PCI总线初始化时被调用多次,并将所有主桥信息加入到acpi_pci_roots队列中。
这段代码还将HOST主桥的_OSC参数的PCI Segment Groups supported位设置为1,该参数在ACPI规范中定义,该位为1时表示当前处理器系统支持PCI Segment Group。
源代码14-23 acpi_pci_root_add函数片段2
在一个x86处理器系统中,如果没有使能ACPI机制,则Linux系统调用pci_legacy_init→pcibios_scan_root函数枚举PCI设备。如果Linux系统使能了ACPI机制,则由这段程序调用pci_acpi_scan_root函数完成PCI设备的枚举。pci_acpi_scan_root和pcibios_scan_root函数对PCI总线树的枚举过程类似。
pci_acpi_scan_root函数在./arch/x86/pci/acpi.c文件中,如源代码14-24所示。
源代码14-24 pci_acpi_scan_root函数
这段代码首先判断当前总线号是否已经存在,如果存在说明这条总线已经被遍历过,该函数将直接退出。否则将首先调用pci_create_bus函数,pci_create_bus函数的源代码在./drivers/pci/probe.c文件中,其主要作用是为当前HOST主桥创建pci_bus结构,并初始化这个pci_bus结构的部分参数如resource[0/1],secondary参数[16]等,然后将这个pci_bus结构加入到全局链表pci_root_buses中,最后进行一些与sysfs相关的初始化工作。
之后调用pci_scan_child_bus函数对当前PCI总线上的设备进行枚举,pci_scan_child_bus函数将完成对PCI总线树的枚举操作,该函数是Linux遍历PCI总线树的要点,下一节将专门介绍讨论该函数的实现机制。
有关PCI Express体系结构导读的文章
目前流量控制从理论到实现大多基于多通道技术,本节也仅讨论基于多通道的流量控制的基本原理。目前几乎所有流量控制算法的核心都是根据接收端缓冲区的容量,向发送端提供反馈。流量控制针对端到端的数据传递,目前流行的流量控制方法共有两种,分别为Rate-Based机制和Credit-Based机制。......
2023-10-20
PCI总线规定了两类数据传送方式,分别是Posted和Non-Posted数据传送方式。显然采用Posted传送方式,当这个Posted总线事务通过某条PCI总线后,就可以释放PCI总线的资源;而采用Non-Posted传送方式,PCI总线在没有结束当前总线事务时必须等待。而使用Non-Posted方式进行数据传送的处理过程与此不同,Non-Posted数据请求在通过PCI总线时,并不会及时释放总线资源,从而在某种程度上影响PCI总线的使用效率和传送带宽。......
2023-10-20
PCI总线定义了两类配置请求,一类是Type 00h配置请求,另一类是Type 01h配置请求。PCI总线使用这些配置请求访问PCI总线树上的设备配置空间,包括PCI桥和PCI Agent设备的配置空间。当x86处理器对CONFIG_DATA寄存器进行读写操作时,HOST主桥将决定向PCI总线发送Type 00h配置请求还是Type 01h配置请求。在PCI总线事务的地址周期中,这两种配置请求总线事务的不同反映在PCI总线的AD[31∶0]信号线上。......
2023-10-20
PCIe设备使用MSI机制时,通过向中断控制器发送MSI报文以提交中断请求。然而对于PCIe体系结构而言,这个MSI报文与普通的存储器写报文并没有本质的区别,这个报文也可以使用不同的TC。如果设备的数据传送使用TC0,而MSI报文使用TC1时,将可能引发数据完整性的问题。PCIe总线规范并没有约定如何处理传递MSI报文而产生的数据完整性问题。当该读操作结束后,即PCIe设备收到存储器读完成TLP后,再发送MSI报文。......
2023-10-20
本节重点讲述PCI桥如何将Type 01h配置请求转换为Type 00h配置请求。下面将举例说明PCI总线配置请求的转换原则,并以图2-8为例说明处理器如何访问PCI设备01和PCI设备31的配置空间。PCI总线规定Type01h配置请求只能由PCI桥负责处理。而1<Bus Number≤3,所以PCI桥1将接收来自PCI总线0的Type 01h配置请求,并将这个配置请求直接下推到PCI总线1。......
2023-10-20
PCI总线作为处理器系统的局部总线,其主要目的是为了连接外部设备,而不是作为处理器的系统总线连接Cache和主存储器。孤立地研究PCI总线并不可取,因为PCI总线仅是处理器系统的一个部分。深入理解PCI总线需要了解一些与处理器体系结构相关的知识。PCI规范并没有对HOST主桥的设计进行约束。PCI桥是PCI总线的一个重要组成部件,该部件的存在使得PCI总线极具扩展性。PCI总线提供的峰值带宽远高于这些总线。......
2023-10-20
下面以图3-2所示的处理器系统为例,说明处理器向PCI设备11进行存储器写的数据传送过程。PCI设备11在PCI总线域的地址范围是0x7300-0000~0x73FF-FFFF。存储器域将0xF300-0008这个地址发向HOST主桥,0xF000-0000~0xF7FF-FFFF这段地址已经由HOST主桥映射到PCI总线域地址空间,所以HOST主桥认为这是一个对PCI设备的访问。PCI总线0的PCI桥1发现0x7300-0008在自己管理的地址范围内,于是接管这个存储器写请求,并通过总线仲裁逻辑获得PCI总线1的使用权,并将这个请求转发到PCI总线1上。......
2023-10-20
相关推荐