一、功能的唯一标识——BDF
首先我们简单回顾一下总线(Bus)、设备(Device)、功能(Function)这几个概念:
- 功能(function):是PCI设备中独立的功能单元,最多可以有8个功能。
- 设备(device):是物理设备,连接在PCI总线上,可能包含一个或多个功能。
- 总线(bus):是设备和系统通信的通道,一个系统可以有多个总线,每个总线最多可以有32个设备。
他们的包含关系是总线上可以挂在多个设备,单个设备最多支持8个功能,而功能(Function)就是我们配置的对象。那在一个PCIe的系统中,就会存在多个功功能,那配置的发起方如何识别正确的功能就是我们面临的第一个问题。因此,每一个功能应该有一个自己的名字(唯一标识)。这个唯一的标识符一般被称为“BDF”。 所谓“BDF”,其实就是 Bus、Device 和 Function的缩写,用来表示这个Function属于哪一条总线,哪一个设备里的哪一个功能。
在BDF中,Bus Number占用8位,Device Number占用5位,Function Number占用3位。显然,PCIe总线最多支持256个子总线,每个子总线最多支持32个设备,每个设备最多支持8个功能。图 3-1 展示了一个 PCIe 拓扑结构,图中着重标识了示例系统中的Buses、Devices 和 Functions。
我们来看一下这个命名规则,PCIe总线采用的是一种深度优先(Depth First Search)的拓扑算法,且Bus0总是分配给Root Complex。Root中包含有集成的Endpoint和多个端口(Port),每个端口内部都有一个虚拟的PCI-to-PCI桥(P2P),并且这个桥也应有设备号和功能号。需要注意的是,每个设备必须要有功能0(Fun0),其他的7个功能(Fun1~Fun7)都是可选的。
二、配置地址空间(Configuration Address Space)
明确了怎么识别需要配置的对象,我们来看一下需要配置的区域是什么样的。
最早的PC要求用户通过设置开关和跳线来为每个插入的卡分配资源,常常导致内存、I/O和中断设置的冲突。后来引入的扩展ISA(EISA)和IBM PS2系统是最早实现即插即用架构的系统之一。在这些架构中,每个插入卡片都附带配置文件,使系统软件能够分配基本资源。PCI进一步扩展了这一功能,通过实现标准化的配置寄存器,使得通用操作系统能够管理几乎所有系统资源。通过标准化的方式实现错误报告、中断传递、地址映射等功能,一个配置软件实体就可以分配和配置系统资源,从而几乎消除了资源冲突的可能性。
PCI为每个功能(Function)定义了一块专用的配置地址空间。映射到配置空间的寄存器允许软件发现功能的存在、配置其正常操作并检查其状态。大多数需要标准化的基本功能都在配置寄存器块的头部区域,但PCI架构设计者意识到,标准化一些可选功能(如电源管理、热插拔等)的能力结构(capability structures)将带来更多好处。PCI兼容的配置空间为每个功能分配了256字节的地址空间,用于实现这些功能。
2.1 PCI 兼容空间(PCI-Compatible Space)
如图 3-2 所示,PCI 兼容的配置空间被命名为256字节,因为它最初是为 PCI 设计的。在这 256 字节的配置空间中,前 16 个双字(即 64 字节)构成了配置头部(Header Type 0 或 Header Type 1)。Type 0 头部是每个功能模块(Function)所必须的,除了桥接功能(bridge functions)使用 Type 1 头部外。其余的 48 个双字(后面的192字节)用于可选寄存器,包括 PCI 功能结构(capability structures)。
对于 PCIe 功能,一些功能结构是必需的。例如,PCIe 功能必须实现以下功能结构:
- PCI Express Capability
- Power Management(电源管理)
- MSI 、MSI-X
在这里我们暂时不关注Type 0 和Type 1的区别,我们需要知道的就是对于PCIe来说,其配置空间中前面的256 Bytes是可以和PCI协议兼容,其中的前64 字节构成了配置头部,其主要作用是为操作系统和配置软件提供一个标准化的方式来识别、配置和管理 PCI 或 PCIe 设备(这部分我们后续讨论)。后面的192 Bytes是PCI的capability structures字段,PCIe也需要利用这些字段实现一部分配置。
2.2 扩展配置空间(Extended Configuration Space)
随着PCIe的引入,原本用于PCI的256字节配置空间不再足够容纳所有新增加的能力结构,因此配置空间的大小从每个功能的256字节扩展到了4KB,这被称为扩展配置空间(Extended Configuration Space)。扩展后的960个双字区域只能通过增强配置机制(Enhanced Configuration Mechanism)访问,因此对于旧的PCI软件是不可见的。
扩展配置空间包含了PCIe的附加可选扩展能力寄存器(Extended Capability Registers),这些寄存器提供了PCIe功能所需的额外功能。例如,它可能包括高级错误报告(Advanced Error Reporting)、虚拟通道(Virtual Channel)、链路带宽通知(Link Bandwidth Notification)等高级功能,如图3-3中列出的部分功能(注意,这并不是完整列表)。
这个扩展配置空间允许PCIe设备支持更多的高级功能,同时保持与传统PCI设备的兼容性。因此,操作系统或驱动程序可以通过标准化的方式识别和利用这些扩展功能,进一步增强系统性能和可靠性。
三、配置的发起者
对于配置来说,有了被配置的对象,还需要有配置操作的发起者,根据规范,只有RC(Root Complex)被允许发起配置请求(Configuration Requests)。RC作为系统处理器的中介,将请求注入PCIe网络中,并将完成的响应返回给处理器。这种配置事务的发起权仅限于通过 RC 由处理器进行,目的是避免设备之间随意修改其他设备配置的混乱局面。
由于只有 RC 可以发起配置请求,因此这些请求只能沿着系统的下游方向传递,这意味着设备之间的点对点配置请求是不允许的。配置请求通过目标设备的ID进行路由,这个ID由设备在拓扑中的总线号(Bus Number)、设备号(Device Number)和功能号(Function Number, BDF)组成。这种严格的路由机制确保了系统的稳定性和一致性,避免了配置冲突。
四、小结
至此,我们基本了解了配置操作的主要参与者,被配置的对象是设备中的功能(Function),每个功能(Function)会有一个自己的唯一标识BDF。配置的发起者是总线与系统处理器的中介——RC。需要配置的配置地址空间里可以兼容PCI协议,此外对于PCIe做了一定的拓展。