GIC-625是Arm CoreLink系列中的通用中断控制器(Generic Interrupt Controller),采用分布式架构设计,专为多核SoC系统优化。其核心功能包括:
GIC-625的寄存器主要分为三大功能组:
Redistributor寄存器(GICR_前缀)
负责处理器私有中断(PPI)和软件生成中断(SGI)的管理,典型寄存器包括:
调试跟踪寄存器(GICT_前缀)
提供错误记录和调试功能,关键寄存器有:
性能监控寄存器(GICP_前缀)
用于系统性能分析,包含:
关键提示:所有寄存器默认仅支持安全访问,需通过GICD_SAC寄存器的GICTNS/GICPNS位开启非安全访问权限。
这个32位寄存器用于记录PPI/SGI中断清除操作时的错误状态:
| 位域 | 名称 | 功能描述 |
|---|---|---|
| [31:0] | Status | 错误状态位,每位对应一个中断ID |
| - | RES0 | 保留位,读为0 |
访问特性:
实际应用示例:
c复制// 读取当前错误状态
uint32_t err_status = mmio_read(GICR_ICERRR0_ADDR);
// 检查特定中断ID(如15)的错误
if (err_status & (1 << 15)) {
// 处理PPI15的中断清除错误
}
这个64位寄存器提供全局错误状态概览:
| 位域 | 名称 | 功能描述 |
|---|---|---|
| [n] | Status | 错误记录n的状态(0-8) |
典型错误处理流程:
提供Redistributor的硬件配置信息:
| 位域 | 名称 | 描述 |
|---|---|---|
| [9] | ECCSupport | ECC功能支持(0=不支持) |
| [8:0] | PPINumber | 唯一Redistributor ID |
扩展配置信息寄存器:
| 位域 | 名称 | 描述 |
|---|---|---|
| [31:28] | Version | GIC-625版本号(0x3=r1p0) |
| [27:24] | UserValue | 客户定制值(通常为0x0) |
| [19:16] | PPIs_per_Processor | 每个核心的PPI数量 |
| [11:4] | NumCPUs | 支持的处理器核心数(最大0x1F) |
GIC-625默认工作在安全模式,配置非安全访问的步骤:
设置GICD_SAC寄存器:
c复制// 启用GICT非安全访问
mmio_write(GICD_SAC_ADDR, mmio_read(GICD_SAC_ADDR) | (1 << 1));
// 启用GICP非安全访问
mmio_write(GICD_SAC_ADDR, mmio_read(GICD_SAC_ADDR) | (1 << 0));
验证配置:
c复制uint32_t sac = mmio_read(GICD_SAC_ADDR);
if (!(sac & (1 << 1))) {
// GICT非安全访问未启用
}
完整的错误处理例程:
c复制void handle_gic_error(void) {
// 1. 确定错误源
uint64_t errgsr = mmio_read(GICT_ERRGSR_ADDR);
for (int i = 0; i < 9; i++) {
if (errgsr & (1ULL << i)) {
// 2. 读取错误状态
uint32_t status = mmio_read(GICT_ERR_BASE + i*64 + 0x10);
// 3. 检查错误类型
if (status & (1 << 29)) {
// 不可纠正错误
uint32_t misc = mmio_read(GICT_ERR_BASE + i*64 + 0x20);
log_error("Uncorrectable error: record=%d, code=0x%x", i, misc & 0xFF);
// 4. 错误恢复处理
if (status & (1 << 22)) { // MV位有效
uint64_t addr = mmio_read(GICT_ERR_BASE + i*64 + 0x18);
log_error("Fault address: 0x%llx", addr);
}
}
// 5. 清除错误状态
mmio_write(GICT_ERR_BASE + i*64 + 0x10, status);
}
}
}
GICP_EVTYPERn寄存器的关键配置位:
| 位域 | 名称 | 配置值说明 |
|---|---|---|
| [17:16] | EVENT_TYPE | 0x00=计数模式, 0x10=最大值 |
| [7:0] | EVENT | 事件ID(参见表5-65) |
常用事件ID示例:
监控SGI中断流量的配置:
c复制// 配置计数器0监控广播SGI
mmio_write(GICP_EVTYPER0_ADDR, 0x10);
// 启用计数器0
mmio_write(GICP_CNTENSET0_ADDR, 1 << 0);
// 定期读取计数值
uint32_t sgi_count = mmio_read(GICP_EVCNTR0_ADDR);
寄存器访问错误:
中断丢失问题:
c复制// 检查Redistributor状态
uint32_t waker = mmio_read(GICR_WAKER_ADDR);
if (waker & (1 << 1)) {
// 处理器睡眠状态
}
初始化顺序:
错误处理设计:
mermaid复制graph TD
A[错误中断触发] --> B[读取GICT_ERRGSR]
B --> C{错误类型?}
C -->|CE| D[记录并继续运行]
C -->|UE| E[触发恢复流程]
E --> F[保存错误上下文]
F --> G[系统恢复或重启]
性能优化点:
GIC-625的可靠性保障机制包括:
错误注入测试:
c复制// 配置错误注入寄存器(需安全权限)
mmio_write(GICT_ERRIRQCR0_ADDR, SPI_ID); // 设置错误中断路由
mmio_write(GICT_ERR<n>CTLR_ADDR, 0x1 << 8); // 启用错误注入
ECC保护:
跨核寄存器访问注意事项:
对全局配置寄存器使用原子操作:
c复制// 使用LDREX/STREX实现原子修改
do {
uint32_t val = __ldrex(GICD_CTLR_ADDR);
val |= (1 << 3); // 设置Enable位
} while (__strex(GICD_CTLR_ADDR, val));
核心间中断(IPI)同步:
c复制// 发送SGI中断到目标核心
mmio_write(GICD_SGIR_ADDR,
(1 << 24) | // 目标列表方式
(core_mask << 16) | // 目标核心位图
(sgi_id << 10)); // SGI ID
通过深入理解GIC-625的寄存器架构,开发者可以构建更稳定、高效的中断管理系统。实际项目中建议结合具体SoC的参考手册,特别注意安全状态转换和错误恢复路径的设计。