3. 中断控制器基础

在 ARM 多核系统中,通用中断控制器(GIC)是连接外设中断源与 CPU 核心的硬件中枢。GIC 负责中断的优先级仲裁、分发、亲和性路由以及虚拟化支持。理解 GIC 架构是适配 PREEMPT_RT 中断线程化与 CPU 亲和性绑定的前提。

3.1 GIC 架构演进与核心组件

GIC 从 v2 发展到 v4,主要变化在于对多核、虚拟化以及大规模中断的支持。其核心组件始终包含两个逻辑单元:Distributor(分发器)和CPU Interface(CPU 接口)。

关键概念: Distributor 负责全局中断使能、优先级分组和路由决策;CPU Interface 负责将中断信号实际递交给指定的 CPU 核心。
特性 GIC v2 GIC v3 GIC v4
中断线数量 最多 1020 个 SPI 几乎无限(通过 ITS) 同 v3,增强虚拟中断
CPU 接口访问 内存映射(MMIO) 系统寄存器(ICC_*) 同 v3
虚拟化支持 基础(虚拟 CPU 接口) 增强(vLPI) 直接注入虚拟中断(doorbell)
亲和性路由 8 位 CPU ID 16 位亲和性(Aff3/Aff2/Aff1/Aff0) 同 v3
典型应用 Cortex-A7/A9/A15 Cortex-A53/A72/A76 虚拟化场景(KVM)
GIC v3 架构核心组件与中断流 外设 SPI 核间 SGI 私有 PPI Distributor 中断优先级 中断使能/屏蔽 亲和性路由 触发方式配置 Redistributor 每 CPU 实例 LPI 配置表 中断抢占 CPU 接口 说明: • GIC v3 引入 Redistributor,每个 CPU 核心拥有独立的 Redistributor 实例,处理私有中断和 LPI。 • Distributor 负责全局配置,Redistributor 负责每 CPU 的中断状态和优先级管理。

3.2 中断类型:SPI / PPI / SGI / LPI

GIC 将中断源划分为四种类型,每种类型在路由、亲和性和使用场景上存在显著差异。

  • SPI(Shared Peripheral Interrupt,共享外设中断):中断号范围 32~1019(v2)或 32~4095(v3)。可路由到任意一个或一组 CPU 核心,常用于外设(如网卡、USB 控制器)。
  • PPI(Private Peripheral Interrupt,私有外设中断):中断号范围 16~31。每个 CPU 核心独享,用于本地定时器、性能监视单元等。
  • SGI(Software Generated Interrupt,软件生成中断):中断号范围 0~15。通过写 GICD_SGIR 或 ICC_SGI1R 寄存器触发,用于核间通信(IPI)。
  • LPI(Locality-specific Peripheral Interrupt,局部外设中断):GIC v3/v4 引入,中断号从 8192 开始。基于消息的中断,通过 ITS(中断翻译服务)路由,支持大量中断源。
类型 中断号范围 路由目标 触发方式 典型用途
SPI 32 ~ 1019 (v2) / 32 ~ 4095 (v3) 任意 CPU 或 CPU 组 电平/边沿 外设中断
PPI 16 ~ 31 固定的私有 CPU 电平/边沿 本地定时器、PMU
SGI 0 ~ 15 指定 CPU 或所有 CPU 边沿(软件触发) 核间通信(IPI)
LPI ≥ 8192 通过 ITS 路由 消息(电平) PCIe MSI/MSI-X
PREEMPT_RT 关联: 在实时系统中,SPI 通常被配置为线程化中断,而 PPI(如 arch_timer)往往保留为快速中断(IRQF_NO_THREAD)以保证调度器时钟精度。SGI 用于 IPI 时,必须考虑其优先级对实时任务抢占延迟的影响。

3.3 中断亲和性与路由机制

中断亲和性(Affinity)决定了中断由哪个 CPU 核心处理。合理的亲和性配置可以避免缓存抖动、提高实时任务的确定性。

3.3.1 GIC v2 亲和性路由

GIC v2 通过 GICD_ITARGETSRn 寄存器设置 SPI 的目标 CPU。每个寄存器对应 4 个中断,每个中断使用 8 位位图表示目标 CPU(bit0~bit7 对应 CPU0~CPU7)。

