Home PCIe Memory and IO 地址空间
Post
Cancel

PCIe Memory and IO 地址空间

早期的PC中,所有的IO设备(除了存储设备之外的设备)的内部存储或者寄存器都只能通过IO地址空间进行访问。 但是这种方式局限性很大,而且效率低,于是乎,软件开发者和硬件厂商都不能忍了……然后一种新的东西就出来了——MMIO。

MMIO,即Memory Mapped IO,也就是说把这些IO设备中的内部存储和寄存器都映射到统一的存储地址空间(Memory Address Space)中。 但是,为了兼容一些之前开发的软件,PCIe仍然支持IO地址空间,只是建议在新开发的软件中采用MMIO。

注:PCIe Spec中明确指出,IO地址空间只是为了兼容早期的PCI设备(Legacy Device),在新设计中都应当使用MMIO,因为IO地址空间可能会被新版本的PCI Spec所抛弃。

IO地址空间的大小是4GB(32bits),而MMIO则取决于处理器(和操作系统),并且由处理器进行统一分配管理。

如下图所示,PCIe总线中有两种MMIO:P-MMIO和NP-MMIO。

PCIeMemoryIO

P-MMIO,即可预取的MMIO(Prefetchable MMIO);NP-MMIO,即不可预取的MMIO(Non-Prefetchable MMIO)。其中P-MMIO读取数据并不会改变数据的值。

注:P-MMIO和NP-MMIO主要是为了兼容早期的PCI设备,因为PCIe请求中明确包含了每次的传输的大小(Transfer Size),而PCI并没有这些信息。

关于Prefetchable 和 Non-Prefetchable

在PCI设备驱动开发过程中,处理板载I/O和内存空间时,常常会遇到prefetchable和nonprefetchable两词,直译为可预取和不可预取。 但是两者具体究竟是什么含义呢?在LDD3, Chapter 12: PCI Drivers一章找到了不错的解释,姑且一边翻译一边解读如下(原文:LDD3影印版 p316,Accessing the I/O and Memory Spaces 下面一段):PCI设备会实现多至六个I/O地址区间(region)。每个区间由内存或I/O地址组成。 大部分设备在内存区间实现其I/O寄存器,这样做也更合理(参考P236),不过,和普通内存不同,I/O寄存器不应该被CPU缓存, 因为每次访问可能伴随副作用(side effect,如何理解这个副作用呢?比如,有些设备的中断状态寄存器只要一读取,便自动清零; 这儿所谓副作用就是指读取某个地址时可能导致该地址内容发生变化)。 把I/O寄存器实现成内存区间的PCI设备可以通过设定其配置空间寄存器的”内存为可预取”位(bit)来标明某地址区间是否可预取。 如果内存区间被标记为可预取,那么CPU便会缓存其内容,访问时会进行各种优化方法; 相反,访问不可预取内存时就不能进行优化,因为每次访问都伴随副作用,就和I/O端口一样。 将其控制寄存器映射到内存地址范围的外设会把该范围置为不可预取,不过诸如PCI板卡上的显示内存(video memory)之类都是可预取的。

This post is licensed under CC BY 4.0 by the author.

查看linux内核版本信息

PCIe基地址寄存器(BAR)