4. GICv3 系统架构:核心组件的职责划分

GICv3 架构相比 GICv2 最大的变化在于引入了 Redistributor 和 ITS(Interrupt Translation Service),并将 CPU Interface 从外部独立单元移入处理器核心内部。整个中断系统由四个核心组件构成:Distributor、Redistributor、ITS 和 CPU Interface。理解每个组件的职责边界,是驱动开发和系统调试的基础。

架构演进要点: GICv3 将每个 CPU 核心的中断状态管理从全局 Distributor 下放到每个核心专属的 Redistributor,大幅减少了多核系统中的总线竞争和锁开销。

4.1 组件全景与数据流

下图展示了 GICv3 中四个核心组件之间的连接关系以及中断请求的宏观流动路径。SPI 由 Distributor 分发,PPI/SGI 由 Redistributor 本地处理,LPI 则经过 ITS 翻译后路由到目标 Redistributor。

GICv3 四组件架构与中断流 GICv3 核心组件架构与中断数据流 外设中断源 SPI Distributor SPI 路由 / 优先级 / 使能 SPI Redistributor 0 PPI/SGI/LPI 管理 Redistributor 1 PPI/SGI/LPI 管理 Redistributor N PPI/SGI/LPI 管理 CPU IF 0 (核心内部) CPU IF 1 (核心内部) CPU IF N (核心内部) ITS LPI 翻译 / 路由 / 集合 LPI (带设备ID) 翻译后中断 图例 Distributor:全局中断控制,SPI 路由 Redistributor:每核心中断状态机 CPU Interface:核心内部中断信号接口 ITS:LPI 中断翻译与路由 外设 / 设备中断源 LPI 流(带设备 ID)

4.2 Distributor(分发器)职责

Distributor 是 GICv3 中负责全局中断资源管理的组件,通常作为内存映射外设存在于系统总线上。它主要处理 SPI(共享外设中断) 的配置与分发。

功能模块 职责描述 关键寄存器/操作
中断使能/禁用 全局控制 SPI 的使能状态,支持按中断号单独控制 GICD_ISENABLERn / GICD_ICENABLERn
优先级管理 为每个 SPI 分配 8 位优先级值,决定抢占行为 GICD_IPRIORITYRn
目标路由 将 SPI 路由到指定的 Redistributor(即目标 CPU 核心) GICD_IROUTERn(支持亲和性路由)
触发方式配置 配置 SPI 为电平触发或边沿触发 GICD_ICFGRn
中断分组 将中断分为 Group 0(安全)或 Group 1(非安全) GICD_IGROUPn / GICD_IGRPMODRn
驱动开发提示: Distributor 的寄存器空间基地址由系统设计决定,通常在 0x2F000000 附近。驱动初始化时首先需要映射 Distributor 的 MMIO 区域,并读取 GICD_TYPER 寄存器获取支持的中断线数量。

4.3 Redistributor(再分发器)职责

Redistributor 是 GICv3 引入的关键组件,每个 CPU 核心拥有一个专属的 Redistributor。它负责管理该核心私有的中断类型:PPI(私有外设中断)、SGI(软件生成中断) 以及来自 ITS 的 LPI(本地特定外设中断)。

Redistributor 的核心价值在于将中断状态机从全局 Distributor 中解耦,每个核心独立维护自己的中断挂起、激活和优先级状态,避免了多核同时访问 Distributor 带来的锁竞争。

中断类型 中断号范围 管理组件 特点
PPI 16-31 Redistributor 每个核心私有,如 per-CPU 定时器
SGI 0-15 Redistributor 软件触发,用于核间通信(IPI)
LPI 8192 起 Redistributor + ITS 通过 ITS 翻译后路由,支持大量中断源

Redistributor 的寄存器空间分为两个区域:RD_base(控制寄存器)和 SGI_base(SGI 相关寄存器)。驱动初始化时需要为每个 CPU 核心找到其对应的 Redistributor 基地址,这通常通过解析 GICR_TYPER 中的 Affinity 字段完成。

/* 伪代码:遍历 Redistributor 区域,匹配当前 CPU 核心 */
void gicv3_redist_init(void) {
    uint64_t redist_base = gicr_base_from_dtb();
    uint32_t cpu_aff = read_cpu_mpidr() & 0xFF;  // 获取当前核心 ID
    
    while (1) {
        uint64_t typer = readl(redist_base + GICR_TYPER);
        if ((typer >> 8) & 0xFF == cpu_aff) {
            // 找到当前核心对应的 Redistributor
            gic_data->redist_base[cpu_id] = redist_base;
            break;
        }
        // 跳转到下一个 Redistributor 帧
        redist_base += SZ_64K;  // Redistributor 帧大小
    }
}

