06 June 2014

PCI 简介

PCI(Periheral Component Interconnect)有三种地址空间:PCI I/O空间、PCI内存地址空间和PCI配置空间。

I/O 空间和内存地址空间由PCI驱动使用。 PCI配置空间由Linux PCI初始化代码使用,由内核用来进行配置,比如中断号和I/O内存基址空间。

PCI 桥

一共有三种PCI桥:

  • HOST/PCI桥(HOST bridge):用于连接CPU和PCI的桥设备
  • PCI/ISA桥 (ISA bridge):用于连接PCI总线和ISA总线的桥
  • PCI-PCI桥(PCI-PCI bridge):用于PCI总线的扩展 下图展示了pci桥的层次连接:

pci bridge connection

在使用PCI设备之前,Linux Knerle需要对其进行枚举和配置。 枚举的结果就将是一个树状的结构,根是HOST/PCI桥。

配置PCI设备

Linux kernel 对PCI配置空间进行配置。这个PCI配置空间其实就是一些寄存器,称为配置寄存器组。 当PCI设备尚未被激活的时候,它只对配置事务响应。设备上是不会有I/O端口映射到计算机的内存空间的。 中断也会被禁止。

PCI设备的地址空间

所有PCI设备的配置空间寄存器组都采用相同的地址,由总线的PCI桥在访问时附加上其他条件进行区分。 对于CPU来说,它通过一个统一的入口地址HOST/PCI桥,即树型结构的根发出指令,再由相应的PCI桥间接地完成具体的读写。 这个PCI桥(或者称PCI总线)包含两个寄存器,’地址寄存器’和’数据寄存器’,CPU向’地址寄存器’写入要访问的地址,然后通过’数据寄存器’读取数据。 地址寄存器的地址组成: 总线号:设备号:功能号:寄存器号 示例,lspci 输出:

  • 0000 : PCI domain (each domain can contain up to 256 PCI buses)
  • 04 : the bus number the device is attached to
  • 00 : the device number
  • .0 : PCI device function

访问PCI设备的几种方式

  • 通过访问I/O端口, I/O 地址空间一般不关联到系统内存,因为端口也可以映射到内存中,会引起混淆;
  • I/O 内存映射,就是我们通常说的MMIO,即将特定外设的端口地址映射到普通内存中。cpu可以像普通内存一样操作设备。内核通过ioremap和iounmap命令用于映射I/O内存
  • 轮询和中断,显然中断是更好的方式。

PCI的BAR(base address register)

BAR是PCI配置空间中从0x10 到 0x24的6个register,用来定义PCI需要的配置空间大小以及配置PCI设备占用的地址空间。 X86的地址空间分为,IO 和 MEM 两类,PCI的BAR的某一位决定了设备需要映射到MEM空间还是IO空间。 POWERPC只有MEM空间(IO空间不单独编址)。



blog comments powered by Disqus