系统软件使用DFS算法对PCI总线进行遍历时,完成这些寄存器的初始化,即分配这些设备在PCI总线域的地址空间。值得注意的是,PCI Agent设备的BAR0~5寄存器和PCI桥的Base寄存器保存的地址都是PCI总线地址。而这些地址在处理器系统的存储器域中具有映像,如果一个PCI设备的BAR空间在存储器域中没有映像,处理器将不能访问该PCI设备的BAR空间。......
2023-10-20
当acpi_pci_link_init函数执行完毕后,Linux PCI开始执行pci_subsys_init函数。在第14.1.3节曾简要介绍了该函数的实现,该函数如源代码14-9所示。
当一个处理器系统使能了ACPI机制,pci_subsys_init函数的执行路径将会发生变化。该函数将首先执行pci_acpi_init函数,并跳过pci_legacy_init和pcibios_irq_init函数之后,执行pcibios_init函数。pci_acpi_init函数的实现较为简单,其源代码在./arch/x86/pci/acpi.c文件中,如源代码14-33所示。
源代码14-33 pci_acpi_init函数
该函数首先调用acpi_irq_penalty_init函数更新acpi_irq_penalty表,该函数与Linux系统使用的IRQ Balance技术相关,对此感兴趣的读者可以从http://www.irqbalance.org网站获得更多的信息,本书并不关心这部分内容。
这段程序将pcibios_scanned参数置1,并将pcibios_enable_irq和pcibios_disable_irq参数初始化为acpi_pci_irq_enable和acpi_pci_irq_disable。这也是Linux系统使能ACPI机制后,Linux PCI并不执行pci_legacy_init[20]和p cibios_irq_init[21]函数的原因。最后这段程序使用acpi_pci_irq_enable函数为当前PCI总线树上的所有PCI设备分配irq号。
如果当前处理器系统使能了ACPI机制,pci_acpi_init函数执行后,pci_subsys_init函数将执行pcibios_init函数。pcibios_init→pcibios_resource_survey函数将检查当前处理器系统的所有PCI设备的BAR空间,该函数并不会操作PCI设备的BAR寄存器,而只是检查当前处理器系统中所有PCI设备的pci_dev→resource参数是否合法。
由第14.3.2节所示,pci_scan_slot函数己经将pci_dev→resource参数进行基本的初始化工作,但是对于不同的处理器系统,resource→start参数的值并不一定有效。
pcibios_resource_survey函数在./arch/x86/pci/i386.c文件中,如源代码14-34所示。
源代码14-34 pcibios_resource_survey函数
在Linux x86中,所有PCI总线树的根节点使用一个双向链表连接在一起,pci_root_buses指向这个链表的起始地址。pcibios_allocate_bus_resources函数使用DFS算法检查并分配PCI总线树中的所有PCI桥使用的系统资源,函数的源代码在./arch/x86/pci/i386.c文件中,如源代码14-35所示。
源代码14-35 pcibios_allocate_bus_resources函数(www.chuimin.cn)
pcibios_allocate_bus_resources函数首先遍历链表pci_root_buses中的所有pci_bus结构,之后调用pci_claim_resource→pci_find_parent_resource函数对pci_bus结构进行检查。pci_find_parent_resource函数在./driver/pci/pci.c文件中,如源代码14-36所示,该函数成功返回时,将获得当前PCI桥的上游PCI桥使用的resource参数。
源代码14-36 pci_find_parent_resource函数
pci_find_parent_resource首先对PCI桥管理的地址空间进行检查。如图3-2所示,每一个PCI桥都管理一段PCI总线地址空间,而且这段地址空间必须隶属于上游PCI桥管理的地址空间,其中PCI桥2管理的地址空间隶属于PCI桥1,而PCI桥1管理的地址空间隶属于HOST主桥,而且这些地址空间的类型需要一致。
之后这段代码检查上下游PCI桥的预读设置位,PCI总线规定下游设备“不可预读空间”不能使用PCI桥的“可预读空间”;而下游设备“可预读空间”可以使用PCI桥的“不可预读空间”和“可预读空间”,下游设备的“可预读空间”优先使用PCI桥的“可预读空间”。
当完成这些检查后pcibios_allocate_bus_resources→request_resource函数将从上游PCI桥管理的地址空间中为当前PCI桥分配地址空间,如果该函数返回失败,则将r→flags参数置0,标记资源没有被正确分配,这种情况可能是因为BIOS的bug,也可能因为其他原因。之后pcibios_allocate_bus_resources函数将递归调用pcibios_allocate_bus_resources函数遍历其下游的PCI总线树。
我们再次回到pcibios_resource_survey函数,发现该函数分别使用两个不同的入口参数0和1调用了pcibios_allocate_resources函数。当入口参数为0时,pcibios_allocate_resources函数为“在BIOS中已经启用了PCI设备”优先分配资源;当入口参数为1时,该函数为其他PCI设备分配资源。
该函数的实现较为简单,其主要过程依然是调用pci_find_parent_resource函数获得上游PCI桥管理的资源,并使用request_resource函数为当前PCI设备分配地址空间。值得注意的是,当入口参数为0时,pcibios_resource_survey函数将暂时禁止PCI设备的ROM空间,ROM空间的初始化将在下文介绍。
pcibios_init函数主要操作Linux系统中的数据结构,并没有对PCI设备的BAR寄存器进行读写操作。在x86处理器系统中,BIOS会枚举PCI总线树,并初始化PCI设备的BAR寄存器;但是在其他处理器系统中,Firmware可能并没有做出这些操作,为此Linux系统将继续遍历PCI总线树,并初始化这些PCI设备的BAR寄存器。
有关PCI Express体系结构导读的文章
系统软件使用DFS算法对PCI总线进行遍历时,完成这些寄存器的初始化,即分配这些设备在PCI总线域的地址空间。值得注意的是,PCI Agent设备的BAR0~5寄存器和PCI桥的Base寄存器保存的地址都是PCI总线地址。而这些地址在处理器系统的存储器域中具有映像,如果一个PCI设备的BAR空间在存储器域中没有映像,处理器将不能访问该PCI设备的BAR空间。......
2023-10-20
Linux PCI采用这种方式,可以保证PCI设备BAR寄存器初始化是从上游PCI总线到下游PCI总线,而PCI桥Base、Limit寄存器的初始化是从下游PCI总线到上游PCI总线。目前Linux系统使用从上游总线到下游总线的方法初始化PCI设备的BAR寄存器。pbus_assign_resources_sorted函数负责分配“未初始化PCI设备的BAR寄存器”,该函数将对这些PCI设备的BAR寄存器进行写操作。......
2023-10-20
TOLUD~4GB这段PCI总线地址空间主要映射和ICH相连的PCI设备地址空间,此外还包括EPBAR指向的空间,以及MCHBAR和DMIBAR指向的空间等。FSB Interrupts存储器空间与MSI中断机制相关,PCIe设备向这段存储器空间进行写操作时,MCH将这个写操作转换为FSB总线的Interrupt Message总线事务。DMI Interface负向译码空间被分为若干段,用来映射ICH使用的PCI总线地址空间。这些PCI设备的BAR空间被映射到这段空间。由以上说明可以发现与MCH连接的PCIe设备的访问延时小于与ICH连接中的PCIe设备。......
2023-10-20
下面以图3-2所示的处理器系统为例,说明PCI设备11向存储器进行DMA写的数据传送过程。本节不介绍PCI设备进行DMA读的过程,而将这部分内容留给读者分析。假定PCI设备11需要将一组数据发送到0x1000-0000~0x1000-FFFF这段存储器域的地址空间中。这个DMA写具体的操作流程如下。PCI设备11将数据发送到PCI设备42的第5、6步如下所示。......
2023-10-20
Capric卡仅使用BAR0空间,其大小为256B,在该空间中包含以下寄存器,这些寄存器使用小端编码方式,如表12-1所示。表12-1 Capric卡的BAR空间寄存器DCSR1寄存器,该寄存器由7个有效位组成。该寄存器的复位值为0,由32位组成,但是只有最低11位有效,因此Capric卡一次DMA读传送的最大值为0x7FF。当Capric卡的DMA读操作完成后,而且DCSR1寄存器的int_rd_enb位为1时,该位为1表示Capric卡已经向处理器提交了DMA读完成中断请求。......
2023-10-20
如果PCI设备访问的地址在某个CPU的Cache行中命中时,可能会出现三种情况。Cache行状态为S时的处理情况与状态为E时的处理情况大同小异,PCI设备在进行写操作时也将数据直接写入主存储器,并使无效状态为S的Cache行。此时CPU对FSB总线监听时,不能简单将当前Cache行使无效,因为这个使无效操作将丢失阴影部分的有效数据。随后CPU将状态位为M的Cache行与存储器进行同步后,再使无效这个Cache行。......
2023-10-20
而桥设备的主要作用是管理下游的PCI总线,并转发上下游总线之间的总线事务。PCI总线规范将PCI主从设备统称为PCI Agent设备。PCI规范也没有规定如何设计HOST主桥。在PCI总线中,还有一类特殊的设备,即桥设备。本书重点介绍PCI桥,而不介绍其他桥设备的实现原理。PCI桥的出现使得采用PCI总线进行大规模系统互连成为可能。其中对PCI设备配置空间的访问可以从上游总线转发到下游总线,而数据传送可以双方向进行。......
2023-10-20
(一)使用金属探测门进行人身检查的方法所有乘机旅客都必须通过安全门检查。对未报警的旅客,可使用手持金属探测器或手工人身检查的方法进行抽查。(二)使用手持金属探测器进行人身检查的方法手持金属探测器检查是通过金属探测器和手相结合的方法按规定程序对旅客人身实施检查。旅客取出物品后,人身检查员应对该报警部位进行复查,确认无误后,方可进行下一步检查。金属探测器连续不用超过180 s,设备将自动切断。......
2023-09-18
相关推荐