PCI配置空间简介

上传人:ba****u 文档编号:132873944 上传时间:2022-08-09 格式:DOCX 页数:21 大小:138.02KB
收藏 版权申诉 举报 下载
PCI配置空间简介_第1页
第1页 / 共21页
PCI配置空间简介_第2页
第2页 / 共21页
PCI配置空间简介_第3页
第3页 / 共21页
资源描述:

《PCI配置空间简介》由会员分享,可在线阅读,更多相关《PCI配置空间简介(21页珍藏版)》请在装配图网上搜索。

1、PCI配置空间简介作者:敏行PCI有三个相互独立的物理地址空间:设备存储器地址空间、I/O地址空间和配置空 间。配置空间是PCI所特有的一个物理空间。由于PCI支持设备即插即用,所以PCI 设备不占用固定的内存地址空间或I/O地址空间,而是由操作系统决定其映射的基 址。系统加电时,BIOS检测PCI总线,确定所有连接在PCI总线上的设备以及它们的配 置要求,并进行系统配置。所以,所有的PCI设备必须实现配置空间,从而能够实 现参数的自动配置,实现真正的即插即用。PCI总线规范定义的配置空间总长度为256个字节,配置信息按一定的顺序和大小 依次存放。前64个字节的配置空间称为配置头,对于所有的设

2、备都一样,配置头的 主要功能是用来识别设备、定义主机访问PCI卡的方式(I/O访问或者存储器访问, 还有中断信息)。其余的192个字节称为本地配置空间,主要定义卡上局部总线的 特性、本地空间基地址及范围等。访问PCI配置空间方法一访问PCI配置空间可通过两个访问寄存器,CONFIG_ADDRESS寄存器和 CONFIG_DATA寄存器。这两个寄存器在PC中分别对应着CF8h和CFCh端口,并 且是32位端口,即读写要用的32为IN和OUT汇编指令。每个PCI设备可应用三个信息进行定位,即Bus Number、Device Number和Function Number。另外,PCI配置空间一共是

3、256个字节,被分割成64个4字节的寄存器, 从0-63编号。每次要访问PCI配置空间时,先设置CONFIG_ADDRESS寄存器,这时 CONFIG_DATA存储器的内容就对应着该PCI配置空间中的相应的寄存器。访问PCI配置空间方法二第二种访问配置空间的方法是通过HalGetBusData和HalSetBusData两个内核函数。 这两个函数将方法进行了封装,不需要程序员对PCI空间进行直接读取。DDK提供了两个内核函数HalGetBusData和HalSetBusData,分别用于读取PCI设备 的配置空间和设置PCI配置空间。ULONG HalGetBusData(IN BUS_DAT

4、A_TYPE BusDataType,IN ULONG BusNumber,IN ULONG SlotNumber,IN PVOID Buffer,IN ULONG Length);注解:夫BusDataType:该参数指定总线类型。HalGetBusData函数可以查询各个总线的情 况,对于PCI总线,这里设置为PCIConfigurationo夫BusNumber:该参数指定Bus的总线号.夫SlotNumber:该参数由Device号和功能号共同组成。夫Buffer:该参数是得到的PCI配置空间的首地址。大Length:该参数是PCI配置空间的大小。访问PCI配置空间方法三(本例仅限于W

5、DM驱动,比较广泛使用)方法二适用于NT式驱动,但并不适用于WDM驱动。WDM中使用IRP获得PCI 配置空间。此方法不需要了解PCI具体的配置空间结构,WDM驱动程序已经帮助 程序员从PCI配置空间中分析出有用信息,并通知给程序员。WDM会为不同总线上的设备提供一个PDO设备,当程序员所写的功能驱动挂接在 PDO之上的时候,就可以将IRP_MN_START_DEVICE传递给底层的PDO去处理。 PCI总线的PDO就会得到PCI配置空间,并从中得到有用信息,如中断号、设备物 理内存及I/O端口等信息。在处理完IRP_MN_START_DEVICE后,驱动程序会将处理结果存储在IRP的设备 堆

6、栈中,从I/O堆栈可以取出CM_FULL_RESOURCE_DESCRIPTOR数据结构,从 CM_FULL_RESOURCE_DESCRIPTOR 中可以取出CM_PARTIAL_RESOURCE_LIST 数据结构,而在 CM_PARTIAL_RESOURCE_LIST 中又可以取出 CM_PARTIAL_RESOURCE_DESCRIPTOR 数据结构。cm_fuLl_rEsouRce_descriptor 数据结构就是PDO帮助程序员从256字 节的PCI配置空间中获取的有用信息, 这其中包括终端号、设备物理内存、I/O 端口等信息。访问PCI配置空间方法四(本例仅限于WDM驱动)方法

7、三没有完整的的获取到256字节的PCI配置空间,需要自己创建IRP_MN_READ_CONFIG 或者 IRP_MN_WRITE_CONFIG,然后将创建好的即插即 用IRP发送到底层的PDO,并等待PDO的处理。该方法获取完整的PCI配置空间。配置空间操作系统PCI总线推出以来,以其独有的特性受到众多厂商的青睐,已经成为计算机扩展 总线的主流。目前,国内的许多技术人员已经具备开发PCI总线接口设备的能力。但是PCI总线的编程技术,也就是对PCI总线设备的操作技术,一直是一件让技术 人员感到头疼的事情。PCI总线编程的核心技术是对相应板卡配置空间的理解和访 问。一般软件编程人员基于对硬件设备原

8、理的生疏,很难理解并操作配置空间,希 望硬件开发人员直接告诉他们怎样操作;而PCI总线硬件开发人员虽深刻地理解了 其意义,在没有太多编程经验地前提下,也难于轻易地操作PCI板卡。结果大多是 硬件技术人员花费大量时间和精力去学习DDK、WINDRVER等驱动程序开发软件。作者在开发PCI总线接口设备时,经过对PCI总线协议的深入研究,从协议本身 的角度出发,找到一种方面而快捷的PCI配置空间操作方法,只使用简单的I/O命 令即可找到特定的PCI总线设备并对其所有的配置空间进行读写操作。一旦读得其 配置空间的内容,即可中得到担任系统对该PCI总线设备的资源分配。1 PCI总线配置空间及配置机制为避

9、免各PCI设备在资源的占用上发生冲突,PCI总线采用即插即用协议。即在 系统建立时由操作系统按照各设备的要求统一分配资源,资源分配的信息由系统写 入各PCI设备的配置空间寄存器,并在操作系统内部备份。各PCI设备有其独自的 配置空间,设计者通过对积压设备(或插槽)的ISDEL引脚的驱动区分不同设备的 配置空间。配置空间的前64个字节称为配置空间的预定自区,它对每个设备都具有 相同的定义且必须被支持;共后的空间称为设备关联区,由设备制造商根据需要定 义。与编程有关的配置空间信息主要有:(1) 设备号(Device ID)及销售商号(VendorID),配置空间偏移量为00h,用于对各PCI设备的

10、区分和查找。为了保证其唯 一性,VendorID应当向PCI特别兴趣小组(PCI SIG)申请而得到。(2) PCI基地址(PCI Base Address),配置空间偏移量为1024h,设备通过 设定可读写的高位数值来向操作系统指示所需资源空间的大小。比如,某设备需要 64K字节的内存空间,可以将配置空间的某基地址寄存器的高16位设成可读写的, 而将低16位置为0 (只可读)。操作系统在建立时,先向所有位写1,实际上只有 高16位被接收而被置成了 1,低16位仍为0.这样操作系统读取该寄存器时,返回 值为FFFF0000h,据此操作系统可以断定其需要的空间大小是64K字节,然后分配 一段空闲

11、的内存空间并向该寄存器的高16位填写其地址。其它可能与编程有关的配置空间的定义及地址请参阅参考文献1。由于PC-AT兼容系统CPU只有内存和I/O两种空间,没有专用的配置空间,PCI 协议规定利用特定的I/O空间操作驱动PCI桥路转换成配置空间的操作。目前存在 两种转换机制,即配置机制1#和配置机制2#。配置机制2#在新的设计中将不再被 采用,新的设计应使用配置机制1#来产生配置空间的物理操作。这种机制使用了两 个特定的32位I/O空间,即CF8h和CFCh。这两个空间对应于PCI桥路的两个寄存 器,当桥路看到CPU在局部总线对这两个I/O空间进行双字操作时,就将该I/O操 作转变为PCI总线

12、的配置操作。寄存器CF8h用于产生配置空间的地址 (CONFIG-ADDRESS),寄存器CFCh用于保存配置空间的读写数据 (CONFIG-DATA )0配置空间地址寄存器的格式如图10CF8H (局部总线):当CPU发出对I/O空间CFCh的操作时,PCI桥路将检查配置空间地址寄存器 CF8h的31位。如果为1,就在PCI总线上产生一个相应的配置空间读或写操作, 其地址由PCI桥路根据配置空间地址寄存器的内容作如图2所示的转换。CFCh (局部总线):设备号被PCI桥路译码产生PCI总线地址的高位地址,它们被设计者用作IDSEL 信号来区分相应的PCI设备。6位寄存器号用于寻址该PCI设备

13、配置空间62个双字 的配置寄存器(256字节)。功能号用于区分多功能设备的某特定功能的配置空间, 对常用的单功能设备为0000某中PCI插槽的总线号随系统(主板)的不同稍有区 别,大多数PC机为1,工控机可能为2或3。为了找到某设备,应在系统的各个总 线号上查找,直到定位。如果在05号总线上不能发现该设备,即可认为该设备不 存在。理解了上述PCI协议里的配置机制后,就可以直接对CF8h和CFCh两个双字的 I/O空间进行操作,查找某个PCI设备并访问其配置空间,从而得到操作系统对该 PCI设备的资源分配。2用I/O命令访问PCI总线配置空间要访问PCI总线设备的配置空间,必须先查找该设备。查找

14、的基本根据是各PCI 设备的配置空间里都存有特定的设备号(DeviceID)及销售商号(Vendor ID),它们占用配置空间的00h地址。而查找的目的 是获得该设备的总线号和设备号。查找的基本过程如下:用I/O命令写配置空间的 地址寄存器CF8h,使其最高位为1,总线号及设备为0,功能号及寄存器号为0, 即往I/O端口 CF8h80000000h ;然后用I/O命令读取配置空间的数据寄存器CFCh。 如果该寄存器值与该PCI设备的DeviceID及Vendor ID不相符,则依次递增设备号/总线号,重复上述操作直到找到该 设备为止。如果查完所有的设备号/总线号(15)仍不能找到该设备,则应当

15、考虑 硬件上的问题。对于多功能设备,只要设备配置寄存器相应的功能号值,其余步骤 与单功能设备一样。如查找设备号为9054h,销售商号为10b5的单功能PCI设备,用VC+6.0编写 的程序如下:char bus;char device;unsigned int ioa0,iod;int scan()bus=0;device=0;for(char i=0;i5;i+) (for(char j=0;j32;j+) bus=i; device=j;ioa0=0x80000000+bus*0x10000+(device*8)*0x100;_outpd(0xcf8,ioa0);iod=_inpd(0xc

16、fc);if (iod0= =0x905410b5) return 0;retrn -1调用子程序scan(),如果返回值为-1,则没有找到该PCI设备。如果返回值为0, 则找到了该PCI设备。该设备的总线号和设备号分别在全局变量bus和device中, 利用这两个变量即可轻易对该设备的配置空间进行访问,从而得到分配的资源信息。 假设该PCI设备占用了 4个资源空间,分别对应于配置空间10h1ch,其中前两个 为I/O空间,后两个为内存空间,若定义其基地址分别为ioaddr1,ioaddr2,memaddr1,memaddr2,相应的程序如下:unsigned short ioaddr1,io

17、addr2;unsigned int memaddr1,memaddr2;unsigned int iobase,ioa;void getbaseaddr(char bus,char device);iobase=0x80000000+bus*0x10000+(device*8)*0x100;ioa=iobase+0x10;/*寻址基地址寄存器0*/_outpd(0xcf8,ioa);ioaddr1=(unsignedshort)_inpd(0xcfc)&0xfffc;/*屏蔽低两位和高16位*/ioa=iobase+0x14; /*寻址基地址寄存器1*/_outpd(0xcf8,ioa);i

18、oaddr2=(unsignedshort)_inpd(0xcfc)&0xfffc;ioa=iobase+0x18;/*寻址基地寄存器2*/_outpd(0xcf8,ioa);memaddr1=_inpd(0xcfc) & 0xfffffff0;/*屏蔽低4位*/ioa=iobase+0x1c; /*寻址基地址寄存器3*/_outpd(0xcf8,ioa);memaddr2=_inpd(0xcfc) & 0xfffffff0;对于I/O基地址,最低两位D0、D1固定为01,对地址本身无效,应当被屏蔽。 对PC-AT兼容机,I/O有效地址为16位,因此高位也应被屏蔽。对于内存地址,最 低位D0固

19、定为0,而D1D3用于指示该地址的一些物理特性1,因此其低4位地 址应当被屏蔽。需要指出的是该内存地址是系统的物理地址,在WINDOWS运行于 保护模式时,需要经过转换得到相应的线性地址才能对该内存空间进行直接读写。 介绍该转换方法的相关文章较为常见,此处不再赘述。上述程序给出了读取配置空间里的基地址的方法。另有相当多PCI设备通过配置 空间的设备关联区来设置该设备的工作状态,可轻易地用I/O命令进行相应的设置, 无须编写繁杂的驱动程序。在开发PCI视频图像采集卡的过程中,该方法得到了实 际应用。如何访问PCI配置空间1. 配置事务的产生PCI协议指出,一般情况下,系统都是通过主桥来实现软件产

20、生配置事务的,CF8 和CFC端口对应主桥的两个32位寄存器,对CF8和CFC进行32位读写操作,即可产生PCI配置事务。2. PCI两类配置命令:类型0和类型1类型0:用于选择总线上的一个设备命令格式:3111 108 72 1 0I reserve I function number I register number I 0 I 0 I类型1:用于向下级总线传递配置请求命令格式:3124 2316 1511 108 72 1 0I reserve I bus number I device number I function number I register number I 0 I

21、1 I3. PCI配置空间访问流程所有PCI主桥和PCI-PCI桥都必须能够产生这两类配置命令,当发生cf8寄存器 32位写操作时,根据Bus Number,若为0,主桥则产生类型0配置命令,否则产生类型1配置命令。假设产生类型0配置命 令,主桥将其(产生的32位命令数据)放在其局部总线上,在其局部总线上寻找选择目标设备,找到目标设备将其IDSEL#有效, 所有的PCI设备都要相应类型0配置命令,在其IDSEL#有效情况下,使其DEVSEL#有效,告诉桥设备自己就是目标设备,再 根据寄存器索引来访问具体的配置寄存器;若其局部总线上没有目标设备,则产生类型1配置命令并将其(产生的32位命令数)

22、放在其局部总线上,所有的PCI设备(除PCI-PCI桥)都要忽略类型1配置命令,只有桥设备响应类型1命令,桥设备译码总 线号判断配置事务的目标总线是否在其后,若目标总线不在其后,忽略该配置事务,否则,它将声明目标总线就在其后,若总 线号不是该桥所挂接的总线,则原封不变的向下传递,否则,将类型1配置命令转换成类型0配置命令放在其挂接的总线上 选择设备。如何在DOS中枚举PCI设备(作者zyl910)07-01-07 12:55发表于:VC的梦,VC的结分类:B)唧唧复唧唧 File: zEnumPCIName: 如何在DOS中枚举PCI设备Author: zyl910Blog:Version:

23、V1.0Updata: 2006-6-30下载(注意修改下载后的扩展名)刖言学计算机这么多年了,PCI这个名词不知道叫了几百遍了。可是,我一直不知 道PC机是如何使用PCI总线的、PCI总线设备到底是如何工作的。可是以前我从来 没意识到这个问题,只是麻木的、带着虚伪的自信活着。直到前段时间在书店看到PCI Express系统体系结构标准教材,才突然感受 到我对PCI还一无所知,可现在PCI Express的时代都快到来了。我很受震撼, 所以毫不犹豫地买下了那本书。回家打开书一看,发现绝大东西看不太懂。当年学接口技术时,那时只有ISA。 ISA很简单,是直接采用电路连线方式将设备与地址总线、各个

24、IRQ及其他控制线 路连接起来。而现在PCI-E就很复杂了,而我跳过了?。【,存在着知识断层。于是我又跑到书店,去查PCI或接口技术上面的书。后来发现,这十年来,接 口技术的书的确更新了,但只为PCI写个寥寥几页简介,有的书甚至连引脚定义、 配置空间等PCI最核心内容都没有。那样子还不如不说,浪费了纸张。典型只为了 教学大纲,而不考虑学生是否能学会、理解。我费了好大功夫,才找了几本关于PCI的书,但主要是英文的。特别是找到了 PCI Express系统体系结构标准教材的英文版,这样就可以对照参考,理解那些 英文资料。看了一段时间之后,发现那些书主要是讲硬件电气特性、通信协议细节,面向 的读者是

25、设计PCI设备的工程师。而我的学习目的是如果在PC机上编程控制PCI 设备。还好在网络上找了一些关于PCI小程序,填补了知识空白。正文一、PCI配置空间PCI设备有三个空间内存地址空间、IO地址空间和配置空间。由于PCI支 持即插即用,所以PCI设备不是占用固定的内存地址空间或I/O地址空间,而是可 以由操作系统决定其映射的基址。怎么配置呢?这就是配置空间的作用。DW I Byte3 I Byte2 I Bytel I Byte0 I Addr+0 IDevice IDIVendor IDI 00-+1 IStatusICommandI 04-+2 IClass CodeI Revision

26、ID I 08-+3 I BIST I Header Type I Latency Timer I Cache Line I 0C-+4 IBaseAddress0I10-+5 IBaseAddress1I14-+6 IBaseAddress2I18_+7 IBaseAddress3I1C_+8 IBaseAddress4I20_+9 IBaseAddress5I24_+10 ICardBus CIS pointerI 28_+11 I Subsystem Device ID I Subsystem Vendor ID I 2C_+12 IExpansion ROM Base AddressI

27、 30_+13 IReserved(Capability List)I 34-+14 IReservedI 38+15 I Max_Lat I Min_Gnt I IRQ Pin I IRQ Line I 3C配置空间中最重要的有:Vendor ID:厂商ID。知名的设备厂商的ID。FFFFh是一个非法厂商ID,可它来判 断PCI设备是否存在。Device ID:设备ID。某厂商生产的设备的ID。操作系统就是凭着Vendor ID和Device ID找到对应驱动程序的。Class Code:类代码。共三字节,分别是类代码、子类代码、编程接口。类代码不 仅用于区分设备类型,还是编程接口的规范,这

28、就是为什么会有通用驱动程序。IRQ Line: IRQ编号。PC机以前是靠两片8259芯片来管理16个硬件中断。现在为 了支持对称多处理器,有了 APIC (高级可编程中断控制器),它支持管理24个中 断。IRQ Pin:中断引脚PCI有4个中断引脚,该寄存器表明该设备连接的是哪个引脚。关于配置空间的详细说明请参考PCI Local Bus Specification的第六章。二、如何访问配置空间如何访问配置空间呢?可通过访问CF8h、CFCh端口来实现(PCI Local Bus Specification的 3.2.2.3.2)。CF8h: CONFIG_ADDRESS。PCI 配置空间地

29、址端口。CFCh: CONFIG_DATA。PCI 配置空间数据端口。CONFIG_ADDRESS寄存器格式:31 位:Enabled 位。23:16位:总线编号。15:11位:设备编号。10: 8位:功能编号。7: 2位:配置空间寄存器编号。1: 0位:恒为“00”。这是因为CF8h、CFCh端口是32位端口。现在有个难题CF8h、CFCh端口是32位端口,可像TurboC之类的16位C 语言编译器都不支持32位端口访问。怎么办?我们可以使ffl_emit_ft程序中插入 机器码。每次都_emit_ 一下肯定很麻烦,所以我们应该将它封装成函数。代码如 下(注意66h是32位指令前缀):/*

30、读 32 位端口 */DWORD inpd(int portid) ( DWORD dwRet;asm mov dx, portid; asm lea bx, dwRet;_emit_(DWORD dwVal)( asm mov dx, portid; asm lea bx, dwVal;_emit_(0x66,0x50,/ push EAX0x66,0x8B,0x07, / mov EAX,BX0x66,0xEF,/ outDX,EAX0x66,0x58);/ pop EAX return; 三、枚举PCI设备怎么枚举PCI设备呢?我们可以尝试所有的bus/dev/func组合,然后判断得到

31、 的厂商ID是否为FFFFh。下面这个程序就是使用该方法枚举PCI设备的。同时为了便于分析数据,将每 个设备的配置空间信息保存到文件,这样可以慢慢分析。/*File:epcip.cName:访问CF8h、CFCh端口来枚举PCI设备Author:zyl910Blog:Version:V1.0Updata:2006-6-30*/#include #include typedef unsigned char BYTE;typedef unsigned int WORD;typedef unsigned long DWORD;/* PCI设备索引。bus/dev/func共16位,为了方便处理可放在

32、一个WORD中*/#define PDI_BUS_SHIFT8#define PDI_BUS_SIZE8#define PDI_BUS_MAX0xFF#define PDI_BUS_MASK0xFF00#define PDI_DEVICE_SHIFT3#define PDI_DEVICE_SIZE5#define PDI_DEVICE_MAX0x1F#define PDI_DEVICE_MASK0x00F8#define PDI_FUNCTION_SHIFT0#define PDI_FUNCTION_SIZE3#define PDI_FUNCTION_MAX0x7#define PDI_FUN

33、CTION_MASK0x0007#define MK_PDI(bus,dev,func)(WORD)(bus&PDI_BUS_MAX)PDI_BUS_SHIFT |(dev&PDI_DEVICE_MAX)PDI_DEVICE_SHIFT | (func&PDI_FUNCTION_MAX)/* PCI配置空间寄存器*/#define PCI_CONFIG_ADDRESS0xCF8#define PCI_CONFIG_DATAOxCFC/* 填充 PCI_CONFIG_ADDRESS */#define MK_PCICFGADDR(bus,dev,func) (DWORD)(Ox8OOOOOOOL

34、 |(DWORD)MK_PDI(bus,dev,func)8)/*读32位端口 */DWORD inpd(int portid)(DWORD dwRet;asm mov dx, portid;asm lea bx, dwRet;_emit_(Ox66,Ox5O, / push EAXOx66,OxED, / in EAX,DXOx66,Ox89,OxO7, / mov BX,EAXOx66,Ox58); / pop EAXreturn dwRet;/*写32位端口 */void outpd(int portid, DWORD dwVal)(asm mov dx, portid;asm lea

35、bx, dwVal;_emit_(Ox66,Ox5O, / push EAXOx66,Ox8B,OxO7, / mov EAX,BXOx66,OxEF, / out DX,EAXOx66,Ox58); / pop EAXreturn;int main(void)(int bus, dev, func;int i;DWORD dwAddr;DWORD dwData;FILE* hF;char szFile0x10;printf(n);printf(Bus#tDevice#tFunc#tVendortDevicetClasstIRQtIntPinn)/*枚举PCI设备*/for(bus = 0;

36、bus = PDI_BUS_MAX; +bus) (for(dev = 0; dev = PDI_DEVICE_MAX; +dev) (for(func = 0; func 16);/* Class Code */outpd(PCI_CONFIG_ADDRESS, dwAddr | 0x8);dwData = inpd(PCI_CONFIG_DATA);printf(6.6lXt,dwData8);/* IRQ/intPin */outpd(PCI_CONFIG_ADDRESS, dwAddr | 0x3C);dwData = inpd(PCI_CONFIG_DATA);printf(dt,(

37、BYTE)dwData);printf(d,(BYTE)(dwData8);printf(n);/*写文件*/sprintf(szFile, PCI%2.2X%2.2X%X.bin,bus, dev, func);hF = fopen(szFile, wb);if (hF != NULL) (/* 256字节的PCI配置空间*/for (i = 0; i 0x100; i += 4) (/* Read */outpd(PCI_CONFIG_ADDRESS, dwAddr | i);dwData = inpd(PCI_CONFIG_DATA);/* Write */fwrite(&dwData,

38、 sizeof(dwData), 1, hF);fclose(hF);return 0;对于我的电脑的枚举结果是:Bus#Device#Func#VendorDeviceClassIRQIntPin类代码的说明000110631896000000Host bridge0101106B1686040000PCI-to-PCI bridge (实际上 是PCI/AGP桥,AGP可看 成一种特殊的PCI设备)09014F1201378000111Simple communication controllers09114F1201378000111Simple communication contro

39、llers09214F1201378000111Simple communication controllers09314F1201378000111Simple communication controllers09414F1201378000111Simple communication controllers09514F1201378000111Simple communication controllers09614F1201378000111Simple communication controllers09714F1201378000111Simple communication

40、controllers0100110630380C0300111USB controller: UniversalHost Controller Specification0101110630380C030052USB controller: UniversalHost Controller Specification0102110630380C030053USB controller: UniversalHost Controller Specification0103110631040C0320114USB2 controller: IntelEnhanced Host Controlle

41、rInterface0110110631776010000ISA bridge0111110657101018A2551IDE controller0115110630594010053Audio device01201106306520000111Ethernet controller10010DE11030000111VGA-compatible controller总线编号为0的都是主板上固有的芯片(主要是南桥),非主板设备的典型是 显卡。WindowsXP的设备管理器中也可以看到PCI信息。启动“设备管理器”,最好 将查看方式设为“依连接查看设备(V)”。找到我的显卡,双击查看属性。切

42、换到“详 细信息”页,定位组合框为“硬件Id”。可看到其中一行为“PCI/VEN_10DE&DEV_0110&CC_030000”,表示厂商 ID 为 “10DE”、设备 ID 为“0110”、类代码为“030000”,与程序得到的结果一致。Display.gif四、PCI BIOS直接访问CF8h、CFCh端口的方法太底层。为了提高兼容性,我们可以使用PCIBIOS。PCI BIOS的中断号是1Ah,AH为B1,AL为功能号。其功能列表为:01h: INSTALLATION CHECK02h: FIND PCI DEVICE03h: FIND PCI CLASS CODE06h: PCI B

43、US-SPECIFIC OPERATIONS08h: READ CONFIGURATION BYTE09h: READ CONFIGURATION WORD0Ah: READ CONFIGURATION DWORD0Bh: WRITE CONFIGURATION BYTE0Ch: WRITE CONFIGURATION WORD0Dh: WRITE CONFIGURATION DWORD0Eh: GET IRQ ROUTING INFORMATION0Fh: SET PCI IRQ81h: INSTALLATION CHECK (32-bit)82h: FIND PCI DEVICE (32-

44、bit)83h: FIND PCI CLASS CODE (32-bit)86h: PCI BUS-SPECIFIC OPERATIONS (32-bit)88h: READ CONFIGURATION BYTE (32-bit)89h: READ CONFIGURATION WORD (32-bit)8Ah: READ CONFIGURATION DWORD (32-bit)8Bh: WRITE CONFIGURATION BYTE (32-bit)8Ch: WRITE CONFIGURATION WORD (32-bit)8Dh: WRITE CONFIGURATION DWORD (32

45、-bit)8Eh: GET IRQ ROUTING INFORMATION (32-bit)8Fh: SET PCI IRQ (32-bit)由于像Turbo C这样的16位编译器访问32位寄存器很麻烦,所以建议使用 WORD方式来访问PCI配置空间。以下是09h号功能的详细说明(摘自Ralf Browns Interrupt List):X-1AB109INT 1A - PCI BIOS v2.0c+ - READ CONFIGURATION WORDAX = B109hBH = bus numberBL = device/function number (bits 7-3 device,

46、bits 2-0 function)DI = register number (0000h-00FFh, must be multiple of 2) (see #00878)Return: CF clear if successfulCX = word readCF set on errorAH = status (00h,87h) (see #00729)EAX, EBX, ECX, and EDX may be modifiedall other flags (except IF) may be modifiedNotes: this function may require up to

47、 1024 byte of stack; it will not enableinterrupts if they were disabled before making the callthe meanings of BL and BH on entry were exchanged between the initial drafts of the specification and final implementationBUG: the Award BIOS 4.51PG (dated 05/24/96) incorrectly returns FFFFh forregister 00

48、h if the PCI function number is nonzeroSeeAlso: AX=B108h,AX=B10Ah,AX=B189h,INT 2F/AX=1684h/BX=304Ch代码如下:/*File: epcib.cName: 使用PCI BIOS来枚举PCI设备Author: zyl910Blog:Version: V1.0Updata: 2006-6-30*/#include #include #include typedef unsigned char BYTE;typedef unsigned int WORD;typedef unsigned long DWOR

49、D;/* PCI设备索引。bus/dev/func共16位,为了方便处理可放在一个WORD中*/#define PDI_BUS_SHIFT 8#define PDI_BUS_SIZE 8#define PDI_BUS_MAX 0xFF#define PDI_BUS_MASK 0xFF00#define PDI_DEVICE_SHIFT 3#define PDI_DEVICE_SIZE 5#define PDI_DEVICE_MAX 0x1F#define PDI_DEVICE_MASK 0x00F8#define PDI_FUNCTION_SHIFT 0#define PDI_FUNCTION

50、_SIZE 3#define PDI_FUNCTION_MAX 0x7#define PDI_FUNCTION_MASK 0x0007#define MK_PDI(bus,dev,func) (WORD)(bus&PDI_BUS_MAX)PDI_BUS_SHIFT | (dev&PDI_DEVICE_MAX)PDI_DEVICE_SHIFT | (func&PDI_FUNCTION_MAX) int main(void) int bus, dev, func;int i;union REGS regs;WORD wAddr;FILE* hF;char szFile0x10;printf(n);

51、printf(Bus#tDevice#tFunc#tVendortDevicetClasstIRQtIntPinn);/*枚举PCI设备*/for(bus = 0; bus = PDI_BUS_MAX; +bus) for(dev = 0; dev = PDI_DEVICE_MAX; +dev) for(func = 0; func 8);printf(n);/*写文件*/sprintf(szFile, PCI%2.2X%2.2X%X.bin”, bus, dev, func);hF = fopen(szFile, wb);if (hF != NULL) (/* 256字节的PCI配置空间*/

52、for (i = 0; i 0x100; i += 2) (/* Read */regs.x.ax = 0xB109; / PCI BIOS v2.0c+ - READ CONFIGURATION WORDregs.x.bx = wAddr;regs.x.di = i;int86(0x1A, ®s, ®s);/* Write */fwrite(®s.x.cx, 2, 1, hF);fclose(hF);return 0;五、保护模式下的PCI BIOS刚才所说的1Ah中断是实模式下的BIOS,保护模式下怎么办?在BIOS内存区(E0000hFFFFFh)可以找到PCI BIO

53、S保护模式入口。其格 式为:0h(dw): _32_ ”标志4h(dw): PCI BIOS保护模式入口8h(by): Rev Level9h(by):长度Ah(by):校检和BhFh:保留关于保护模式下PCI BIOS的具体用法可参考PCI Bus Demystified的第七章。由于切换到保护模式的代码比较复杂,所以就没有编程测试了。六、总结本文章中的代码能在纯DOS下或Windows9X中正常运行,但是不能在 WindowsXP等NT平台下运行:对于访问端口方式,厂商ID均返回FFFFh;对于调 用PCI BIOS方式,貌似根本没有实现该功能。这可能与WindowsXP设计有关 不再使用V86方式执行DOS程序,而是专门做了个DOS虚拟机。而且还有许多这 样的兼容性问题,比如VBE。我都有点怀疑这不是微软故意这么做,让我们不能接 触底层,只能使用高层的.Net,这样不可能对像微软这样掌握核心技术的公司造成 威胁。

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!