/* GIC v2 SPI 亲和性设置示例 */
#define GICD_ITARGETSR(n)   (0x1800 + (n) * 4)

/* 将中断 42 路由到 CPU0 和 CPU2 */
uint32_t target = 0x05;  /* bit0=CPU0, bit2=CPU2 */
writel(target, GICD_ITARGETSR(42 / 4));

3.3.2 GIC v3/v4 亲和性路由

GIC v3 使用 GICD_IROUTERn 寄存器,支持 16 位亲和性值(Aff3:Aff2:Aff1:Aff0),可以精确路由到特定物理 CPU 或 CPU 组。路由模式包括:

  • 指定 CPU:写入目标 CPU 的 MPIDR 值。
  • 任意 CPU:写入 0xFFFFFFFF,由 GIC 自动选择。
  • 中断组:通过 GICD_ICFGRn 配置组 0(安全)或组 1(非安全)。
/* GIC v3 SPI 亲和性设置示例 */
#define GICD_IROUTER(n)     (0x6000 + (n) * 8)

/* 将中断 100 路由到 CPU1 (Aff0=1) */
uint64_t aff = 0x00000001;  /* MPIDR: Aff0=1 */
writeq(aff, GICD_IROUTER(100));
中断亲和性路由决策流程 中断到达 Distributor 中断类型? PPI:固定 CPU SGI:软件指定目标 SPI/LPI:查路由表 路由决策点: • PPI 直接路由到产生中断的 CPU 核心,无需配置路由表。 • SPI/LPI 通过 GICD_IROUTER 或 ITS 配置表确定目标 CPU 或 CPU 组。

3.4 中断优先级与抢占

GIC 支持 16~256 级中断优先级(v2 为 16 级,v3/v4 为 256 级)。优先级数值越小,优先级越高。PREEMPT_RT 内核依赖优先级机制实现中断线程化后的实时调度。

注意: 在 GIC v3 中,每个 Redistributor 维护独立的优先级掩码寄存器(ICC_PMR)。当 CPU 核心设置 PMR 为 0xF0 时,所有优先级低于 0xF0 的中断将被屏蔽。实时任务应确保关键中断的优先级高于 PMR 阈值。
/* 设置 CPU 接口优先级掩码(GIC v3 系统寄存器) */
asm volatile("msr ICC_PMR_EL1, %0" : : "r" (0xF0));

/* 读取当前优先级掩码 */
uint32_t pmr;
asm volatile("mrs %0, ICC_PMR_EL1" : "=r" (pmr));

3.5 中断虚拟化:GIC v4 的 Direct Virtual Interrupt

GIC v4 引入了 直接虚拟中断注入 机制,允许物理外设直接向虚拟机注入中断,无需 VMM 介入。其核心是 Doorbell 机制:

  • 物理中断到达时,ITS 将中断转换为虚拟中断(vLPI)。
  • 通过 Doorbell 机制通知虚拟机 CPU 接口。
  • 虚拟机直接读取中断信息,减少 VM-Exit 次数。
特性 GIC v3 虚拟化 GIC v4 虚拟化
中断注入方式 VMM 写 List 寄存器 硬件直接注入(Doorbell)
VM-Exit 次数 每次中断至少 1 次 0 次(理想情况)
中断延迟 较高(VMM 调度影响) 接近物理中断
适用场景 通用虚拟化 实时虚拟化、NFV
PREEMPT_RT 与虚拟化: 在实时虚拟化场景中,GIC v4 的直接注入机制可以显著降低虚拟中断延迟,配合 PREEMPT_RT 的线程化中断模型,能够为虚拟机内的实时任务提供接近裸机的确定性。

3.6 本章小结

GIC v2/v3/v4 架构为 ARM 多核系统提供了灵活的中断管理能力。理解 SPI/PPI/SGI/LPI 四种中断类型的路由特性,掌握亲和性寄存器的配置方法,是后续实现 PREEMPT_RT 中断线程化与 CPU 隔离的基础。在下一阶段,我们将深入分析中断控制器与 PREEMPT_RT 线程化模型的适配细节。