【Linux驱动学习PCIE篇】PCIE学习(rk356x系列)

Rockchip AXI PCIe 主机控制器驱动 ------ 学习笔记

源码文件:pcie-rockchip.c

平台:Rockchip RK3399 及同系列(rk35xx)

作者:Shawn Lin, Wenrui Li (Rockchip)

基础框架参考:Synopsys Designware Host Controller + ARM PCI Host Generic Driver


目录

  1. 整体架构概览
  2. 核心数据结构
  3. 寄存器布局与定义
  4. 配置空间访问
  5. [设备树解析 ------ 硬件资源获取](#设备树解析 —— 硬件资源获取)
  6. 硬件初始化流程
  7. 中断处理体系
  8. [ATU 地址转换单元](#ATU 地址转换单元)
  9. [Probe 主流程](#Probe 主流程)
  10. 面试高频考点

1. 整体架构概览

复制代码
┌─────────────────────────────────────────────────┐
│                   CPU (AXI Bus)                  │
└────────────────────┬────────────────────────────┘
                     │
          ┌──────────▼──────────┐
          │   PCIe Controller   │
          │  (Rockchip AXI)     │
          │                    │
          │  ┌──────────────┐  │
          │  │  ATU (地址    │  │  ← Outbound: CPU→PCIe
          │  │  转换单元)    │  │  ← Inbound:  PCIe→CPU
          │  └──────────────┘  │
          │  ┌──────────────┐  │
          │  │  Config Space │  │  ← ECAM 方式访问
          │  └──────────────┘  │
          │  ┌──────────────┐  │
          │  │  Interrupt    │  │  ← INTx/MSI 中断管理
          │  │  Controller   │  │
          │  └──────────────┘  │
          └─────────┬──────────┘
                    │
          ┌─────────▼──────────┐
          │   PCIe PHY         │  ← 物理层 (SerDes)
          └─────────┬──────────┘
                    │
          ┌─────────▼──────────┐
          │   PCIe Endpoint    │  ← 下游设备 (网卡/NVMe等)
          └────────────────────┘

关键设计特点:

  • 基于 Designware IP 核,复用其寄存器布局
  • 采用 ECAM (Enhanced Configuration Access Mechanism) 访问配置空间
  • 双寄存器基址:axi-base(数据传输/配置空间) 和 apb-base(内部控制寄存器)
  • 支持 1/2/4 lane,Gen1(2.5GT/s) 和 Gen2(5GT/s)

2. 核心数据结构

c 复制代码
struct rockchip_pcie {
    // ===== 寄存器基址 =====
    void __iomem *reg_base;   // AXI 总线接口 (配置空间访问、数据传输)
    void __iomem *apb_base;   // APB 总线接口 (控制器内部寄存器)

    // ===== PHY =====
    struct phy *phy;          // PCIe 物理层 (SerDes PHY)

    // ===== 复位信号 (共7个) =====
    struct reset_control *core_rst;        // 核心复位
    struct reset_control *mgmt_rst;        // 管理接口复位
    struct reset_control *mgmt_sticky_rst; // 粘性管理复位 (热复位时保持状态)
    struct reset_control *pipe_rst;        // PIPE 接口复位 (连接 PHY)
    struct reset_control *pm_rst;          // 电源管理复位
    struct reset_control *aclk_rst;        // ACLK 时钟域复位
    struct reset_control *pclk_rst;        // PCLK 时钟域复位

    // ===== 时钟 (共4个) =====
    struct clk *aclk_pcie;       // AXI 主时钟
    struct clk *aclk_perf_pcie;  // AXI 性能监控时钟
    struct clk *hclk_pcie;       // AHB 总线时钟
    struct clk *clk_pcie_pm;    // 电源管理模块时钟

    // ===== 电源管理 =====
    struct regulator *vpcie3v3;  // 3.3V (可选)
    struct regulator *vpcie1v8;  // 1.8V (可选)
    struct regulator *vpcie0v9;  // 0.9V (可选)

    // ===== GPIO =====
    struct gpio_desc *ep_gpio;   // PERST# --- 控制 EP 设备复位

    // ===== 配置信息 =====
    u32 lanes;                   // 通道数 (1/2/4)
    u8  root_bus_nr;             // 根总线编号 (通常为 0)
    struct device *dev;          // 所属 device
    struct irq_domain *irq_domain; // INTx 中断域
};

学习要点:

  • reg_base vs apb_base:两个基址分别对应 AXI 和 APB 总线,AXI 用于高速配置空间访问,APB 用于慢速控制寄存器的读写。
  • 7 个复位信号反映了硬件复杂度:核心、管理、PIPE、电源管理、两个时钟域各有独立复位。
  • 3 个 regulator 都是 optional,部分硬件上这些电压域可能由 PMIC 常供电。

3. 寄存器布局与定义

3.1 Client 寄存器区 (基址 0x0)

这是面向"用户/驱动"的控制接口区。

偏移 寄存器名 功能
0x00 CLIENT_CONFIG 核心配置:使能、链路训练、ARI、通道数、RC模式、Gen2选择
0x48 CLIENT_BASIC_STATUS1 链路状态(Link Up 标志位在 bit21:20
0x4c CLIENT_INT_MASK 中断屏蔽
0x50 CLIENT_INT_STATUS 中断状态

CLIENT_CONFIG 位域:

复制代码
[0]  - Enable           : 控制器使能
[1]  - Link Train Enable: 链路训练使能
[3]  - ARI Enable       : Alternative Routing-ID
[5:4]- Lane Num         : 通道数编码 ((lane>>1)&3)<<4
[6]  - Mode RC          : 1=Root Complex, 0=Endpoint
[7]  - Gen Select 2     : 1=Gen2(5GT/s), 0=Gen1(2.5GT/s)

HIWORD_UPDATE 机制(值得注意的设计):

c 复制代码
#define HIWORD_UPDATE(mask, val)  (((mask) << 16) | (val))
#define HIWORD_UPDATE_BIT(val)    HIWORD_UPDATE(val, val)

高 16 位是写掩码,低 16 位是实际值。一次 32 位写入即可实现 "读-改-写" 的原子操作,无需额外的锁保护。

3.2 Core Control / Management 寄存器区 (基址 0x900000)

偏移 寄存器名 功能
0x000 CORE_CTRL 链路速度/宽度状态(只读/状态)
0x004 CORE_CTRL_PLC1 FTS (Fast Training Sequence) 计数配置
0x020 TXCREDIT_CFG1 发送信用更新间隔
0x20c CORE_INT_STATUS 核心中断状态
0x210 CORE_INT_MASK 核心中断屏蔽

3.3 RC 配置空间 (基址 0x800000 / 0xa00000)

偏移 寄存器名 功能
0xa00000 RC_CONFIG_VENDOR Vendor ID (写为 0x1d87 --- Rockchip)
0xa00008 RC_CONFIG_RID_CCR Revision ID + Class Code (PCI Bridge)
0xa000d0 RC_CONFIG_LCS Link Control/Status(链路重训练、带宽管理中断)
0x800000 RC_CONFIG_NORMAL_BASE RC 自身 Type0 配置空间基址
0xc00000 AXI_CONF_BASE Outbound ATU 区域
0xc00800 AXI_INBOUND_BASE Inbound ATU 区域

3.4 ECAM 地址计算

c 复制代码
#define PCIE_ECAM_ADDR(bus, dev, func, reg) \
    (PCIE_ECAM_BUS(bus)   | PCIE_ECAM_DEV(dev) | \
     PCIE_ECAM_FUNC(func) | PCIE_ECAM_REG(reg))

// bus<<20 | dev<<15 | func<<12 | reg<<0

ECAM 将 PCIe 的 BDF (Bus/Device/Function) + Register 映射到 MMIO 地址空间,这是 PCIe 的标准做法。


4. 配置空间访问

4.1 读写体系

复制代码
pci_ops {
    .read  = rockchip_pcie_rd_conf
    .write = rockchip_pcie_wr_conf
}
    │
    ├── 判断设备是否有效 (rockchip_pcie_valid_device)
    │     - bus == root_bus → 只允许 dev=0(只有一个slot)
    │     - bus->primary == root_bus → 只允许 dev=0(直连设备)
    │
    ├── bus == root_bus ?
    │   YES → rd_own_conf / wr_own_conf    (Type0 --- RC 自身)
    │   NO  → rd_other_conf / wr_other_conf (Type1 --- 下游设备 ECAM)
    │
    └── 返回 PCIBIOS_SUCCESSFUL / PCIBIOS_DEVICE_NOT_FOUND

4.2 关键区别

rd_own_conf rd_other_conf
基址 apb_base + 0x800000 reg_base + ECAM_ADDR
对象 RC 自身 Type0 配置头 下游设备 Type0/Type1 配置头
范围 仅 root bus 非 root bus

4.3 重要限制

驱动在 probe 末尾有一行警告:

only 32-bit config accesses supported; smaller writes may corrupt adjacent RW1C fields

这意味着:写配置空间时,非 4 字节对齐的小写入会先读 4 字节、修改、再写回,可能损坏相邻的 RW1C (Read-Write-1-to-Clear) 位。这是该硬件的一个已知限制。


5. 设备树解析 ------ 硬件资源获取

函数 rockchip_pcie_parse_dt() 是驱动中"时间优先级最高"的部分,在 probe 中第一个被调用。

获取的资源清单

复制代码
Category          | Resource Name    | Method
─────────────────────────────────────────────────────
寄存器映射          | "axi-base"       | devm_ioremap_resource
                   | "apb-base"       | devm_ioremap_resource
─────────────────────────────────────────────────────
PHY                | "pcie-phy"       | devm_phy_get
─────────────────────────────────────────────────────
复位 (7个)          | core, mgmt,      | devm_reset_control_get
                   | mgmt-sticky,     |
                   | pipe, pm, pclk,  |
                   | aclk            |
─────────────────────────────────────────────────────
GPIO               | "ep" (PERST#)    | devm_gpiod_get (默认 HIGH)
─────────────────────────────────────────────────────
时钟 (4个)          | aclk, aclk-perf, | devm_clk_get
                   | hclk, pm         |
─────────────────────────────────────────────────────
中断 (3条线)        | "sys"            | devm_request_irq (子系统/错误)
                   | "legacy"         | irq_set_chained_handler (INTx)
                   | "client"         | devm_request_irq (逻辑层/事件)
─────────────────────────────────────────────────────
电源 (3个, 可选)    | vpcie3v3,        | devm_regulator_get_optional
                   | vpcie1v8,        |
                   | vpcie0v9         |
─────────────────────────────────────────────────────
通道数              | "num-lanes"      | of_property_read_u32 (默认1)

EPROBE_DEFER 的处理

多处使用了此模式:

c 复制代码
if (PTR_ERR(phy) != -EPROBE_DEFER)
    dev_err(dev, "missing phy\n");
return PTR_ERR(phy);

含义: 如果依赖的资源驱动(如 PHY、复位控制器)尚未加载,返回 -EPROBE_DEFER 通知内核稍后重新尝试 probe,且不打印错误(因为这不是真正的错误,只是时序问题)。

三条中断线的职责

复制代码
"sys"    → 控制器内部错误/事件(FIFO溢出、TLP错误、PHY错误等)
"legacy" → 下游设备的 INTx (INTA~INTD) 传统中断 ← 级联中断处理
"client" → 高层逻辑事件(热复位、DPA、错误上报、PHY变化等)

6. 硬件初始化流程

rockchip_pcie_init_port() 是核心初始化函数,流程如下:

Step-by-Step

复制代码
1. GPIO: PERST# 拉低 (复位 EP)
       │
2. 复位序列 assert:
       aclk_rst → pclk_rst → pm_rst
       │
       ▼
3. udelay(10)  ← 等 10μs 确保复位生效
       │
4. 复位序列 deassert (按特定顺序!):
       pm_rst → aclk_rst → pclk_rst
       │
5. phy_init()       ← 初始化 PHY
       │
6. 核心复位 assert:
       core_rst → mgmt_rst → mgmt_sticky_rst → pipe_rst
       │
7. 写 CLIENT_CONFIG:
       Enable | LinkTrain | ARI | LaneNum | ModeRC | Gen2
       │
8. phy_power_on()   ← PHY 上电
       │
9. 核心复位 deassert (严格顺序!):
       mgmt_sticky_rst → core_rst → mgmt_rst → pipe_rst
       │
10. 工作区 (Controller bug workaround):
       读写 L1_SUBSTATE_CTRL2 → 配置 FTS count
       │
11. 使能 Gen1 链路训练
       │
12. 轮询等 Link Up (每 20ms, 超时 500ms):
       检查 BASIC_STATUS1[21:20] == 2'b11 → 成功
       │
13. 触发 Gen2 重训练 (写 LCS.Retrain_Link)
       │
14. 轮询等 Gen2 (每 20ms, 超时 500ms):
       检查 CORE_CTRL[4:3] → 若超时则回退 Gen1
       │
15. 读最终链路宽度 (x1/x2/x4)
       │
16. 写 RC 配置头:
       Vendor ID → Class Code → BAR → ATU Region0

复位顺序的重要性

复制代码
/* 注释原文:Please don't reorder the deassert sequence */

复位解除 (deassert) 的顺序为:

复制代码
mgmt_sticky_rst → core_rst → mgmt_rst → pipe_rst

这是由硬件设计决定的------内部状态机要求先释放粘性复位,再依次释放核心、管理、PIPE。随意调整顺序会导致控制器无法正常工作

链路训练两阶段

复制代码
Gen1 训练 (必须成功)          Gen2 训练 (可降级)
┌──────────────────┐       ┌──────────────────┐
│ 2.5 GT/s 建立链接 │  ───► │ 尝试升级到 5 GT/s │
│ 超时则整体失败    │       │ 超时 → 保持 Gen1   │
│                  │       │          │        │
│ 500ms timeout    │       │    500ms timeout  │
└──────────────────┘       └──────────────────┘

7. 中断处理体系

三层中断结构

复制代码
硬件中断线
   │
   ├─ "sys" ──► rockchip_pcie_subsys_irq_handler()
   │               ├─ INT_LOCAL: 检查 CORE_INT_STATUS
   │               │    ├─ PRFPE/CRFPE/RRPE  → FIFO RAM 奇偶校验错
   │               │    ├─ PRFO/CRFO         → FIFO 溢出
   │               │    ├─ RT/RTR            → 重放超时
   │               │    ├─ PE                → PHY 接收错误
   │               │    ├─ MTR/UCR/FCE       → TLP 畸形/流控错
   │               │    ├─ CT                → 请求完成超时
   │               │    ├─ UTC               → TC 映射错误
   │               │    └─ MMVC              → MSI 掩码变化
   │               └─ INT_PHY: PHY 链路变化
   │                     └─ 更新 Tx Credit + 清除带宽中断
   │
   ├─ "legacy" ─► rockchip_pcie_legacy_int_handler()  [chained]
   │               ├─ chained_irq_enter/exit
   │               ├─ 读 INT_STATUS[8:5] (INTA~INTD)
   │               ├─ 用 ffs() 逐位查找
   │               └─ irq_find_mapping → generic_handle_irq
   │
   └─ "client" ─► rockchip_pcie_client_irq_handler()
                    ├─ LEGACY_DONE / MSG        → 传统/MSI 完成
                    ├─ HOT_RST                  → 热复位
                    ├─ DPA                      → 动态功率分配
                    ├─ FATAL_ERR / NFATAL_ERR   → AER 致命/非致命错
                    ├─ CORR_ERR                 → 可纠正错误
                    └─ PHY                      → PHY 事件

级联中断 (Chained IRQ)

c 复制代码
irq_set_chained_handler_and_data(irq, rockchip_pcie_legacy_int_handler, rockchip);

这告诉内核:当 "legacy" 中断触发时,先调用 rockchip_pcie_legacy_int_handler,它负责:

  1. 读取状态寄存器找到具体是哪根 INTx
  2. 通过 irq_find_mapping 将硬件中断号映射到 Linux IRQ 号
  3. 调用 generic_handle_irq 分发给对应的设备驱动

中断使能

c 复制代码
rockchip_pcie_enable_interrupts():
  1. CLIENT_INT_MASK → 只使能 CLI (Correctable/Fatal/Non-Fatal/DPA/HotRst/MSG/Legacy/PHY)
  2. CORE_INT_MASK → 使能所有核心中断
  3. 使能带宽变化中断 (LCS.LBMIE | LCS.LABIE)

8. ATU 地址转换单元

ATU (Address Translation Unit) 是 PCIe 控制器的关键模块,负责 CPU AXI 地址和 PCIe 总线地址之间的转换。

Outbound ATU (CPU → PCIe)

c 复制代码
rockchip_pcie_prog_ob_atu(rockchip, region_no, type, num_pass_bits, lower_addr, upper_addr);

作用: CPU 发出的 AXI 读写请求 → 转换为 PCIe 总线上的 TLP 包。

参数说明:

  • region_no: 区域编号 (1~32),Region 0 保留给默认映射
  • type: AXI_WRAPPER_MEM_WRITE(0x2)AXI_WRAPPER_IO_WRITE(0x6)
  • num_pass_bits: 地址直通位数(决定地址窗口大小),20-1 表示 1MB
  • lower_addr / upper_addr: PCI 总线侧的物理地址

硬件寄存器布局 (每个 Region 4个寄存器):

复制代码
ADDR0: [5:0]=num_pass_bits,  [31:8]=lower_addr[31:8]
ADDR1: upper_addr (高32位)
DESC0: [23]=enable, [2:0]=type
DESC1: 保留 (写0)

Inbound ATU (PCIe → CPU)

c 复制代码
rockchip_pcie_prog_ib_atu(rockchip, region_no, num_pass_bits, lower_addr, upper_addr);

作用: 下游 EP 设备的 DMA 请求 → 转换为 AXI 地址,访问系统内存。

当前配置:

c 复制代码
rockchip_pcie_prog_ib_atu(rockchip, 2, 32 - 1, 0x0, 0);
// region=2, 直通32位, CPU端地址=0x0

表示允许 EP 通过 DMA 访问整个低 4GB 的 CPU 内存空间。

地址映射图解

复制代码
             Outbound (CPU → PCIe)
┌─────────────────┐         ┌─────────────────┐
│ CPU AXI Address  │────────►│ PCIe Mem Space  │
│ 0xFA000000      │  ATU    │ 0x00000000      │
│ 窗口: 1MB×N     │         │ (总线侧地址)     │
└─────────────────┘         └─────────────────┘

             Inbound (PCIe → CPU)
┌─────────────────┐         ┌─────────────────┐
│ EP DMA Request  │────────►│ System DRAM     │
│ (PCIe TLP)      │  ATU    │ 0x00000000      │
│                 │         │ (4GB 窗口)       │
└─────────────────┘         └─────────────────┘

9. Probe 主流程

rockchip_pcie_probe() 是驱动入口,完整流程:

复制代码
Probe 被调用 (设备树匹配 "rockchip,rk3399-pcie")
  │
  ├─ 1. 解析 DT (rockchip_pcie_parse_dt)
  │     获取:寄存器、PHY、复位、GPIO、时钟、中断、电源、通道数
  │
  ├─ 2. 使能时钟
  │     aclk_pcie → aclk_perf_pcie → hclk_pcie → clk_pcie_pm
  │
  ├─ 3. 使能电源 (rockchip_pcie_set_vpcie)
  │     vpcie3v3 → vpcie1v8 → vpcie0v9 (链式回滚)
  │
  ├─ 4. 初始化端口 (rockchip_pcie_init_port)
  │     复位序列 → PHY初始化 → Gen1训练 → Gen2训练 → RC配置
  │
  ├─ 5. 使能中断 (rockchip_pcie_enable_interrupts)
  │
  ├─ 6. 初始化 INTx IRQ Domain
  │     创建线性中断域 (irq_domain_add_linear, 大小=4)
  │
  ├─ 7. 获取 Host Bridge 资源 (of_pci_get_host_bridge_resources)
  │     解析 DT 中 "ranges" 属性 → I/O / MEM / BUS 三种资源
  │
  ├─ 8. 申请总线资源 (devm_request_pci_bus_resources)
  │
  ├─ 9. 遍历资源链表
  │     IORESOURCE_IO  → pci_remap_iospace, 记录 io_bus_addr
  │     IORESOURCE_MEM → 记录 mem_bus_addr, mem_size
  │     IORESOURCE_BUS → 记录 root_bus_nr
  │
  ├─ 10. 配置 Outbound ATU (MEM 窗口)
  │     按 1MB 步长循环配置 (非 Region 0)
  │
  ├─ 11. 配置 Inbound ATU (DMA 窗口)
  │     Region 2, 32-bit 直通, CPU地址=0
  │
  ├─ 12. 配置 Outbound ATU (I/O 窗口)
  │     Offset 偏移防止覆盖 MEM 区域
  │
  ├─ 13. 扫描 PCI 总线 (pci_scan_root_bus)
  │     这是最核心的一步:枚举所有 PCIe 设备
  │
  ├─ 14. 资源分配与配置
  │     pci_bus_size_bridges → pci_bus_assign_resources
  │     → pcie_bus_configure_settings (每个子总线)
  │
  ├─ 15. 添加设备 (pci_bus_add_devices)
  │     触发设备驱动 probe,设备可用
  │
  └─ 16. 打印硬件限制警告 (32-bit only)

错误回滚路径

复制代码
err_vpcie:
    disable vpcie0v9 → vpcie1v8 → vpcie3v3
err_set_vpcie:
    clk_disable_unprepare(pm)
err_pcie_pm:
    clk_disable_unprepare(hclk)
err_hclk_pcie:
    clk_disable_unprepare(aclk_perf)
err_aclk_perf_pcie:
    clk_disable_unprepare(aclk)
err_aclk_pcie:
    return err;

遵循 "先开后关,后开先关" 的原则。


10. 面试高频考点

Q1: ECAM 是什么?本驱动中如何实现?

ECAM (Enhanced Configuration Access Mechanism) 是 PCIe 规范定义的标准配置空间访问方式。每个 BDF (Bus/Device/Function) 占用 4KB MMIO 空间,公式为:

复制代码
Address = Base + (Bus<<20 | Dev<<15 | Func<<12 | Reg<<0)

本驱动中 PCIE_ECAM_ADDR 宏实现了这个映射。

Q2: ATU 的作用是什么?Outbound 和 Inbound 有什么区别?

  • Outbound ATU: CPU 访问 PCIe 总线地址空间(如设备 BAR 空间),将 CPU 物理地址翻译为 PCIe 总线地址
  • Inbound ATU: PCIe 设备 DMA 访问系统内存,将 PCIe 总线地址翻译为 CPU 物理地址
  1. 先以 Gen1 (2.5GT/s) 进行训练→成功则链路建立
  2. 再触发 Gen2 (5GT/s) 重训练→成功则升级,失败则保持 Gen1
  3. 最终协商出链路宽度 (x1/x2/x4) 和速度

Q4: 为什么需要 7 个独立的复位信号?

反映了 SoC 内部 PCIe 控制器的硬件分区设计:

  • core/mgmt/mgmt-sticky: 控制器核心逻辑和管理模块需要分步复位
  • pipe: PIPE 是连接 PHY 的标准接口,需要独立复位
  • pm: 电源管理状态机独立复位
  • aclk/pclk: 不同时钟域需要各自的复位,避免跨时钟域问题

Q5: EPROBE_DEFER 是什么?为什么在这个驱动中反复出现?

Linux 内核的设备模型机制。当驱动依赖的资源(如 PHY、复位控制器、时钟)尚未准备好时,返回 -EPROBE_DEFER 告诉设备模型"稍后重新调用我的 probe"。这个驱动依赖大量资源,因此对每个资源都需要处理这种情况。

Q6: 为什么寄存器写入使用 HIWORD_UPDATE 宏?

c 复制代码
#define HIWORD_UPDATE(mask, val)  (((mask) << 16) | (val))

这是一种硬件支持的原子读-改-写机制。高 16 位作为字节掩码指示要修改哪些低 16 位,一次 32 位写入即可修改特定位段,无需软件层面的 read-modify-write 序列,避免了竞态条件。

Q7: 传统中断 (INTx) 和 MSI 中断的区别?

  • INTx (Legacy): 基于物理引脚的边带信号 (INTA~INTD),4 条共享线,通过级联中断处理
  • MSI (Message Signaled Interrupt): 通过 PCIe 带内 TLP 报文发送中断,无需额外引脚,支持更多中断向量

本驱动通过 irq_domain + chained_irq 实现了对 INTx 的支持。

Q8: devm_* 系列函数有什么优势?

devm_ (device managed) 函数会自动管理资源的生命周期:

  • probe 失败时自动释放所有已申请的资源
  • driver remove 时自动释放
  • 减少手动错误处理代码

本驱动大量使用 devm_kzallocdevm_ioremap_resourcedevm_request_irq 等。


附录:关键常量速查表

常量 含义
ROCKCHIP_VENDOR_ID 0x1d87 Rockchip 的 PCI-SIG Vendor ID
AXI_REGION_SIZE 1MB 单个 ATU region 大小
AXI_REGION_0_SIZE 32MB Region 0 的大小
MAX_AXI_WRAPPER_REGION_NUM 33 最大 OB ATU Region 数
MAX_AXI_IB_ROOTPORT_REGION_NUM 3 最大 IB ATU Region 数
RC_REGION_0_PASS_BITS 24 Region 0 的地址直通位
Link Training Timeout 500ms Gen1/Gen2 各自的超时时间
Training Poll Interval 20ms 链路状态轮询间隔