4.4 ITS(中断翻译服务)职责

ITS 是 GICv3 中支持 LPI(本地特定外设中断) 的核心引擎。它本质上是一个 中断路由表查询引擎,负责将设备发送的 EventID(设备侧中断标识)翻译为 GIC 内部的 INTID(中断号)和目标 CPU 核心。

ITS 的工作流程可以概括为三个步骤:

  1. 设备表查询: 根据设备发送的 DeviceID 查找该设备对应的中断翻译表基地址。
  2. 中断翻译: 使用 EventID 在翻译表中查找对应的 INTID 和 目标 Redistributor。
  3. 中断注入: 将翻译后的中断信息写入目标 Redistributor 的 LPI 挂起表,触发中断。
ITS 中断翻译流程 ITS 中断翻译与路由流程 PCIe 设备 设备表 DeviceID → 翻译表基址 中断翻译表 EventID → INTID + 目标 集合表 目标 Redistributor DeviceID EventID 目标信息 写入 LPI 挂起表 目标 Redistributor ITS 通过三级查表(设备表 → 翻译表 → 集合表)将物理设备的 EventID 映射为 GIC 内部中断号与目标核心
关键约束: ITS 的翻译表(Translation Table)和集合表(Collection Table)存储在内存中,由驱动通过 ITS_BASER 寄存器配置基地址。表项格式必须严格遵循 GICv3 规范,错误的表项配置会导致 LPI 中断丢失或路由到错误的 CPU 核心。

4.5 CPU Interface(CPU 接口)职责

在 GICv3 中,CPU Interface 被集成到处理器核心内部,不再作为独立的外设存在。它通过 系统寄存器(System Registers) 而非内存映射寄存器与操作系统交互,这显著降低了中断处理的延迟。

CPU Interface 的核心职责包括:

  • 中断优先级屏蔽: 通过 ICC_PMR_EL1 设置当前 CPU 的优先级阈值,低于该阈值的中断被屏蔽。
  • 中断确认(IAR): 读取 ICC_IAR0_EL1(Group 0)或 ICC_IAR1_EL1(Group 1)获取当前最高优先级中断的中断号。
  • 中断结束(EOI): 写入 ICC_EOIR0_EL1 或 ICC_EOIR1_EL1 通知 GIC 中断处理完成。
  • 中断抢占控制: 管理中断嵌套和抢占逻辑,确保高优先级中断可以抢占低优先级中断处理。
  • 运行优先级管理: 通过 ICC_RPR_EL1 读取当前 CPU 的运行优先级。
系统寄存器 访问类型 功能描述
ICC_PMR_EL1 读/写 优先级屏蔽寄存器,设置中断阈值
ICC_IAR1_EL1 读 中断确认寄存器,返回 Group 1 中断号
ICC_EOIR1_EL1 写 中断结束寄存器,标记 Group 1 中断完成
ICC_BPR1_EL1 读/写 二进制点寄存器,控制优先级分组
ICC_CTLR_EL1 读/写 控制寄存器,使能/禁用 CPU Interface
/* Linux 内核 GICv3 驱动中 CPU Interface 中断处理入口示例 */
static asmlinkage void __exception_irq_entry gicv3_handle_irq(struct pt_regs *regs) {
    u32 irqnr;
    
    /* 1. 读取 IAR 确认中断 */
    irqnr = gic_read_iar();
    
    /* 2. 处理中断 */
    if (likely(irqnr & ICC_IAR1_EL1_INTID_MASK)) {
        handle_domain_irq(gic_data.domain, irqnr, regs);
    }
    
    /* 3. 写入 EOI 结束中断 */
    gic_write_eoir(irqnr);
}

4.6 组件职责对比总结

下表从多个维度对比四个组件的职责边界,帮助驱动开发者在调试时快速定位问题组件。

对比维度 Distributor Redistributor ITS CPU Interface
管理的中断类型 SPI PPI、SGI、LPI LPI(翻译服务) 所有已使能中断
寄存器访问方式 MMIO MMIO MMIO 系统寄存器
每核心实例数 1(全局) 每个核心 1 个 1(可选) 每个核心 1 个
主要功能 SPI 路由与配置 本地中断状态机 EventID → INTID 翻译 中断确认与结束
中断优先级控制 设置 SPI 优先级 设置 PPI/SGI 优先级 不直接参与 优先级屏蔽与抢占
架构设计思想: GICv3 通过将中断状态机下放到 Redistributor,将 CPU 交互接口内移到核心内部,实现了中断处理路径的“去中心化”。ITS 的引入则为大规模中断场景(如 PCIe MSI-X)提供了可扩展的翻译机制。这种分层设计使得 GICv3 能够高效支持从嵌入式双核到服务器百核的广泛场景。