汇编学习笔记(27)

https://zhuanlan.zhihu.com/p/26244141
PCI的拓扑结构和枚举过程

https://www.sohu.com/a/300238384_505795
首先我们来看一下在x86系统中,PCIe是什么样的一个体系架构。下图是一个PCIe的拓扑结构示例,PCIe协议支持256个Bus, 每条Bus最多支持32个Device,每个Device最多支持8个Function,所以由BDF(Bus,device,function)构成了每个PCIe设备节点的身份证号。

 


PCIe体系架构一般由root complex,switch,endpoint等类型的PCIe设备组成,在root complex和switch中通常会有一些embeded endpoint(这种设备对外不出PCIe接口)。这么多的设备,CPU启动后要怎么去找到并认出它们呢? Host对PCIe设备扫描是采用了深度优先算法,其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。我们一般称这个过程为PCIe设备枚举。枚举过程中host通过配置读事物包来获取下游设备的信息,通过配置写事物包对下游设备进行设置。

第一步,PCI Host主桥扫描Bus 0上的设备(在一个处理器系统中,一般将Root complex中与Host Bridge相连接的PCI总线命名为PCI Bus 0),系统首先会忽略Bus 0上的embedded EP等不会挂接PCI桥的设备,主桥发现Bridge 1后,将Bridge1 下面的PCI Bus定为 Bus 1,系统将初始化Bridge 1的配置空间,并将该桥的Primary Bus Number 和 Secondary Bus Number寄存器分别设置成0和1,以表明Bridge1 的上游总线是0,下游总线是1,由于还无法确定Bridge1下挂载设备的具体情况,系统先暂时将Subordinate Bus Number设为0xFF。


PCIe的配置
  每个PCI设备根据插入的物理位置的不同会得到一个 BUS Device Function(BDF)的编号,用来唯一定位这个设备
  每个PCI设备都会有一个配置空间,
  可以通过IO空间的的两个寄存器来访问指定设备的配置空间
    CF8h: CONFIG_ADDRESS ; PCI配置空间地址端口(BDF)
        31 位:Enabled位。
        23:16 位:总线编号。
        15:11 位:设备编号。
        10: 8 位:功能编号。
        7: 2 位:配置空间寄存器编号。
        1: 0 位:恒为“00”。这是因为CF8h、CFCh端口是32位端口。
    CFCh: CONFIG_DATA
  PCIe规定这个配置空间的大小是4K, 所以上面的方式只能访问255b的数据,于是还有内存映射的方式
  PCI规定 一套系统最多支持255个Bus,每个Bus最多32个Devices,每个Devices最多支持8个Function,配置空间最大是256MB,当然实际肯定是用不了这么多的。
  系统采用 MMIO就是将这个空间映射到物理地址的方式实现访问,具体映射的空间,配置Root Comples(RC)寄存器中.

  配置空间的结构会根据设备的类型不同而有所区别,
  以非Bridge设备为例,其中包含了Device ID 和 Vendor ID,这两个ID需要向委员会申请,程序可以通过这两个ID配短处具体设备二选择对应的驱动程序。
  同时配置空间中也包含了他数据空间访问方式的配置,以及数据空间大大小
  比如bar的bit0 用于表示要映射到 IO空间还是内存空间
  而Base Address值表明数据映射的地址,Base Address会固定一些位为0并且只读,用于表示数据的大小。

  这样操作系统就可以通过
  1. RC寄存器知道配置空间 或 (CONFIG_ADDRESS / CONFIG_DATA) 找到配置空间。
  2. 配置 配置空间的内容来位数据区域映射 访问地址。
  3. 通过映射的访问地址操作硬件完成功能。

  同时PCI设备也是可以有中断线连接到 IO APIC的。

文献:
https://zhuanlan.zhihu.com/p/26244141
https://blog.csdn.net/jiangwei0512/article/details/51603525
https://zhuanlan.zhihu.com/p/36423152

原文地址:https://www.cnblogs.com/alwaysking/p/14530100.html