PCI配置空间

PCI配置空间

 最后编辑:2010-5-26(修改错别字)

一.        概括

任何计算机系统都会有输入/输出,所以对外部设备的访问是CPU设计中的一个重要问题。外设上一般会有很多寄存器,像状态寄存器、控制寄存器、数据寄存器等等。对这些寄存器的访问,一般会有两种不同的形式:

 

一种叫内存映射方式。这种方式下,外设寄存器和系统内存统一编址,于是对外设寄存器的访问和内存访问一样,不需要额外的指令。

 

另一种叫I/O映射方式。这种方式下,外设和系统内存分属不同的体系,所以访问外设需要另外的指令。X86体系的CPU就是用的I/O映射方式,外设寄存器访问指令为IN和OUT。和内存访问地址空间不同的是:I/O访问指令的地址空间只有从0~65535。在计算机发展早期,这些地址还算富裕,但是随着外设的发展,各种功能的寄存器越来越多,更有甚者,一些外设上竟另外配置了RAM和扩展ROM,这时区区65536的I/O地址就显得有点“捉襟见肘”了。

 

为了解决这个问题,PCI规范设计时就为每个设备定义了一个256字节的PCI配置空间。将PCI设备中需要用到的一些基本寄存器都集中存放在该区域。而所有的PCI设备中配置空间的访问只使用I/O地址0CF8H~0CFFH来访问。

 

二.        PCI配置空间

256字节的PCI配置空间分为64字节的头标区和192字节的设备相关区两部分。头标区的各个寄存器用来唯一地识别设备;设备相关区则保存一些与设备相关的数据。

 

配置空间的头标区又分为两部分:前16个字节的定义在各种类型的PCI设备中都是一样的;剩余的字节随设备类型不同而有所不同。位于偏移地址0EH处的头标类型字段规定了头标区的布局结构。目前,规范定义了三种头标类型。

 

头标类型

设备

2

PCI-CardBus桥

1

PCI-PCI桥

0

除上述桥外的所有设备

 

因为PCI网卡的头标类型是0,所以下面我们就来详细说说其布局结构,至于其他类型的头标请读者自行阅读。图3就是头标类型0的头标区的布局。头标区中的寄存器根据功能可分成下面几组:

 

1. 设备的识别

(1)       供应商代码:该寄存器用于识别PCI设备的制造商,具体代码由PCI SIG(http://www.pcisig.com)分配。0FFFFH是无效的供应商代码。

(2)       设备代码。该寄存器用来标识某供应商生产的具体设备,代码由各供应商定义。供应商代码和设备代码,读者可以到网站http://www.pcidatabase.com/查阅。

 

图3 头标类型0的头标区的布局

 

(3)       版本号。该寄存器用来定义指定设备的版本信息。

(4)       头标类型。该字段的第7位为“1”表示该设备是多功能设备,为“0”表示为单功能设备;该字段的0~6位就是上文表中所述的头标类型。

(5)       设备分类代码。用来标识设备的总体功能和特定的寄存器级编程接口。

上面5个字段均为只读类型,所有的PCI设备都必须实现其功能。

 

2. 控制命令和设备状态

(1)       命令寄存器为一个设备发出和响应PCI总线命令提供粗略的控制。图4就是命令寄存器格式。

 

 

图4 命令寄存器格式

 

我们比较感兴趣的位有:

a.位0(I/O空间控制):控制对I/O空间访问的响应。该位为0时,禁止设备响应对I/O空间的访问;该位为1时,允许设备响应I/O空间的访问。缺省设置为0。

b.位1(存储器空间控制):控制一个设备对存储器空间访问的响应。该位为0时,禁止响应;该位为1时,允许设备响应对存储器空间的访问。缺省设置为0。

 至于其他位的功能,读者若有兴趣可以自行查阅。

 

(2)       状态寄存器用来记录PCI总线有关的状态信息。

 

3. 基址寄存器

PCI设备中,除了配置空间外,还有两个物理空间:内存空间和I/O空间。为了访问这两个地址空间,就必须使用基址寄存器。头标类型0中涉及3种基址寄存器:内存空间基址寄存器、I/O空间基址寄存器和扩展ROM基址寄存器。关于基址寄存器,我们下一章重点讲述。

 

4. 其他寄存器

其他寄存器包括一些本文不涉及到的寄存器,如中断引脚、中断线等等。有兴趣的读者可以自行阅读。

 

三.        PCI逻辑设备

每条PCI总线都有个总线号,主总线的总线号固定为0。每条PCI总线上都有各种各样的PCI设备。这里的设备其实指的是PCI设备接口卡(更确切地说是PCI总线接口芯片),通常取决于插槽的位置。每块PCI接口卡上可以有若干个功能模块,这些功能模块共用同一个PCI总线接口芯片,包括其中用于地址映射的电子线路,以降低陈本。从逻辑的角度说,每个“功能”实际上就是一项设备,所以设备号和功能号合在一起又可以称作“逻辑设备号”,而每块卡上最多可以容纳8个逻辑设备。显然,这些字段结合在一起就唯一地确定了系统中的一项PCI逻辑设备。

 

而一个PCI配置空间是对应于一个PCI逻辑设备的,所以上面说的PCI设备其实严格意义上来说应该是“PCI逻辑设备”。

 

四.        PCI配置空间的访问

上面说过,PCI规范使用从0CF8H~0CFFH 这8个I/O地址来访问所有设备的PCI配置空间。这8个字节实际上构成了两个32位寄存器:0CF8H寄存器叫做“配置地址寄存器”;0CFCH叫做“配置数据寄存器”。当要访问配置空间的寄存器时,先向地址寄存器写上目标地址,然后就可以从数据寄存器中读写数据了。

 

我们说过,PCI配置空间对应于一个PCI逻辑设备,所以要访问一个配置空间的某个寄存器,必须要指定:PCI总线号、PCI设备号、PCI设备功能号和寄存器号。配置地址寄存器的格式如下:

 

31

30   24

23     16

15     11

10    8

7       2

1

0

使能位

保留

总线号

设备号

功能号

寄存器号

0

0

 

第0、1位上的“0”是用来要求你只能按双字(4字节)来读写配置空间寄存器(0~7共8位正好能访问2^8=256个字节的配置空间)。第31位“使能位”用来决定是否允许访问配置空间:为“1”时表示可以访问;为“0”时表示不可以访问。

 

例如,为了读总线号0、设备号17H、功能号0的30H寄存器,你可以使用下面的代码:

 

MOV  EAX, 8000B830H

MOV  DX, 0CF8H

OUT   DX, EAX

 

MOV DX, 0CFCH

IN  EAX, DA

 

五.        PCI配置空间的遍历

从上面的配置地址寄存器的格式我们可以看出:总线号从0~255、设备号从0~31、功能号从0~7。根据配置空间的第0个寄存器是否返回0FFFFH值来判断是否存在该PCI设备(没有代码为0FFFFH的供应商)。下面是PCI配置空间遍历的流程图:

 

 

图5遍历PCI配置空间流程图

 

根据该流程用MASM6.11编制的程序源代码pci.asm。该程序经编译,可以在DOS下运行。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值