pci note 4
==========
-v0.1 2015.6.20 Sherlock draft: about pci resource assignment, just analysis
ARM specific PCIe
-v0.2 2015.6.22 Sherlock add introduction, some details analysis
有些机器没有中文输入法,就成了现在中英杂揉了 :(
linux kernel中pci分配资源的代码比较复杂,下面先总体介绍大体的流程,有了一个整体
概念后再去理解细节就比较容易一些了。
整个资源分配的过程就是从系统的总资源里给每个pci设备的bar分配资源,给每个pci桥
的base, limit的寄存器分配资源。借用这个系列笔记一中的图,资源分配所要做的就是填写
pci ep设备和pci桥中配置空间的寄存器,从总的资源(这里假设soc系统给这个pci host
bridge分配的资源是 0xb200_0000 ~ 0xb400_0000)给pci桥上的base/limit寄存器分资源,
给pci ep设备上的Bar分资源。
现在已知的是:
1. resource: 0xb200_0000 ~ 0xb400_0000. 这个是系统早就分好的。pcie dts节点中的range项是其的一个子集。
所有分配可以用pci_assign_unassigned_bus_resources完成。
__pci_bus_size_bridges用深度优先递归确定各级pci桥上base/limit的大小。会记录在
pci_dev->resource[PCI_BRIDGE_RESOURCES] ...中,这时并没有在寄存器中写入数值。
__pci_bus_assign_resources()首先对当前总线下的设备请求的资源排序,这个资源中包括
总线下的设备上的bar; 总线下游请求的资源,即base/limit下的资源。对于该总线下设备
上的bar资源,在下面__assign_resources_sorted的调用链中立即分配, pci桥上的base/limit
则先不分配。__pci_bus_assign_resources()中再次用深度优先递归的办法,依次分配各个
pci ep设备上的bar资源,在每个递归向上返回的过程中调用__pci_bus_size_bridges()
设置pci桥上的base/limit寄存器。
下面用具体例子再详细解释一下分配过程, 是用的例子是直接在pci host bridge上插
一个pcie ep设备:
==========
-v0.1 2015.6.20 Sherlock draft: about pci resource assignment, just analysis
ARM specific PCIe
-v0.2 2015.6.22 Sherlock add introduction, some details analysis
有些机器没有中文输入法,就成了现在中英杂揉了 :(
linux kernel中pci分配资源的代码比较复杂,下面先总体介绍大体的流程,有了一个整体
概念后再去理解细节就比较容易一些了。
整个资源分配的过程就是从系统的总资源里给每个pci设备的bar分配资源,给每个pci桥
的base, limit的寄存器分配资源。借用这个系列笔记一中的图,资源分配所要做的就是填写
pci ep设备和pci桥中配置空间的寄存器,从总的资源(这里假设soc系统给这个pci host
bridge分配的资源是 0xb200_0000 ~ 0xb400_0000)给pci桥上的base/limit寄存器分资源,
给pci ep设备上的Bar分资源。
现在已知的是:
1. resource: 0xb200_0000 ~ 0xb400_0000. 这个是系统早就分好的。pcie dts节点中的range项是其的一个子集。
2. pci ep设备有多少个bar和各个bar的信息, 这些信息已经存在了对应的pci_dev->resource[]中了。
大体流程是:
所有分配可以用pci_assign_unassigned_bus_resources完成。
__pci_bus_size_bridges用深度优先递归确定各级pci桥上base/limit的大小。会记录在
pci_dev->resource[PCI_BRIDGE_RESOURCES] ...中,这时并没有在寄存器中写入数值。
__pci_bus_assign_resources()首先对当前总线下的设备请求的资源排序,这个资源中包括
总线下的设备上的bar; 总线下游请求的资源,即base/limit下的资源。对于该总线下设备
上的bar资源,在下面__assign_resources_sorted的调用链中立即分配, pci桥上的base/limit
则先不分配。__pci_bus_assign_resources()中再次用深度优先递归的办法,依次分配各个
pci ep设备上的bar资源,在每个递归向上返回的过程中调用__pci_bus_size_bridges()
设置pci桥上的base/limit寄存器。
下面用具体例子再详细解释一下分配过程, 是用的例子是直接在pci host bridge上插
一个pcie ep设备: