接前一篇文章:《PCI Express体系结构导读》随记 —— 第I篇 第2章 PCI总线的桥与配置(11)
PCI设备都有独立的配置空间,HOST主桥通过配置读写总线事务访问这段空间。PCI总线规定了三种类型的PCI配置空间,分别是PCI Agent设备使用的配置空间,PCI桥使用的配置空间和Cardbus桥片使用的配置空间。
本节重点介绍PCI Agent和PCI桥使用的配置空间,而并不介绍Cardbus桥片使用的配置空间。值得注意的是,在PCI设备配置空间中出现的地址都是PCI总线地址,属于PCI总线。
2.3.2 PCI Agent设备的配置空间
在一个具体的处理器应用中,PCI设备通常将PCI配置信息存放在E2PRROM中。PCI设备进行上电初始化时,将E2PROM的信息读取到PCI设备的配置空间中作为初始值。这个过程由硬件逻辑完成,绝大多数PCI设备使用这种方式初始化其配置空间。
读者可能会对这种机制产生一个疑问,如果系统软件在PCI设备将E2PROM中的信息读到配置空间之前就开始操作配置空间,会不会带来问题?因为此时PCI设备的初始值并不“正确”,仅仅是PCI设备使用的复位值。读者的这种担心是多余的,因为PCI设备在配置寄存器没有初始化完毕之前,即E2PROM中的内容没有导入PCI设备的配置空间之前,可以使用PCI总线规定的“Retry”周期,使HOST主桥在合适的时机重新发起配置读写请求。
在x86处理器中,系统软件使用CONFIG_ADDR和CONFIG_DATA寄存器,读取PCI设备配置空间的这些初始化信息,然后根据处理器系统的实际情况使用DFS(深度优先搜索)算法,初始化处理器系统中所有PCI设备的配置空间。
在PCI Agent设备的配置空间中包含了许多寄存器,这些寄存器决定了该设备在PCI总线中的使用方法,本节不会全部介绍这些寄存器,因为系统软件只对部分配置寄存器感兴趣。PCI Agent设备使用的配置空间如图2-9所示:
在PCI Agent设备的配置空间中包含的寄存器如下所示:
(1)Device ID和Vendor ID寄存器
这两个寄存器的值由PCISIG分配,只读。其中,Vendor ID代表PCI设备的生产厂商,而Device ID代表这个厂商所生产的具体设备。如Intel公司的基于82571EB芯片的系列网卡,其Vendor ID为0x8086(PCI SIG分配给Intel的Vendor ID号为0x8086,8086处理器也是Intel设计的第一个PC处理器),而Device ID为0x105E(这仅是Intel为82571的Copper口分配的Vendor ID)。
其中,0x8086代表Intel,0x105E代表82571EB网卡芯片。Intel将0x10xx作为LAN设备的Device ID。Intel在PCISIG上注册了多如牛毛的Device ID(这些Device ID放在一起,几页纸也列不完)。不过16位的Device ID即便对于Intel这样的大公司,也基本没有用完的可能。当Vendor ID寄存器为0xFFFF时,表示无效Vendor ID。
(2)Revision ID和Class Code寄存器
这两个寄存器只读。Revision ID寄存器记载PCI设备的版本号。该寄存器可以被认为是Device ID寄存器的扩展。
而Class Code寄存器记载PCI设备的分类,该寄存器由三个字段组成,分别是Base Class Code、Sub Class Code和Interface。其中,Base Class Code将PCI设备分类为显卡、网卡、PCI桥等设备;Sub Class Code对这些设备进一步细分;而Interface定义编程接口。Class Code寄存器棵供系统软件识别当前PCI设备的分类。
除此之外,硬件逻辑设计也需要使用该寄存器识别不同的设备。当Base Class Code寄存器为0x06,Sub Class Code寄存器位0x04时,如果Interface寄存器为0x00,则表示当前PCI设备为一个标准的PCI桥;如果Interface寄存器为0x01,则表示当前PCI设备为一个使用“负向译码”的PCI桥。
硬件逻辑需要根据这些寄存器判断当前PCI桥的使用方式。许多PCI桥既可以支持“正向”译码,也可以支持“负向”译码,系统软件必须合理设置Class Code寄存器。
PCI Agent设备配置空间中包含的其余寄存器请看下回。