认识PCI设备,还是要从配置空间说起,当PCI在ACPI和PCI复合体上电和枚举完成后,PCI根复合体会从PCI设备读出PCI设备的配置空间,许多信息(例如寄存器、内存空间、中断信息等等)都是是从配置空间获取的,所以接下来会详细讲解PCI配置空间。
PCI配置空间的大小是256个字节(0x00~0xFF),而PCIe的配置空间扩大到了0x00~0xFFF;一般来说配置空间会像下面这样分区:
接下来尽可能详细的解释这部分配置:
type 0 Header
配置空间的截图如下:
这部分需要注意的是寄存器,status寄存器、command寄存器、BIST寄存器、Base Address Register0~5、ROM寄存器、INT寄存器、PMCSR寄存器,其它只读位的寄存器暂时不讨论。
status寄存器:
状态寄存器用于记录PCI总线相关事件的状态信息:
command寄存器:
命令寄存器提供对设备生成和响应PCI周期的能力的粗略控制。当0被写入该寄存器时,除了配置访问之外的所有访问,设备都从PCI总线上逻辑断开。所有设备都需要支持此基本功能级别。根据设备的功能,可以实现也可以不实现命令寄存器中的各个位:
BIST寄存器:
此可选寄存器用于BIST的控制和状态。不支持BIST的设备必须始终返回值0(即,将其视为保留寄存器)。调用BIST的设备不得妨碍PCI总线的正常操作。
Base Address Register0~5:
BAR寄存器比较特殊,它可能有多种形态:
和其他寄存器不一样,这个寄存器反而不建议去修改,虽然这个寄存器是可以读写的,但是往往只有系统知道如何正确的初始化,并且对于驱动来说,直到怎么使用这个寄存器比如何初始化它更重要。
一个经典的PCIe案例中,寄存器被分为三类,64位地址空间需要6个寄存器才能完全映射,如果仔细观察,就会发现寄存器和资源几乎一致:
第一个称之为基础寄存器空间,它往往用于初始化对应的PCI设备中的子系统以及烧录系统等特殊行为,在任何时候它都是可用的,一般它会被映射到I/O空间内;
第二个称之为设备寄存器空间,往往用于具体的PCIe的设备的功能设置,这部分可能大于4KB但是小于1MB;一般大小为4KB的倍数(这并不意外,低于4KB也会被设置为4KB的寄存器空间,因为内存页面的设置是以页面为单位的,寄存器设置也是如此),不过这部分需要总线驱动映射之后才可以用,在PCI设备中,一般会有一个嵌入式系统,这个系统初始化之前,是没办法映射设备寄存器和功能寄存器空间。
第三个也是功能寄存器空间,这里面可以映射的数量级更多一些;也是需要设备初始化之后才可以使用的。
ROM寄存器:
该寄存器被定义为处理该扩展ROM的基地址和大小信息。PCI设备可以带一个扩展ROM,通过执行ROM中存放的代码来完成与设备有关的初始化,同时也有可能完成系统的引导功能。
INT LINE寄存器
中断线路寄存器用于传输中断线路路由信息。寄存器必须由任何使用中断引脚的设备或设备功能来实现。POST软件将在初始化和配置系统时将路由信息写入该寄存器。
该寄存器中的值告诉设备的中断引脚连接到系统中断控制器的哪个输入。设备本身不使用该值,而是由设备驱动程序和操作系统使用。设备驱动程序和操作系统可以使用这些信息来确定优先级和矢量信息。此寄存器中的值是特定于系统体系结构的。
PMCSR寄存器
此16位寄存器用于管理PCI功能的电源管理状态以及启用/监视PME: