1、PCI总线的发展历史
1990年,起源于Intel架构开发实验室,全称是Peripheral Component Interconnect,首先在服务器中使用,代替了原来的MCA以及EISA,EISA直到2000年才宣告退出历史舞台。直到1994年,才开始在PC上广泛使用,代替了原来的VESA。在1995年的中期,苹果电脑也开始使用PCI总线电气规范。后来PCI也增加了许多新的功能,比如66MHz,3.3V标准,以及133MHz的PCI-X。2004年,出现了PCI-Express,原来的PCI总线电气规范被称为了传统PCI(Conventional PCI)。
2、PCI总线地址空间
独立的内存以及IO接口,由软件分配。而另外一个地址空间-PCI配置空间(PCI Configuration Space),使用独立的地址,允许软件决定每一个连入的设备需要多少内存以及IO地址空间。通过设备配置空间寄存器的设置,每一个设备至多可以申请6个内存以及IO地址空间。PCI配置空间还包括了连入设备的相关信息,根据这些信息,操作系统可以方便地使用相应的驱动来使用这些设备。为了使PCI总线公平地使用PCI总线,提供了一种等待计时的功能,计时器在设备获得了总线使用权时以PCI时钟信号的速率开始计时,直到减为零,设备释放总线占有权。
3、关于PCI的中断
四个中断,属于电平触发方式(边沿触发方式的中断容易丢失)。单功能设备只是使用INTA#,多功能设备使用多个中断。四个中断通过PCI桥(两个PCI总线之间)映射到系统中断上,所以软件无从得知是那个PCI中断。后来的PCI加入了消息信号中断的机制,PCI-Express使用的也是消息信号中断机制,而没有物理中断线。
4、PCI电气规范
PCI卡的尺寸,长度为174.63mm,高度为36.068~106.68mm。一下是一幅PCI个引脚定义的图。
5、PCI设备的初始化
机器上电的时候,配置软件必须扫描PCI总线,确定有哪些PCI设备,然后加载相应的驱动程序。所有PCI设备都必须实现PCI协议规定必须的配置寄存器。而对PCI配置访问实际上就是访问设备的配置寄存器。
6、PCI配置空间
配置空间各项数据说明:
厂商识别码(Vendor ID):标识设备的制造者,有PCI SIG来分配。0FFFH表示未配置任何设备。
设备识别码(Device ID):标识特定的设备,具体代码由厂商分配。
版本ID,Revision ID:指定一个设备特有的版本号。
Class Code(分类代码):用于设备分类。0BH处为基本分类代码;0A处为子分类代码;09H处为标识一个专用的寄存器级编程接口,便于设备的软件可以与设备交互数据。
命令寄存器(Command):为发出和响应PCI总线命令提供了对设备粗略的控制。
状态寄存器(Status):用于记录PCI总线有关操作的状态信息,系统对该寄存器的读操作无特殊要求。
基地址寄存器(Base Address Registers):供地址映射使用,使PCI的IO映射以及内存映射与具体设备无关。
扩展ROM的基地址寄存器(Expansion ROM Base Address):用来处理那些配置了局部EPROM或者Flash ROM的基地址和大小。Cache大小寄存器:用来指定系统中Cache行的长度,每个参加Cache协议的设备都要使用该寄存器。
延时计时器:该寄存器以PCI总线时钟为单位指定PCI总线主设备的延迟计时器。
内含自测寄存器:可选的寄存器,用作内含自测试的控制与状态寄存器。
中断引脚寄存器(Interrupt Pin):用来表示设备使用了哪个PCI中断引脚。
中断线寄存器(Interrupt Line):用来表示设备中的中断引脚与系统可编程控制器8259的哪个中断输入线相连接。
MAX_GNT表示设备需要多长的突发传输时间。MAX_LAT表示对PCI总线进行访问的频繁程度。
Card CIS Pointer:由在卡总线和PCI之间共享芯片的设备实现。
子系统厂商标识和子系统标识(Subsystem Vendor ID):用于惟一地标识设备所驻留的插入卡和子系统。即插即用操作系统可以定位正确的驱动程序,装载到存储器。
7、PCI扩展ROM
通过执行扩展ROM存放的代码来完成与设备相关的初始化,同时也可能完成系统引导功能。该机制允许扩展ROM中含有几个不同的映像,以适应不同的机器和处理器结构。
凡是支持扩展ROM的设备,必须支持按任意字节组合方式对ROM进行访问,特别强调的是要支持双字(DWORD)访问。扩展ROM中的信息安排要与现有的适合于ISA和EISA以及MC适配器的Intel X86扩展ROM中的头标区兼容。头标区中所给信息经过了扩充,从而使适配器的功能进一步优化使用,从而可以使扩展ROM中的代码在运行期间所使用的存储空间最小。
PCI扩展ROM中代码从不在原地执行,而是将代码从ROM中拷贝到RAM中执行。这样可以在初始化和运行时动态地确定代码长度,并且能够改善代码的执行速度。
PCI对于不同的系统和处理器配置都应该包含其编码映像。每个映像由ROM首区(映像开始处)+数据配置区(映像的第64KB范围内)组成。
ROM首区内容
偏移 |
长度 |
值 |
说明 |
00H~01H |
2 |
55AAH |
ROM标签字节 |
02H~17H |
22 |
XX |
保留 |
18H~19H |
2 |
XX |
到PCI数据结构指针 |
数据配置区
偏移量 |
长度 |
说明 |
偏移量 |
长度 |
说明 |
00H~03H |
4 |
标签,字符串"PCID" |
0DH~0FH |
3 |
分类代码 |
04H~05H |
2 |
供应商识别码 |
10H~11H |
2 |
映像长度 |
06H~07H |
2 |
设备识别码 |
12H~13H |
2 |
代码数据的修改级别 |
08H~09H |
2 |
对重要产品数据的指针 |
14H~14H |
1 |
代码类型 |
0AH~0BH |
2 |
PCI数据结构长度 |
15H~15H |
1 |
指示标志 |
0CH~0CH |
1 |
PCI数据结构修改 |
16H~17H |
2 |
保留 |
8、关于PCI设备的初始化
系统POST首先检查PCI设备在配置空间是否使用了扩展ROM基地址寄存器(即是否有扩展ROM),若使用了,POST将ROM映射到地址空间中一个未用的部分。
9、PCI BIOS
其主要作用有以下两点:
- 为应用软件或者PCI总线设备或者板卡提供服务调用。
- 初始化每个系统PCI设备。PCI BIOS轮流查询每个PCI插槽,查找存在的PCI设备,读取存在设备配置空间的头标区,以决定设备的厂商号,类型和存储需求等内容。并且将分配的I/O或存储空间地址回写到每个设备配置空间的基地址寄存器中。
- PCI BIOS调用的入口以及返回值说明,对80x86机器,调用功能号为1AH,入口参数在AX中,返回值在AH中。下面列举的是比较常用的,更多说明请参考PCI BIOS规则说明书。
功能说明 |
入口参数(AX) |
返回值说明 |
出口参数(AH) |
PCI BIOS存在查询 |
B101H |
成功调用 |
00H |
查找PCI 设备 |
B102H |
不支持的功能 |
81H |
查找PCI 设备的类代码 |
B103H |
错误的厂商号 |
83H |
产生特殊周期 |
B106H |
未找到设备 |
86H |
读配置寄存器-单字节操作 |
B108H |
错误的寄存器号 |
87H |
读配置寄存器-单字操作 |
B109H |
设置失败 |
88H |
读配置寄存器-双字操作 |
B10AH |
缓冲区太小 |
89H |
写配置寄存器-单字操作 |
B10BH |
|
|
写配置寄存器-单字节操作 |
B10CH |
|
|
写配置寄存器-双字节操作 |
B10DH |
|
|
取得中断线路选项 |
B10EH |
|
|
设置PCI中断 |
B10FH |
|
|
- 下面是一个关于通过PCI BIOS调用读PCI配置寄存器的例子:
-
- .386
- ;FUNCTION CODE
- PCI_FUNCTION_ID = 0B1H
- PCI_BIOS_PRESENT = 01H
- FIND_PCI_DEVICE = 02H
- FIND_PCI_CLASS_CODE = 03H
- GENERATE_SPECIAL_CYCLE = 06H
- READ_CONFIG_BYTE = 08H
- READ_CONFIG_WORD = 09H
- READ_CONFIG_DWORD = 0AH
- WRITE_CONFIG_BYTE = 0BH
- WRITE_CONFIG_WORD = 0CH
- WRITE_CONFIG_DWORD = 0DH
- GET_IRQ_ROUTING_OPTIONS = 0EH
- SET_PCI_IRQ = 0FH
- ;RETURN CODE
- SUCCESSFUL = 00H
- FUNC_NOT_SUPPORTED = 81H
- BAD_VENDOR_ID = 83H
- DEVICE_NOT_FOUND = 86H
- BAD_REGISTER_NUMBER = 87H
- SET_FAILED = 88H
- BUFFER_TOO_SMALL = 89H
- VID = 0H
- DID = 2H
- PCICMD = 4H
- PCISTS = 6H
- RID = 8H
- CLCD = 9H
- CALN = 0CH
- LAT = 0DH
- HDR = 0EH
- BIST = 0FH
- BADR0 = 10H
- BADR1 = 14H
- BADR2 = 18H
- BADR3 = 1CH
- BADR4 = 20H
- BADR5 = 24H
- EXPOM = 30H
- INTLN = 3CH
- INTPIN = 3DH
- MINGNT = 3EH
- MAXLAT = 3FH
- SSTACK SEGMENT STACK PARA USE16
- DW 64 DUP(?)
- SSTACK ENDS
- DATA SEGMENT PARA USE16
- MES DB ' PCI CARD NOT FOUND! $'
- MES0 DB '***********************PCI CONFIG INFO*****************************',13,10,'$'
- MES1 DB 'PCI BIOS NOT FOUND!',10,13,'$'
- MES2 DB ' PCI CONFIG READ ERROR! $'
- MES3 DB ' Vendor Identification: 10E8$'
- MES4 DB ' Device Identification: 5933$'
- MES5 DB ' PCI Command Register: $'
- MES6 DB ' PCI Status Register: $'
- MES7 DB ' Revision Identification Register: $'
- MES8 DB ' Class Code Register: $'
- MES9 DB ' Cache Line Size Register: $'
- MES10 DB ' Master Latency Timer: $'
- MES11 DB ' Header Type: $'
- MES12 DB ' Built-in Self-test: $'
- MES13 DB ' Base Address Register0: $'
- MES14 DB ' Base Address Register1: $'
- MES15 DB ' Base Address Register2: $'
- MES16 DB ' Base Address Register3: $'
- MES17 DB ' Base Address Register4: $'
- MES18 DB ' Base Address Register5: $'
- MES19 DB ' Expansion Rom Base Address: $'
- MES20 DB ' Interrupt Line: $'
- MES21 DB ' Interrupt Pin: $'
- MES22 DB ' Minimum Grant: $'
- MES23 DB ' Maximum Latency: $'
- BN DB ?
- DN_FN DB ?
- R_VALUE DD ?
- V_VID DW ?
- V_DID DW ?
- V_PCICMD DW ?
- V_PCISTS DW ?
- V_RID DB ?
- V_CLCD DD ?
- V_CALN DB ?
- V_LAT DB ?
- V_HDR DB ?
- V_BIST DB ?
- V_BADR0 DD ?
- V_BADR1 DD ?
- V_BADR2 DD ?
- V_BADR3 DD ?
- V_BADR4 DD ?
- V_BADR5 DD ?
- V_EXPOM DD ?
- V_INTLN DB ?
- V_INTPIN DB ?
- V_MINGNT DB ?
- V_MAXLAT DB ?
- DATA ENDS
- CODE SEGMENT PARA USE16
- ASSUME CS:CODE,DS:DATA,SS:SSTACK
- START: MOV AX,DATA
- MOV DS,AX
- MOV AX,0B101H ;查找PCI BIOS
- INT 1AH
- JNC JUDGE1 ;如果CF被置位,则PCI BIOS不存在
- MOV DX,OFFSET MES1 ;显示不存在信息
- MOV AH,09H
- INT 21H
- JMP EXIT
- JUDGE1: CMP AH,00H
- JZ JUDGE2 ;如果不等,则PCI BIOS 不存在
- MOV DX,OFFSET MES1 ;显示不存在信息
- MOV AH,09H
- INT 21H
- JMP EXIT
- JUDGE2: CMP EDX,' ICP' ;如果EDX中放的是"PCI "则说明PCI BIOS存在
- JZ FIND
- MOV DX,OFFSET MES1 ;否则错误的设备
- MOV AH,09H
- INT 21H
- JMP EXIT
- FIND: MOV AX,0B102H ;找到了PCI BIOS,再查找指定PCI设备
- MOV CX,5933H ;板卡的设备的ID
- MOV DX,10E8H ;板卡的供应商ID
- MOV SI,0 ;索引
- INT 1AH
- JNC READ
- MOV DX,OFFSET MES
- MOV AH,09H
- INT 21H
- JMP EXIT
- READ: MOV BN,BH ;保存总线号
- MOV DN_FN,BL ;保存设备号
- CALL KENTER ;回车换行
- MOV DX,OFFSET MES0
- MOV AH,09H
- INT 21H
- CALL KENTER ;回车换行
- MOV DX,OFFSET MES3 ;输出供应厂商ID
- MOV AH,09H
- INT 21H
- CALL KENTER
- MOV DX,OFFSET MES4 ;输出设备的ID
- MOV AH,09H
- INT 21H
- CALL KENTER
- MOV AX,0B109H ;读命令寄存器,单字操作
- MOV BH,BN
- MOV BL,DN_FN
- MOV DI,PCICMD
- INT 1AH
- JC ERROR
- MOV DX,OFFSET MES5 ;显示PCI命令寄存器内容
- MOV AH,09H
- INT 21H
- MOV AX,02H
- CALL SHOW
- CALL KENTER
- MOV AX,0B109H ;读PCI状态寄存器内容,单字操作
- MOV BH,BN
- MOV BL,DN_FN
- MOV DI,PCISTS
- INT 1AH
- JC ERROR
- MOV DX,OFFSET MES6 ;显示状态寄存器内容
- MOV AH,09H
- INT 21H
- MOV AX,02H
- CALL SHOW
- CALL KENTER
- MOV AX,0B108H ;版本号,单字节操作
- MOV BH,BN
- MOV BL,DN_FN
- MOV DI,RID
- INT 1AH
- JC ERROR
- MOV DX,OFFSET MES7 ;显示版本号
- MOV AH,09H
- INT 21H
- MOV AX,01H
- CALL SHOW
- CALL KENTER
- MOV AX,0B108H ;读中断引脚信号,单字节操作
- MOV BH,BN
- MOV BL,DN_FN
- MOV DI,INTLN
- INT 1AH
- JC ERROR
- MOV DX,OFFSET MES20 ;显示中断引脚
- MOV AH,09H
- INT 21H
- MOV AX,01H
- CALL SHOW
- CALL KENTER
- MOV AX,0B10AH ;读配置寄存器,双字操作
- MOV BH,BN ;PCI设备的总线号
- MOV BL,DN_FN ;设备以及功能号,入口参数
- MOV DI,BADR0
- INT 1AH
- JC ERROR
- MOV DX,OFFSET MES13 ;基址寄存器0
- MOV AH,09H
- INT 21H
- MOV AX,04H
- CALL SHOW
- CALL KENTER
- MOV AX,0B10AH ;读配置寄存器,双字操作
- MOV BH,BN ;PCI设备的总线号
- MOV BL,DN_FN ;设备及功能号,入口参数
- MOV DI,BADR1
- INT 1AH
- JC ERROR
- PUSH ECX
- MOV DX,OFFSET MES14 ;基址寄存器1
- MOV AH,09H
- INT 21H
- MOV AX,04H
- POP ECX
- CALL SHOW
- CALL KENTER
- MOV AX,0B10AH ;读配置寄存器,双字操作
- MOV BH,BN ;PCI设备的总线号
- MOV BL,DN_FN ;设备及功能号,入口参数
- MOV DI,BADR2
- INT 1AH
- JC ERROR
- MOV DX,OFFSET MES15 ;基地址寄存器2
- MOV AH,09H
- INT 21H
- MOV AX,04H
- CALL SHOW
- CALL KENTER
- MOV AX,0B10AH ;读配置寄存器,双字操作
- MOV BH,BN ;PCI设备的总线号
- MOV BL,DN_FN ;设备及功能号,入口参数
- MOV DI,BADR3
- INT 1AH
- JC ERROR
- MOV DX,OFFSET MES16 ;基地址寄存器3
- MOV AH,09H
- INT 21H
- MOV AX,04H
- CALL SHOW
- CALL KENTER
- MOV AX,0B10AH ;读配置寄存器,双字操作
- MOV BH,BN ;PCI设备的总线号
- MOV BL,DN_FN ;设备及功能号,入口参数
- MOV DI,BADR4
- INT 1AH
- JC ERROR
- MOV DX,OFFSET MES17 ;基地址寄存器4
- MOV AH,09H
- INT 21H
- MOV AX,04H
- CALL SHOW
- JMP EXIT
- ERROR: CALL KENTER
- MOV DX,OFFSET MES2 ;显示读错误信息
- MOV AH,09H
- INT 21H
- EXIT: MOV AH,4CH ;返回DOS
- INT 21H
- KENTER PROC
- MOV DL,0AH
- MOV AH,02H
- INT 21H
- MOV DL,0DH
- MOV AH,02H
- INT 21H
- RET
- KENTER ENDP
- SHOW PROC NEAR ;显示子程序
- PUSH DX
- PUSH DI
- PUSH BX
- MOV DI,OFFSET R_VALUE
- MOV [DI],ECX ;保存获取的数据
- ADD DI,AX
- DEC DI
- MOV CX,AX
- C1: MOV AL,[DI]
- PUSH AX
- SHR AL,4
- AND AL,0FH ;取高4位
- CMP AL,0AH ;是否是A以上的数
- JB C2
- ADD AL,07H
- C2: ADD AL,30H
- MOV BH,AL
- POP AX
- AND AL,0FH ;取低4位
- CMP AL,0AH
- JB C3
- ADD AL,07H
- C3: ADD AL,30H
- MOV BL,AL
- MOV AH,2 ;显示十六进制数对应的ACSII码
- MOV DL,BH
- INT 21H
- MOV DL,BL
- INT 21H
- DEC DI
- LOOP C1
- POP BX
- POP DI
- POP DX
- RET
- SHOW ENDP
- CODE ENDS
- END START
推荐阅读最新更新时间:2024-05-03 00:40