PCI的配置空间

PCI的配置空间

主要讨论如何去访问PCI配置空间和描述PCI设备的配置空间的定义和使用规则。理论上如何访问PCI配置空间的问题是属于总线操作的一部分,但是和配置空间有着密切联系,有必要一起讨论。

 

PCI的配置空间一共256 bytes大小,可以分成两个部分:头部和独立部分。这里主要讨论header部分的register。由于PCI的架构特性,PCI分为普通PCI设备和PCI桥。PCI桥也可以认为是一个pci设备,其配置空间的header部分稍微复杂一点。可以参阅PCI-PCI bridge spec来了解更多情况。

下图是pci架构的级联图。不同的bus就是通过Bridge来连接的。每个PCI bus上都可以挂载多个PCI设备,相同bus上的各个设备是以PCI device NO.来区分的。所以在逻辑上来讲,在PCI总线系统中的各个PCI设备都会有一个特定而唯一的逻辑地址---Bus_NO + Device_NO + Function_NO. 总线上的逻辑信号就译码每个设备的不同逻辑地址来找到对应的PCI设备,并访问其配置i空间。

 

由于PCI总线在开机之后任何时候都可以去访问,所以我们可以在POST阶段或者系统中随时可以依据设备的总线逻辑地址去访问该PCI设备,每个pci设备都会有个唯一对应的总线地址的,比如下图。

这个是在本人电脑上读到的EHCI对应的总线地址。BUSNO=0;DeviceNO=29;FunctionNO=0.所以如果要访问这个pci设备-EHCI的话,就要使用PCI配置空间访问函数中输入这个地址。当然如果要访问配置空间的某个register的话,那么输入的参数应该是(BusNO, DeviceNO, FunctionNo, Register)。

 

访问PCI配置空间的算法

理所当然,说到这里就必然涉及到如何去访问pci总线,其中的算法是怎样的呢?PCI协议中定义了一组IO端口CF8h/CFCh。如果要写程序来访问配置空间,那么必须调用这组IO来实现。主要的形式为:

out cf8h, config_address;
in config_data,cfch;

这里config_address表示函数需要输入的四个参数(BusNO, DeviceNO, FunctionNo, Register)来组合PCI总线的逻辑配置地址,以32bit表示。

而config_data则是通过内部配置机制而得到的反馈数据,读到的就是PCI设备中的配置空间register,以32bit表示。

 

PCI配置地址

接下来大家都会关心如何组合得到config_address呢?config_address是32bit表示的,组合形式如下图所示。

需要说明一下:

Pci总线上最多支持256个bus;每个bus上最多支持挂载32个device;而每个device则最多支持7个function(关于function部分可以后续讨论);而PCI配置空间则最多有64个Register(32bit)。这些限制从上图也可以看出来的。

所以一般以8bit来表示BusNO,5bit表示DeviceNO,3bit表示functionNO,6bit表示RegisterNO。

在写入cf8h端口之前需要置bit31为‘1’。表示使能 pci总线配置周期,来实现访问pci设备的配置空间。

 

PCI配置空间寄存器

通过PCI总线的配置周期,得到的config_data是以什么形式表示的呢?

其实,得到的32bit数据就是我们需要讨论的PCI配置空间。如下图:

当然,得到的config_data是32bit表示的,实际情况PCI配置空间register可能是byte、word或者dword等。这个都不是问题。

 

 

PCI配置空间的描述

1、  PCI设备识别

这些Register都是只读的,所有pci设备均要定义并使用这些register。程序也是通过读取这些register获得设备名称和厂商名称的。

Vendor ID:     表示该设备的厂商代号。PCI SIG会给每个PCI设备厂商分配一个唯一的ID,16bit表示。如果读到该处为0ffffh,那么表示对应逻辑地址上没有设备存在。

Device ID:     表示设备的ID号,这是由厂商自由分配的ID。

Revision ID:  由厂商自己定义,可以认为是Device ID的扩展。

Header type     区分设备类型的register。Bit7表示该设备是否是多fuction设备,若bit7=1表示为多功能设备(最大功能号位7),反之则是单功能设备。 而bit[6:0]则表示设备是否是bridge。00h表示普通pci设备,type0;如为01h,表示PCI bridge。

Class code        这部分用来区分设备的功能性。包含三个byte。0Bh为base class code;0Ah为sub-class code;09h表示编程接口。对于base class code有如下定义:

而sub-class code可以参考PCI spec的附录。往往,通过程序scan pci总线设备的时候,就是通过class code识别该设备的功能类型的。

 可以参考http://blog.csdn.net/pankul/article/details/8603632

 

2、  PCI设备的控制Register

Command:    通过此register来实现pci周期的响应,当0被写入此register时,设备逻辑上是不与总线”相连”的;而只有配置周期能访问该pci设备。如bit0、bit1均为0,则表示该设备对应的memory空间和io空间是不能访问的。上电启动该register为0.

 

Bit Location

Description

0

控制该设备对IO空间访问的响应。0表示不响应IO空间的访问;1表示能访问IO空间访问。

1

控制该设备对memory空间访问的响应。0表示不响应,1表示响应memory空间的访问。

2

控制该设备成为总线上的master。0表示不能产生Pci访问,1表示可以当做master来主动产生Pci 访问行为。

3

控制设备产生特殊的操作周期,具体不详。

4

控制设备能使用memory write and invalidate。该设备必须是master,才能产生memory write and invalidate 指令。详情参看pci spec 的chapter3

5

针对VGA设备来说的,enable VGA设备访问的palette 寄存器,并能侦测palette data。

6

使能设备响应parity errors

7

使能Wait周期,实现控制设备的address/data stepping。Stepping可以理解为单步?步进?

8

使能SEER#的驱动功能

9

针对master 设备来说的,在仲裁的问题中比较重要。置1表示支持到所有target的fast back-to-back 传输。

Fast back-to-back表示在完成一个传输周期之后没有wait cycle,而是直接开始下一个数据传输。包括两个情况:对同一个target操作back2back;对不同的target操作back2back。由于pci总线是并行总线设计,所有的设备都是并联挂载在总线上,所有仲裁机制必须很好的处理好fast back2back问题。

10-15

Reserved

 

3、  pci设备的状态Register

无需多言,可以按照字面上来理解。

 

4、  中断相关register

Interrupt line:        8bit的register表示设备所分配的irq号。可读写的寄存器,在post阶段会被BIOS写入一个PCI irqrouting分配的中断。如果没有被使用则用‘FFh’表示。

Interrupt Pin:         8bit的register表示设备使用的中断Pin脚。1-4分别表示INTA#、INTB#、INTC#、INTD#。这个是只读寄存器。

 

5、  Base Address

PCI设备一般都会需要分配memory空间或者IO空间。这些空间的基地址就保存在配置空间的BARx寄存器中。

是否需要分配memory空间或者iO空间,这是由PCI设备自身属性来说的。看BAR的bit0的值。Bit0是只读位,0表示对应BAR对应于memory空间;1表示相应BAR对应于IO空间。如下图表示BAR适用于memory空间的基地址

 

下图表示IO空间对应的基地址

至于如何分配memory 、io空间,算法如何?这些可以后续再写出来。对于bios工程师来说最好的方式还是那句话:Read the fucking source code!

这里只列举部分比较常用的PCI配置空间Register,其他的Register已经忽略,可以去详细阅读PCI spec。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值