3. GIC 架构概述:GICv2/v3/v4 演进历史、GIC在SoC中的位置、中断类型(SPI/PPI/SGI/LPI)

3.1 GIC 演进历史:从 v2 到 v4

通用中断控制器(Generic Interrupt Controller, GIC)是 ARM 架构中标准化的中断管理单元。随着多核处理器、虚拟化技术及高密度服务器场景的需求演进,GIC 经历了四个主要版本的迭代。下表总结了各版本的核心差异与关键特性:

特性 GICv2 GICv3 GICv4 / v4.1
CPU 接口 专用引脚(nIRQ/nFIQ) 内存映射寄存器(System Register 接口) 同 GICv3,增加虚拟化扩展
亲和性路由 仅支持 8 个 PE(CPU 接口) 支持最多 2^16 个 PE,通过 Affinity 路由 同 GICv3
虚拟化支持 基本虚拟中断(vgic) 硬件加速虚拟中断(List Registers) 直接注入虚拟中断(vLPI)
LPI 支持 不支持 支持(通过 ITS) 支持,并优化虚拟 LPI
中断号范围 ID0~ID1019(SPI 最多 988 个) ID0~ID1023 + LPI(16-bit 空间) 同 GICv3
典型应用 Cortex-A9/A15 多核 SoC Cortex-A53/A72/A76 服务器/移动 SoC 虚拟化场景(KVM、Xen)
关键演进驱动力: 多核扩展性(从 8 核到数千核)、虚拟化硬件卸载(减少 Hypervisor 干预)、以及高吞吐设备(NVMe/GPU)对大量中断的需求(LPI)。

3.2 GIC 在 SoC 中的位置

GIC 位于处理器核心(PE)与外设/软件之间,是中断信号的汇聚与分发中心。下图展示了 GICv3 在典型 ARM SoC 中的系统级位置:

GICv3 在 SoC 中的位置与中断路径 PE Cluster 0 Core 0 Core 1 ... PE Cluster 1 Core 0 Core 1 ... GIC Distributor (GICD) 中断优先级、使能、路由配置 RD Cluster0 RD Cluster1 ITS LPI 转译 SPI 外设 (UART/GPIO/...) PPI 外设 (PMU/Timer/...) LPI 设备 (NVMe/GPU/...) 图例 PE Cluster Distributor Redistributor ITS 外设
架构要点: GICv3 将每个 PE 的 CPU 接口替换为 Redistributor,通过内存映射寄存器直接与 PE 通信,消除了 GICv2 的物理引脚限制,使得支持数百甚至数千个 PE 成为可能。

3.3 中断类型详解:SPI / PPI / SGI / LPI

GIC 将中断源划分为四种类型,每种类型在触发方式、路由目标和配置粒度上各有不同。理解这些类型是编写正确中断处理程序的基础。

3.3.1 共享外设中断 (SPI)

  • 中断号范围: GICv2: ID32~ID1019; GICv3: ID32~ID1023
  • 触发方式: 电平触发 (Level-sensitive) 或边沿触发 (Edge-triggered),可编程配置
  • 路由目标: 可路由到任意一个或多个 PE(通过 Distributor 配置)
  • 典型用途: UART、I2C、SPI、GPIO、DMA 等 SoC 内部外设
  • 关键特性: 多个 PE 可以共享同一个 SPI 中断源,但通常只由一个 PE 处理

3.3.2 私有外设中断 (PPI)

  • 中断号范围: ID16~ID31
  • 触发方式: 电平触发或边沿触发,可编程配置
  • 路由目标: 固定路由到特定的单个 PE,不可跨 PE 路由
  • 典型用途: 每个 PE 私有的 Timer、PMU (Performance Monitor Unit)、CTI (Cross Trigger Interface)
  • 关键特性: 每个 PE 都有自己独立的 PPI 实例,配置寄存器也独立

3.3.3 软件生成中断 (SGI)

  • 中断号范围: ID0~ID15
  • 触发方式: 仅边沿触发 (由软件写入 GICD_SGIR/ICC_SGI1R 寄存器触发)
  • 路由目标: 可定向到指定 PE 或 PE 组,支持广播和定向发送
  • 典型用途: 核间通信 (IPI)、操作系统调度、TLB 刷新、CPU 热插拔
  • 关键特性: 发送方可指定目标 PE 的亲和性 (Affinity),GICv3 支持 16 个 SGI 通道

3.3.4 本地特定外设中断 (LPI)

  • 中断号范围: 8192~ (16-bit 空间,最多 65536 个)
  • 触发方式: 仅电平触发 (消息中断,基于写操作)
  • 路由目标: 通过 ITS (Interrupt Translation Service) 进行转译和路由
  • 典型用途: PCIe MSI/MSI-X、NVMe、高速网络控制器、GPU
  • 关键特性: 支持中断数量巨大、可动态配置、支持虚拟化直接注入 (vLPI)
开发注意事项: LPI 中断不经过 Distributor 的优先级/使能寄存器,而是通过 ITS 和 Redistributor 的 LPI 配置表 (LPI Configuration Table) 管理。驱动开发时,LPI 的使能/禁用在 ITS 侧完成,而非传统的 GICD 寄存器。

3.4 中断类型对比总结

属性 SPI PPI SGI LPI
ID 范围 32~1019/1023 16~31 0~15 8192~65535
触发方式 电平/边沿 电平/边沿 边沿 (软件触发) 电平 (消息)
路由粒度 任意 PE 固定 PE 指定 PE/组 通过 ITS 转译
配置方式 Distributor 寄存器 Redistributor 寄存器 软件写 SGI 寄存器 ITS 命令 + 内存表
数量 ~988 个 16 个/PE 16 个 ~57344 个
虚拟化支持 基本 (LRS) 基本 (LRS) 基本 (LRS) vLPI 直接注入
典型延迟 中等 低 极低 低 (硬件加速)

3.5 中断处理流程概览 (GICv3 视角)

一个典型的中断从外设产生到 CPU 处理,经过以下关键阶段:

  1. 中断产生: 外设 (如 UART) 拉高中断请求线 (SPI),或通过 PCIe 写消息产生 LPI。
  2. Distributor 仲裁: GICD 根据优先级、使能位和路由配置,选择最高优先级的中断,发送给目标 Redistributor。
  3. Redistributor 转发: Redistributor 接收中断,检查该 PE 的优先级掩码,若中断优先级高于当前 PE 的优先级掩码,则向 PE 发送 IRQ 信号。
  4. PE 响应: PE 进入中断模式,读取 ICC_IAR0_EL1 (或 ICC_IAR1_EL1) 寄存器获取中断 ID,硬件自动清除该中断的 pending 状态 (对于边沿触发)。
  5. 中断处理: 执行中断服务例程 (ISR),完成必要的设备操作。
  6. 中断结束: 写入 ICC_EOIR0_EL1 (或 ICC_EOIR1_EL1) 寄存器,通知 GIC 中断处理完成,允许下一个中断被递送。
驱动开发关键点: 在 Linux 内核中,GIC 驱动 (drivers/irqchip/irq-gic-v3.c) 负责初始化 Distributor 和 Redistributor,注册中断域 (irq_domain),并为每个中断类型提供正确的映射和回调函数。理解上述流程有助于调试中断丢失、优先级反转或虚拟化中断注入失败等问题。