PCIE协议解析 synopsys IP Configuration Space Header 读书笔记
Posted yijingjing17
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PCIE协议解析 synopsys IP Configuration Space Header 读书笔记相关的知识,希望对你有一定的参考价值。
5.1.7.1 PF PCI-Compatible Configuration Space Header – Type 0
Byte Offset | Byte 3 | Byte 2 | Byte 1 | Byte 0 |
0x00 | Device ID(ROS) | Vendor ID(ROS) | ||
0x04 | Status Register(ROS) | Command Register(RW) | ||
x08 | Class Code(ROS) | Revision ID | ||
0x0C | BIST(0x00)(RO) | Header Type(ROS) | Latency Timer(RO) | Cache Line Size(RW) |
0x10 | Base Address Register 0 | |||
0x14 | Base Address Register 1 | |||
0x18 | Base Address Register 2 | |||
0x1C | Base Address Register 3 | |||
0x20 | Base Address Register 4 | |||
0x24 | Base Address Register 5 | |||
0x28 | CardBus CIS Pointer RO(cs) | |||
0x2C | Subsystem ID RO(cs) | Subsystem Vendor ID RO(cs) | ||
0x30 | Expansion ROM Base Address (RW) | |||
0x34 | Reserved | CapPtr | ||
0x38 | Reserved | |||
0x3C | Max_Latency1 RO(cs) | Min_Grant1 RO(cs) | Interrupt Pin RO(cs) | Interrupt Line |
其中,用户需要配置的寄存器主要包括为以下两个:
1、 Command Register(RW)
2、 Base Address Register
以下来自王齐老师的书:
(1) Device ID和Vendor ID寄存器
这两个寄存器的值由PCISIG分配,只读。其中Vendor ID代表PCI设备的生产厂商,而Device ID代表这个厂商所生产的具体设备。如Intel公司的基于82571EB芯片的系列网卡,其Vendor ID为0x8086[1],而Device ID为0x105E[2]。
(2) Revision ID和Class Code寄存器
这两个寄存器只读。其中Revision ID寄存器记载PCI设备的版本号。该寄存器可以被认为是Device ID寄存器的扩展。
(3) Header Type寄存器
该寄存器只读,由8位组成。
第7位为1表示当前PCI设备是多功能设备,为0表示为单功能设备。
第6~0位表示当前配置空间的类型,为0表示该设备使用PCI Agent设备的配置空间,普通PCI设备都使用这种配置头;为1表示使用PCI桥的配置空间,PCI桥使用这种配置头;为2表示使用Cardbus桥片的配置空间,Card Bus桥片使用这种配置头,本篇对这类配置头不感兴趣。
系统软件需要使用该寄存器区分不同类型的PCI配置空间,该寄存器的初始化必须与PCI设备的实际情况对应,而且必须为一个合法值。
(4) Cache Line Size寄存器
该寄存器记录HOST处理器使用的Cache行长度。在PCI总线中和Cache相关的总线事务,如存储器写并无效和Cache多行读等总线事务需要使用这个寄存器。值得注意的是,该寄存器由系统软件设置,但是在PCI设备的运行过程中,只有其硬件逻辑才会使用该寄存器,比如PCI设备的硬件逻辑需要得知处理器系统Cache行的大小,才能进行存储器写并无效总线事务,单行读和多行读总线事务。
如果PCI设备不支持与Cache相关的总线事务,系统软件可以不设置该寄存器,此时该寄存器为初始值0x00。对于PCIe设备,该寄存器的值无意义,因为PCIe设备在进行数据传送时,在其报文中含有一次数据传送的大小,PCIe总线控制器可以使用这个“大小”,判断数据区域与Cache行的对应关系。
(5) Subsystem ID和Subsystem Vendor ID寄存器
这两个寄存器和DeviceID和Vendor ID类似,也是记录PCI设备的生产厂商和设备名称。但是这两个寄存器和Device ID与Vendor ID寄存器略有不同。下文以一个实例说明Subsystem ID和Subsystem Vendor ID的用途。
Xilinx公司在FGPA中集成了一个PCIe总线接口的IP核,即LogiCORE。用户可以使用LogiCORE设计各种各样基于PCIe总线的设备,但是这些设备的Device ID都是0x10EE,而Vendor ID为0x0007[3]。
(6) Expansion ROM base address寄存器
有些PCI设备在处理器还没有运行操作系统之前,就需要完成基本的初始化设置,比如显卡、键错误!超链接引用无效。盘和硬盘等设备。为了实现这个“预先执行”功能,PCI设备需要提供一段ROM程序,而处理器在初始化过程中将运行这段ROM程序,初始化这些PCI设备。Expansion ROM base address记载这段ROM程序的基地址。
(7) Capabilities Pointer寄存器
在PCI设备中,该寄存器是可选的,但是在PCI-X和PCIe设备中必须支持这个寄存器,Capabilities Pointer寄存器存放Capabilities寄存器组的基地址,PCI设备使用Capabilities寄存器组存放一些与PCI设备相关的扩展配置信息。该组寄存器的详细说明见第4.3节。
(8) Interrupt Line寄存器
这个寄存器是系统软件对PCI设备进行配置时写入的,该寄存器记录当前PCI设备使用的中断向量号,设备驱动程序可以通过这个寄存器,判断当前PCI设备使用处理器系统中的哪个中断向量号,并将驱动程序的中断服务例程注册到操作系统中[4]。
该寄存器由系统软件初始化,其保存的值与8259A中断控制器相关,该寄存器的值也是由PCI设备与8259A中断控制器的连接关系决定的。如果在一个处理器系统中,没有使用8259A中断控制器管理PCI设备的中断,则该寄存器中的数据并没有意义。
在多数PowerPC处理器系统中,并不使用8259A中断控制器管理PCI设备的中断请求,因此该寄存器没有意义。即使在x86处理器系统中,如果使用I/O APIC中断控制器,该寄存器保存的内容仍然无效。目前在绝大多数处理器系统中,并没有使用该寄存器存放PCI设备使用的中断向量号。
(9) Interrupt Pin寄存器
这个寄存器保存PCI设备使用的中断引脚,PCI总线提供了四个中断引脚INTA#、INTB#、INTC#和INTD#。Interrupt Pin寄存器为1时表示使用INTA#引脚向中断控制器提交中断请求,为2表示使用INTB#,为3表示使用INTC#,为4表示使用INTD#。
如果PCI设备只有一个子设备时,该设备只能使用INTA#;如果有多个子设备时,可以使用INTB~D#信号。如果PCI设备不使用这些中断引脚,向处理器提交中断请求时,该寄存器的值必须为0。值得注意的是,虽然在PCIe设备中并不含有INTA~D#信号,但是依然可以使用该寄存器,因为PCIe设备可以使用INTx中断消息,模拟PCI设备的INTA~D#信号,详见第6.3.4节。
(10) Base Address Register 0~5寄存器
该组寄存器简称为BAR寄存器,BAR寄存器保存PCI设备使用的地址空间的基地址,该基地址保存的是该设备在PCI总线域中的地址。其中每一个设备最多可以有6个基址空间,但多数设备不会使用这么多组地址空间。
在PCI设备复位之后,该寄存器将存放PCI设备需要使用的基址空间大小,这段空间是I/O空间还是存储器空间[5],如果是存储器空间该空间是否可预取,有关PCI总线预读机制的详细说明见第3.4.5节。
系统软件对PCI总线进行配置时,首先获得BAR寄存器中的初始化信息,之后根据处理器系统的配置,将合理的基地址写入相应的BAR寄存器中。系统软件还可以使用该寄存器,获得PCI设备使用的BAR空间的长度,其方法是向BAR寄存器写入0xFFFF-FFFF,之后再读取该寄存器。
处理器访问PCI设备的BAR空间时,需要使用BAR寄存器提供的基地址。值得注意的是,处理器使用存储器域的地址,而BAR寄存器存放PCI总线域的地址。因此处理器系统并不能直接使用“BAR寄存器+偏移”的方式访问PCI设备的寄存器空间,而需要将PCI总线域的地址转换为存储器域的地址。
如果x86处理器系统使能了IOMMU后,这两个地址也并不一定相等,因此处理器系统直接使用这个PCI总线域的物理地址,并不能确保访问PCI设备的BAR空间的正确性。除此之外在Linux系统中,ioremap函数的输入参数为存储器域的物理地址,而不能使用PCI总线域的物理地址。
而在pci_devàresource[bar].start参数中保存的地址已经经过PCI总线域到存储器域的地址转换,因此在编写Linux系统的设备驱动程序时,需要使用pci_devàresource[bar].start参数中的物理地址,然后再经过ioremap函数将物理地址转换为“存储器域”的虚拟地址。
(11) Command寄存器(bring up的时候需要注意????)
该寄存器为PCI设备的命令寄存器,该寄存器在初始化时,其值为0,此时这个PCI设备除了能够接收配置请求总线事务之外,不能接收任何存储器或者I/O请求。系统软件需要合理设置该寄存器之后,才能访问该设备的存储器或者I/O空间。在Linux系统中,设备驱动程序调用pci_enable_device函数,使能该寄存器的I/O和Memory Space位之后,才能访问该设备的存储器或者I/O地址空间。
(12) Status寄存器
该寄存器的绝大多数位都是只读位,保存PCI设备的状态。
(13) Latency Timer寄存器
在PCI总线中,多个设备共享同一条总线带宽。该寄存器用来控制PCI设备占用PCI总线的时间,当PCI设备获得总线使用权,并使能Frame#信号后,Latency Timer寄存器将递减,当该寄存器归零后,该设备将使用超时机制停止[6]对当前总线的使用。
如果当前总线事务为MemeoryWrite and Invalidate时,需要保证对一个完整Cache行的操作结束后才能停止当前总线事务。对于多数PCI设备而言,该寄存器的值为32或者64,以保证一次突发传送的基本单位为一个Cache行。
PCIe设备不需要使用该寄存器,该寄存器的值必须为0。因为PCIe总线的仲裁方法与PCI总线不同,使用的连接方法也与PCI总线不同。以上是关于PCIE协议解析 synopsys IP Configuration Space Header 读书笔记的主要内容,如果未能解决你的问题,请参考以下文章
PCIE协议解析 synopsys IP PCI Express Capability 读书笔记(13)
PCIE协议解析 synopsys IP Register配置空间 读书笔记
PCIE协议解析 synopsys IP 基本配置空间总结 读书笔记(14)
PCIE协议解析 synopsys IP Configuration Space Header 读书笔记