PCI协议是一套工业标准,这个就不细说了,这套协议有点类型IP协议,由多种不同功能的设备组成,主要是主机,主设备, bridge(桥) ,从设备等等组成, PCI bridge 类似于IP协议里面的 路由器, 链接自己的bus(有一个独立无一的bus id)到主的总线,它的主要作用是转发两个bus间的通信。
1)BUS Operation.
1.1) BUS command
0000 Interrupt Acknowledge
0001 Special Cycle
0010 I/O Read
0011 I/O Write
0100 Reserved
0101 Reserd
0110 Memory Read
0111 Memory Write
1000 Reserved
1001 Reserved
1010 Configuration Read
1011 Configuration Write
1100 Memory Read Multiple
1101 Dual Address Cycle
1110 Memory Read Line
1111 Memory Write and Invalidate
1.1.2) Read commands
Memory Read command 读一个DWORD bytes
Memory Read Line command 读一个cache line size bytes
Memory Read Multiple command 读一个包含多个cache line 的 block.
1.1.3) Write command
1.1.4) 设备选择(Device selection)
1.1.5) 设备配置
PCI 定义为驱动软件提供了初始化和配置,通过一个单独的配置空间(memory)(独立于读写空间(memory). 每个设备只解析它自己的地址, 在配置阶段, 设备选择需要在访问前完成, 通过 PCI的IDSEL pin给设备传入信号,也就是 “片选”信号,表明该设备被选取。如何实现IDSEL是一个系统规范,不是PCI规范。 通常情况下:设备0的IDSEL,对应"地址寄存器"的16位, 设备1对应17位,依次类推, 设备0~设备16的片选(IDSEL)分别对应地址寄存器的[16..31] 位。 主机通过设置 状态寄存器里面的Master-Abort位来终止配置。 有两种配置类型寄存器,都是32bit。
type 0: 31-{reserved} -11 10-{ Function number}-8 7-{ Register number}-2 1-{ 0 }-1 0-{0}-0
type 1: 31-{reserved} -23 23-{bus number} -16 15-{device-number}-11 10-{ Function number}-8 7-{ Register number}-2 1-{ 0 }-1 0-{1}-0
type 0 只在本地总线内使用,Host,bridges 使用 type 0来配置挂在它们各自总线下的设备。
type 1 用来配置其它 bus 的设备。 如 主机需要配置某个 bridge,就使用type 0,如果配置某个该bridge后面的某个设备,就需要使用type 1。
响应 type 0的设备 主要分别两种类型:1)往前兼容的设备(老设备)2) 多功能设备(multi-function device).
device number 占5位,最大可以选择32个设备,但是由于 IDSEL对应 AD[31..11]只有21位,分别对应设备0~设备20,实际上最大只能支持21个设备。
function number 最大的功能号是8, 功能号0是PCI设备必须实现的,其它功能不是必须的。
驱动配置代码,根据device number的次序,逐步检测(此时 function number 为0),如果检测到一个多功能设备,则依次检测function number.
系统必须提供给软件提供接口,产生一个配置流(configure cycles),有两种机制用来产生这样的配置流(configure cycles).
配置机制1 : 使用 (CF8h) 作为 CONFIG_ADDRESS, (CFCh) 作为 CONFIG_DATA.
配置的过程是这样的, 两个I/O寄存器分别是 CONFIG_ADDRESS(CF8h) 和 CONFIG_DATA(CFCh)。 CONFIG_ADDRESS 选择 BUS,device,然后再通过 CONFIG_DATA 写入数据(CONFIG_ADDRESS 的第31位必须是1)。
配置机制2: 主要是为了向前兼容,不建议使用。映射 4k的PCI配置空间到PC的内存(C000h ~ CFFFh)。
配置空间enable需要写 I/O port CF8h 的CSE位。
7-{KEY}-4 3-{FUNCTION NUMBER}-1 0-{SCE}-0
转发寄存器 I/O port CFAh 用来表明 那一个bus 被访问,如果 它的值是 0,那么 该bridge的本地总线被访问, 发起一个type 0的访问,否则 bridge转发 数据到其它 pci桥, 发起一个type 1的配置访问。
2) 配置空间
type 0 配置空间 总共 256个字节: 依次是 Vendor ID, Device ID, command, status, revision id, class code, cache line size, latency timer, Header type, BIST, Base Address register, cardbus CIS Point, Sub Vender ID, subsystem ID, Expansion ROM Base Address, interrupt Line , interrput Pin, Min_Gnt, Max_Lat.
Vendor ID, device ID, Sub Vendor ID, subsystem ID 这些都是工业标准确定的,比如: (Vendor ID)0x1002 代表 "ATI Technologies" , 0x4752 表示是 "ATI Rage XL PCI" 等等,这些都是 PCI相关的组织分配的。
class code: 用来标识 device的通用功能, 3个字节大小, 高字节(offset 0B)是 基本的类别代码,标识一些通用的功能, 中间字节(offset 0A)是子类别,低字节是 编码级别的接口,标识详细的功能类别。
00h Device was built before Class Code, definitions were finalized.
01h Mass storage controller.
02h Network controller.
03h Display controller.
04h Multimedia device.
05h Memory controller.
06h Bridge device.
07h Simple communication controllers.
08h Base system peripherals.
09h Input devices.
0Ah Docking stations.
0Bh Processors.
0Ch Serial bus controllers.
0Dh - FEh Reserved.
FFh Device does not fit in any defined classes.
cache line size : PCI设备的读写功能, 如:read, read line, read multiple line. 数据大小就是 line * cache line size.
BIST : build-in Self-Test.
Interrupt line 设置那些输入产生中断, 主要是被设备驱动程序和操作系统使用。
BASE ADDRESS : 这是 最重要的功能之一, 应用程序可以重新分配各个 设备在内存的地址映射地址。 当PC启动的时候,BIOS会检测所有的PCI设备,然后,把它们映射到相应的内存地址。 以后,直接通过内存地址就可以访问到pci设备的内存,寄存器空间。 映射分为2种模式,分别是映射到内存空间或者I/O空间。 PCI设备可以同时使用两种映射,可以分别通过 内存空间或者I/O空间来访问同一PCI设备。 BASE ADDRESS的bit 0, 0-表明是 内存映射, 1-表明是I/O映射。
Memory Base Address Register Bits 2/1 Encoding
00 Base register is 32 bits wide and mapping can be done anywhere in the 32-bit Memory Space.
01 Base register is 32 bits wide but must be mapped below 1M in Memory Space.
10 Base register is 64 bits wide and can be mapped anywhere in the 64-bit address space.
11 Reserved
应用程序通过 把 BASE ADDRESS全部写入1,可以得到相应设备所需要的内存大小。
一个典型的设备一般是把“控制功能” 映射到一个内存区域, 也有设备映射到两个不同内存区域的,比如显卡, 它把“控制功能”映射到一个区域, 把 frame buffer映射到另一个区域。
Expansion ROM Base Address 有些PCI设备会提供附加的ROM,应用程序可以映射ROM到相应的内存地址。
参考文章
"PCI Local Bus Specification"