Fork me on GitHub
侧边栏

PCIE driver中RANGE的解释

my_pcie_0: pcie@10000000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "mypcie";
device_type = "pcie";
reg = < 0x40000000 0x00100000 >;
ranges = < 0x02000000 0 0xf0000000 0xf00000000 0x0 0x08000000>;
} 

PCIe设备树中的ranges属性定义了PCI地址空间与CPU物理地址空间之间的映射关系,其核心作用如下:


1. 地址转换规则

  • 三元组结构
    每个ranges条目由三个字段组成:

    <子地址空间类型 子地址范围 父地址范围 大小>
    
    • 子地址:PCI设备视角的地址(如PCI总线地址)。
    • 父地址:CPU物理地址(如SoC的内存控制器地址)。
    • 大小:映射区域的长度[[1]][[4]][[6]]。

    示例(来自知识库):

    ranges = <0x02000000 0 0xf0000000 0x0 0xf0000000 0x0 0x10000000>;
    

    表示将PCI地址0xf0000000开始的256MB(0x10000000)非预取内存区域,映射到CPU的0xf0000000地址[[1]][[5]]。


2. 映射类型与属性

  • 地址空间类型
    • 0x02000000:表示32-bit非预取内存空间(PCI_ADDRESS_SPACE_MEM)[[1]][[6]]。
    • 0x42000000:表示64-bit非预取内存空间(若支持64-bit BAR)[[5]][[9]]。
  • 预取属性
    若地址支持预取(如显存),需通过标志位(如PCI_BAR_MEM_PREFETCH)标识,以优化性能[[5]][[7]]。

3. 功能与用途

  • 资源访问
    CPU通过父地址(如0xf0000000)访问PCI设备的BAR空间(如寄存器或DMA缓冲区),而PCI设备通过子地址解码TLP包目标地址[[4]][[9]]。
  • 内存一致性
    若映射为可预取内存,需确保DMA操作与CPU缓存一致性(如通过dma_coherent_mask)[[5]][[6]]。
  • 桥接配置
    PCIe桥(如RC)的ranges属性还定义了下游总线地址到上游总线的转换规则,支持多层级地址路由[[8]][[10]]。

4. 解析与验证

  • 内核处理
    Linux内核在PCI枚举阶段解析ranges属性,生成struct resource并配置MMU或PCI控制器,实现地址转换[[4]][[7]]。
  • 调试方法
    通过/proc/iomemlspci -vv查看PCI设备的BAR映射是否与设备树ranges一致[[5]][[9]]。

可以用下面为例:

[arch/arm64/boot/dts/rockchip/rk3588.dtsi]
pcie3x4: pcie@fe150000 {
    ......
    #address-cells = <3>
    #size-cells = <2>;
    /*           PCI地址标志  PCI地址高32位  PCI地址低32位 CPU地址高32位  CPU地址低32位 地址长度高32位 地址长度低32位 */
	ranges = <    0x00000800     0x0       0xf0000000     0x0        0xf0000000     0x0       0x100000
			      0x81000000     0x0       0xf0100000     0x0        0xf0100000     0x0       0x100000
			      0x82000000     0x0       0xf0200000     0x0        0xf0200000     0x0       0xe00000
			      0xc3000000     0x9       0x00000000     0x9        0x00000000     0x0       0x40000000>;
    ......
};

[arch/arm64/boot/dts/renesas/r8a774b1.dtsi]
pciec0: pcie@fe000000 {
    ......
    #address-cells = <3>;
    #size-cells = <2>;
    /* Map all possible DDR as inbound ranges */
    /*          PCI地址标志  PCI地址高32位  PCI地址低32位 CPU地址高32位  CPU地址低32位 地址长度高32位 地址长度低32位 */
    dma-ranges = <0x42000000      0        0x40000000        0        0x40000000       0       0x80000000>;
    ......
};

https://stackoverflow.com/questions/29839805/pcie-device-tree-ranges-property-explanation

posted @ 2025-03-19 23:15  yooooooo  阅读(555)  评论(0)    收藏  举报