GICv3_LPI机制

文章介绍了GICv3中断控制器的改进,包括新增的基于消息的中断MSI和局部特定外设中断LPI。LPI有两种触发方式:直接写入GICR_SETLPIR或通过ITS转换EventID。GICv3还支持MSI,简化了大型系统中断线路的需求。文章还提到了GICv2的中断类型和GICv3的内部结构。

GICv3_LPI机制




参考资料:

  • 《ARM® Generic Interrupt Controller Architecture Specification Architecture version 2.0(IHI0048B_b_gic_architecture_specification_v2).pdf》
  • 《IHI0069G_gic_architecture_specification.pdf》第5章
  • 《GICv3_Software_Overview_Official_Release_B.pdf》
  • ARM GIC(六)gicv3架构-LPI

一、 GICv2

框图如下:

在这里插入图片描述
在这里插入图片描述
GIC V2有3种中断:

① 软件触发中断(SGI,Software Generated Interrupt)
这是由软件通过写入专用仲裁单元的寄存器即软件触发中断寄存器(ICDSGIR)显式生成的。它最常用于CPU核间通信。SGI既可以发给所有的核,也可以发送给系统中选定的一组核心。中断号0-15保留用于SGI的中断号。用于通信的确切中断号由软件决定。

② 私有外设中断(PPI,Private Peripheral Interrupt)
这是由单个CPU核私有的外设生成的。PPI的中断号为16-31。它们标识CPU核私有的中断源,并且独立于另一个内核上的相同中断源,比如,每个核的计时器。

③ 共享外设中断(SPI,Shared Peripheral Interrupt)
这是由外设生成的,中断控制器可以将其路由到多个核。中断号为32-1020。SPI用于从整个系统可访问的各种外围设备发出中断信号。

在GICv2里,设备向中断控制器发出中断,必须使用物理上的线路:
在这里插入图片描述
在复杂系统中有成本上千的中断时,就需要成本上千的中断信号线,这太复杂了。

于是在GICv3中引入MSI(“message-based interrupts”),设备往某个地址写入数值,即可触发中断。

二、 GICv3

2.1 MSI

在GICv3里,添加了MSI(“message-based interrupts”),设备往某个地址写入数值,即可触发中断:
在这里插入图片描述
使用消息来发送中断,好处是可以省略硬件线路。在大型系统中有成百上千个中断,使用MSI可以省下很多线路。

2.2 GICv3内部结构

GIC V3里新增加了一类中断:LPI(Locality-specific Peripheral Interrupts)

框图如下:

在这里插入图片描述
对于原来的SPI,它也是可以使用MSI的方式传递的,这个功能是可选的。如果GICv3支持MSI方式的SPI,要产生/清除中断时,操作如下GIC寄存器:

  • 产生中断:写寄存器GICD_SETSPI_NSR 或 GICD_SETSPI_SR
  • 清除中断:写寄存器GICD_CLRSPI_NSR 或 GICD_CLRSPI_SR

对于LPI中断,有两种触发方式:

  • 写寄存器GITS_TRANSLATER
    • 设备把数据写入GITS_TRANSLATER寄存器,写入的值被称为EventID
  • 写寄存器GICR_SETLPIR

2.3 中断号

0~1023跟GICv2保存一致。

INTID中断类型描述
0~15SGI
16~31PPI
32~1019SPI设备发出的中断
1020~1023SPI用于特殊目的
1024~1055-保留
1056~1119PPI扩展的PPI,GICv3.1才支持
1120~4095-保留
4096~5119SPI扩展的SPI,GICv3.1才支持
5120~8191-保留
8192~芯片实现LPI

三、 LPI的触发方式

LPI有两种触发中断的方式:

  • 把INTID直接写入GICR_SETLPIR寄存器
  • 使用ITS把EventID 转换为LPI INTID,会用到"GITS_TRANSLATER"寄存器

这两种方法只能支持一种。

3.1 使用GICR_SETLPIR

这个寄存器格式如下:
在这里插入图片描述
把LPI的中断号写入这个寄存器即可触发中断。

3.2 使用ITS

ITS的意思是:Interrupt Translation Service,中断转换服务。
在这里插入图片描述
能产生MSI中断的设备,都有一个DeviceDI(设备ID),它产生的每一个MSI中断都有一个EventID(事件ID)。"DeviceID+EventID"组合被传入ITS,IDS会把它们转换为INTID。

过程如下:

  • 外设发生中断消息(Interrupt Message)到ITS
    • 外设只要写GITS_TRANSLATER就可以发送消息,这个寄存器格式如下:
      在这里插入图片描述
    • 消息里包含有:DeviceID(哪一个设备)、EventID(这个设备的哪一个中断)
  • ITS使用DeviceID在Device Table中找到一项
    • 只有一个Device Table
    • 每一个能发生MSI中断的设备在里面都有一项,它指向这个设备的Interrupt Translation Table(中断转换表,简称ITT)
    • 每一个能发生MSI中断的设备,都有一个ITT
  • ITS使用EventID在ITT中找到一项,从中返回INTID和Collection ID
  • ITS使用Collection ID在Collection Table中找到一项,从中返回"Target Redistributor",即:中断发给哪个CPU
  • ITS把INTID发给Redistributor

在这里插入图片描述
在这里插入图片描述
上图中Device Table、Interrupt Translation Table、Collection Table都是在内存里,但是我们不能直接去设置内存。而是通过发送ITS命令来设置这些表格。

我们不研究ITS的内部细节,暂且了解这些内容即可。



致谢

以上笔记源自韦东山老师的视频课程,感谢韦老师,韦老师是嵌入式培训界一股清流,为嵌入式linux开发点起的星星之火,也愿韦老师桃李满园。聚是一团火,散是满天星!

在这样一个速食的时代,坚持做自己,慢下来,潜心琢磨,心怀敬畏,领悟知识,才能向下扎到根,向上捅破天,背着世界往前行!
仅此向嵌入行业里的每一个认真做技术的从业者致敬



<think> 我们正在讨论ARM GIC(Generic Interrupt Controller)的中断路由问题。用户之前询问了是否可以将SPI(Shared Peripheral Interrupt)路由到指定的CPU集合而非单个CPU。现在用户的新问题是:GICv4的LPI(Locality-specific Peripheral Interrupt)中断是否支持多核路由? 回顾之前的回答: - 对于SPI中断,GIC架构(包括v3/v4)原生不支持路由到自定义CPU集合,只能路由到单个CPU或所有CPU中的任意一个。 - 用户现在想了解LPI中断是否支持类似的多核路由。 根据ARM GICv4架构规范[^1][^2]: 1. **LPI中断特性**: - LPI是一种基于消息的中断(Message-Based Interrupt),通过写特定的内存地址(ITS寄存器)来触发。 - LPI的中断路由依赖于ITS(Interrupt Translation Service)模块的配置。 2. **LPI的路由机制**: - 每个LPI中断通过ITS转换表(Interrupt Translation Table)配置目标CPU。 - 在ITS中,每个LPI中断可以配置一个目标`DeviceID`和`EventID`,然后通过转换表映射到目标物理CPU(通过`ICID`标识)或虚拟CPU(通过`vPE`标识)[^2]。 - 关键点:**每个LPI中断只能路由到单个目标CPU(物理或虚拟)**,不支持同时路由到多个CPU。 3. **与SPI的对比**: - SPI支持两种模式:单个指定CPU或任意CPU(1-of-N)。 - LPI同样只支持单个目标CPU,但通过ITS可以实现更灵活的映射(比如动态改变目标CPU)。 4. **多播(Broadcast)支持**: - 在GICv4中,LPI本身不支持多播(即同时发送到多个CPU)。 - 但可以通过软件方式模拟:例如,触发多个LPI事件,每个事件指向不同的CPU。但这需要硬件(外设或ITS)的支持,并非GIC原生功能。 **结论**: - ❌ **GICv4的LPI中断不支持多核路由(即同时路由到多个CPU)**。 - ✅ 但LPI支持动态重定向:可以通过软件(如操作系统)动态修改ITS表项,将同一个外设中断快速切换到不同的CPU上。 --- ### 附加说明:LPI中断处理流程 1. 外设通过写内存地址(如PCIe设备的MSI-X)触发LPI。 2. ITS根据`DeviceID`和`EventID`查找转换表: $$ \text{Interrupt Translation Table Entry} = \langle \text{目标ICID}, \text{LPI ID} \rangle$$ 3. GIC根据ICID将中断发送到对应的物理CPU或虚拟CPU[^2]。 --- ### §§相关问题§§ 1. 如何在GICv4中使用ITS配置LPI中断? 2. LPI中断与SPI中断在性能上有何差异? 3. GICv4的虚拟化扩展如何优化LPI中断处理? 4. ARM架构中是否存在支持多播中断的类型? --- 参考文献: [^1]: ARM Generic Interrupt Controller Architecture Specification GICv4 [^2]: ARM GIC学习专栏(站内引用) </think> 根据 ARM GICv4 架构规范和相关技术文档[^1][^2],LPI(Locality-specific Peripheral Interrupt)中断的路由机制如下: ### LPI 中断路由特性分析 1. **单目标路由机制** LPI 中断通过 ITS(Interrupt Translation Service)模块配置路由目标: $$ \text{ITS 表项} \rightarrow \langle \text{DeviceID, EventID} \rangle \xrightarrow{\text{映射}} \text{目标 PE} $$ 每个 LPI 中断只能映射到 **单个物理 CPU(ICID)或虚拟 CPU(vPE)**,不支持指定多个目标[^1][^2]。 2. **与 SPI 的对比** - **SPI**:支持精确路由(单核)或硬件分发(全核随机选一) - **LPI**:仅支持精确路由到单个目标 ```mermaid graph LR A[LPI触发] --> B[ITS查表] B --> C{目标类型} C --> D[单个物理CPU] C --> E[单个虚拟CPU] ``` 3. **不支持多播的原因** - LPI 设计用于低延迟外设中断(如 PCIe MSI-X),需保证原子性处理 - ITS 转换表的物理实现限制每个条目只能存储单个目标地址[^1] - 虚拟化场景中,LPI 直接注入机制要求目标唯一性 ### 变通方案 虽然不支持硬件级多核路由,但可通过软件实现近似效果: 1. **中断重定向** 在中断处理函数中触发 IPI(核间中断)广播到目标 CPU 集合: ```c // Linux 驱动示例 irq_handler() { handle_local(); // 本地快速处理 ipi_send(target_cpus); // 通知其他 CPU } ``` 2. **动态目标切换** 利用 ITS 的灵活映射特性,在不同时刻将中断路由到集合内的不同 CPU: $$ \text{时间片 } T_0 \rightarrow \text{CPU}_A, \quad \text{时间片 } T_1 \rightarrow \text{CPU}_B $$ --- ### 关键结论 - ✅ **支持**:精确路由到单个物理/虚拟 CPU - ❌ **不支持**:原生硬件级多核路由(广播或目标集合) - ⚡ **替代方案**:通过软件层 IPI 或动态 ITS 重配置间接实现多核处理 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值