PCI总线和设备树是硬件体系内很重要的组成部分,几乎所有的外围硬件都以这样或那样的形式连接到PCI设备树上。虽然Intel为了方便各种IP的接入而提出IOSF总线,但是其主体接口(primary interface)还依然是PCIe形式。我们先从软件角度去理解PCIE,这样会更容易理解,因为PCIE难点在于硬件实现,它简化了很多硬件物理层协议。
PCI Express Technology》,Mike Jackson, Ravi Budruk; MindShare, Inc;PCIe扫盲系列博文》,作者Felix,这是对《PCI Express Technology》的理解与翻译;PCI EXPRESS体系结构导读 (王齐)》;PCI Express_ Base Specification Revision 4.0 Version 0.3 ( PDFDrive )》;NCB-PCI_Express_Base_5.0r1.0-2019-05-22》Linux驱动开发》韦东山在学习PCI/PCIE之前,我们要回归原点,CPU访问最容易的设备就是内存,我们访问内存只需要知道他的地址,然后通过指针直接访问即可,如下:
volatile unsigned int *p = 某个地址;
unsigned int val;
*p = val; /* 写 */
val = *p; /* 读 */
除了上述的内存外,还有很多设备也支持这样的访问模式,他们被统一成为“ram-like”接口
ram-like接口特点如下:
ram-like"设备共享上面的信号,怎么才能互不影响?每个设备都有自己的片选信号。ram-like体系如下图:
CPU访问RAM、Flash和GPIO等设备都是通过访问内存控制器去间接性访问这些设备;如下图,就是CPU接口通过PCIE控制器访问PCIE设备示意图:



PCI/PCIe设备上有配置空间(配置寄存器),用来表明自己"需要多大的地址空间"。
PCI/PCIe地址空间。主机上的程序访问PCI/PCIe设备,读出配置信息。
分配地址空间:注意,分配的是PCI/PCIe地址空间。
把地址空间首地址写入设备。
假设CPU发出的addr_cpu,是用来方位PCI设备的,转换关系为:
PCI/PCIe控制器中,有某个寄存器,有来保存offset值。addr_pci = addr_cpu + offset
volatile unsigned int *p = addr_cpu;
unsigned int val;
*p = val; /* 写, 硬件会把addr_cpu转换为addr_pci去写PCI/PCIe设备 */
val = *p; /* 读, 硬件会把addr_cpu转换为addr_pci去读PCI/PCIe设备 */
