目录
4.1.4 Collection & Device 表的size和构造
本文为GICv3软件手册的阅读译文,目的在于学习GICv3控制器、掌握GICv3编程原则。
1. GICV3 基础
1.1 中断类型
SPI (shared peripheral interrupt)能够被路由到特定PE或者一组PE
PPI (Private peripheral interrupt)针对特定PE的设备中断,如PE的Timer中断
SGI (software generarted interrupt)用于内部处理器间的通信,通过写SGI寄存器来触发SGI中断。
LPI (locality sepcicifc peripheral interrupt)LPI是基于massage-based的中断,LPI相关的配置保存在memory中而非寄存器。
GICv3 Interrupt ID ranges Table
INTID | Interrupt Type | Notes |
0 - 15 | SGIs | Banked per PE |
16 - 31 | PPIs | Banked per PE |
32 - 1019 | SPIs | - |
1020 - 1023 | Special interrupt number | Used to signal special cases |
1024 - 8191 | Reserved | - |
8192 and greater | LPIs | The upper boundary is IMPLEMENTATION DEFINED |
1.2 中断传递方式
通常中断信号传递是从设备到中断控制器,依赖与硬件中断信号。GICv3支持基于message-based的中断,该类中断的设置和清除通过写中断控制器的寄存器实现。
使用消息将中断从设备传递到中断控制器(不需硬件中断信号),该类型中断对大系统的硬件设计非常有利,大系统通常会有成百上千的信号路由到SoC或者和中断控制器进行交互。
1.3 中断状态
对于SPI、SGI、PPI等类型中断,中断控制器的状态机有以下4中状态(LPI中断没有active和 active&pending状态):
1> Inactive : 中断源未触发
2> Pending: 中断源已经触发,但是PE没有应答
3> Active: 中断源触发且中断已经被PE响应
4> Active&Pending:该中断源的一个中断已经被PE响应,另一个中断被Pending (中断信号 未消失或者再次触发中断)
1.3.1 电平触发类型中断
Inactive -> Pending
当中断触发时,该中断转变从inactive到pending状态。此刻,GIC发射中断信号到对应PE。
Pending -> Active&Pending
当PE通过读取IAR寄存器应答中断时,该中断从pending转换到active&pending状态。通常读IAR寄存器是在中断异常被捕获后、该读取操作是中断出处理的一部分。
此刻,GIC关闭该中断信号到PE的传递。
Active&Pending -> Active
当设备关闭中断信号时,该中断状态由active&pending转变到active。该变化通常发生在软件处理中断过程,写设备的中断状态寄存器时。
Active -> Inactive
当PE写EOIRs(end of interrupt registers)寄存器后,该中断从active状态进入到inactive状态,表示PE完成了该中断的处理。
1.3.2 边沿触发类型中断
此处需要特殊说明的后两种状态,其他状态同电平触发类型中断。
Active -> Active&Pending
外设再次发射中断信号时该中断从active 状态转变到active&pending状态。
Active&Pending -> Pending
当PE写EOIRs寄存器后该中断从active&pending转变到pending状态,表示PE已经完成了第一个中断。此刻GIC再次发起中断信号到PE。
1.4 亲和性路由
GICv3 使用亲和路由识别连接的PE,路由中断到特定PE或PE组。
1.5 安全模式
CICv3 支持Arm TrustZone技术,每个中断必须指定组和安全设置。GICv3支持3中组合,如图:
Group0 中断做为FIQ类型中断;Group1 中断既可以时IRQ也可以时FIQ类型,这个取决于PE当前的异常级别和安全状态,各中对于关系如图(Armv8-A 支持):
下图显示一个简单的软件栈,EL0执行环境下不同类型的中断触发时中断的执行方式。
图例中:因为SCR_EL3.IRQ=1,IRQ中断被路由到EL1执行环境;SCR_EL3.RIQ=1,FIQ中断被路由到EL3执行环境。同Table6一致,当前的执行环境为EL0或者EL1时,Group1中断被标记为IRQ类型中断。其他安全状态的中断被作为FIQ类型中断、此类异常被带入EL3执行环境,软件切换到EL3环境执行时,需要执行必要的上下文切换。
1.5.1 软件影响
配置软件控制器时,软件可以设置中断号所归属的中断组,只有运行在安全环境时才能进行此设置。
1.5.2 支持的单一安全状态
ARMv8 & GICv3 支持两种安全设置,实现时可以选择一种或者两种安全状态。
GICD_CTLR.DS=0,表示支持两种(Secure&Non-Secure)状态
GICD_CTLR.DS=1, 表示仅支持一种安全状态
当仅支持一种安全状态时,系统仅有两个中断组:Group0 & Group1 组中断。
1.6 编程模型
GICv3中断控制器有三类寄存器接口: Distributor interface、Redistributor interface、CPU interface。
- Distributor interface: 影响所有连接到中断控制器的PE行为
设置中断优先级和SPI中断的分发
使能&关闭 SPI中断
设置每个SPI中断的优先级
设置每个SPI中断的路由信息
设置每个SPI中断的触发方式,电平/边沿
产生message-based SPI
控制SPI中断的Pending & Active状态
决定配置在哪种安全状态下应用
Redistributor interface: 每个PE对应一个独立Redistributors
使能&关闭 SGI和PPI中断
设置每个SGI&PPI中断优先级
设置每个PPI中断触发方式,电平/边沿
设置每个SGI&PPI到中断组
控制SGI&PPI中断状态
控制LPI中断的pending状态和其在内存中属性数据的基地址
管理连接PE的电源
CPU interface :连接Redistributor与PE
使能中断处理的通用控制和配置
中断应答
执行中断优先级、停用或者下降中断
设置中断在PE中的优先级
设置PE的竞争策略
确定PE的等待中断的最高优先级
在GICv3中 CPU interface register(ICC_*_ELn)被作为系统寄存器访问。在访问系统寄存器前必须使能系统寄存器接口,即需要使能ICC_SRE_ELn中的SRE位。
2. GIC配置
2.1 GIC global setting
GICD_CTLR :
ARE(Enable Affinity routing)
控制affinity routing使能,如果没有设能则GICv3能够配置为legacy模式。安全与非安全模式的ARE是使能与否是独立控制的。
Eanble
Group 0, Secure Group1, Non-Secure Group1 使能是独立控制的,分别为 GICD_CTRL.EnableGrp0、GICD_CTRL.EnableGrp1S、GICD_CTRL.EnableGrp1NS
2.2 PE独立设置
Redistributor configuration
系统reset时,redistributor认为连接的PE在sleeping模式,可以通过设置GICD_WAKER寄存器唤醒PE,唤醒过程的软件动作:
清除GICR_WAKER.ProcessorSleep;
等待GIC_WAKER.ChildrenAsleep为零;
CPU interface configuration
CPU interface用来负责传递中断到与之连接的PE,使能CPU interface软件需要进行如下配置:
A.使能系统寄存器访问
需要通过设置ICC_SRE_Eln.SRE位来使能系统寄存器的访问。
B.设置优先级掩码和BPR(binary point register)寄存器
ICC_PMR_EL1: priority mask register,设置可路由到对应PE的最小中断有先级
ICC_BRPn_EL1: binary point register,用于priority 分组和竞争
C. 设置EOI(End of Interrupt)
ICC_CTRL_EL1.EOImode、ICC_CTRL_EL3.EOImode 用于标识中断处理完成
D.使能中断组信号
每个中断组的信号必须被使能,在该组的中断被路由到对应的PE之前。
ICC_IGRPEN1_EL1:使能Group 1的组中断
ICC_IGRPEN0_EL1:使能Group 0的组中断
PE配置
PE的部分寄存器也用来配置接中断的接受和处理。
路由控制:
PE寄存器SCR_EL3和HCR_EL2用来作为中断的路由控制,决定了哪种异常的中
断可以被处理。reset后该路由设置为无效,必须通过软件进行配置。
中断掩码:
指每个PE的PSTATE寄存器中的异常掩码位,当这些位被设置时,表示中断被
mask,reset后这些位被mask。
中断向量表:
PE的中断向量表的地址被设置在VBAR_ELn寄存器,reset时VBAR_ELn寄存器状
态位置,需要进行软件设置。
2.3 SPI PPI & SGI 配置
SPI 通过Distributor进行配置,使用GICD_*寄存器。PPI、SGI通过独立的Redistributor进行配置,使用 GICR_*寄存器。
对于每个中断,软件需要啊进行如下配置:
优先级(GICD_IPRIORITYn,GICR_IPRIORITYn)
每个中断有一个8bit优先级数,0x00表示最高优先级、0xFF表示最低优先级。
中断控制器实现8bit的优先级数据配置是非必须的;如果GIC支持两种安全模式,需
最少设置5bit的优先数位;如果仅支持安全模式,则最少实现4bit的优先数位。
组(GICD_IGROUPn,GICD_IGRPMODn, GICR_IGROUP0,GICR_IGRPMOD0)
通过此寄存器设置可以将中断配置为3个不同的组中的一个(Group 0,
Secure Group 1、Non-secure Group1)。
中断触发方式(GICD_ICFGRn,GICR_ICFGRn ;边沿or电平)
如果依赖物理信号发生中断,则必须配置中断触发方式:边沿or电平。SGI中断总是
被作为边沿触发方式。
中断使能(GICD_ISENABLERn,GICD_ICENABLER,
GICR_ICENABLER0,GICR_ICENABLER0,)
配置中断的使能状态,每个中断有自己使能位;建议在使能中断前先完成中断相关的配置。
对于大部分系统来说,是没有必要在初始化后在进行配置修改。但是如果在要改变中断
的组设置,需要先disable部分中断。
系统reset后,大部分中断的配置寄存器值为未定义;系统需要重新配置中断寄存器。
SPI中断的PE目标
对于SPI中断,需要通过GICD_IROUTERn寄存器配置中断的目标PE。每个SPI都有一
个对应的GICD_IROUTORn寄存器。Interrupt_Routing_Mode 位用来控制路由策略,如下:
GICD_IROUTORn.Interrupt_Routing_Mode =0
SPI被路由到寄存器指定的affinity相应的PE
GICD_IROUTORn.Interrupt_Routing_Mode =1
在遵循中断分组的原则下,SPI中断能够被传送到连接的任意PE。Distributor选
择目标PE(非软件配置),
PE可以根据CICR_CTLR寄存器中DPG1S、DPG1NS、DPG0位的配置,选择不接
收N个中断中的一个。
3. 中断处理
3.1 中断pending
当中断状态为pending时,中断控制器决策是否发送该中断到所连接的一个PE,哪个PE可以被中断控制器的选择,取决于如下设置:
使能组
每个中断组(Group 0, Secure Group 1 、 Non-Secure Group 1)有各自的位
域在Distributor 和 CPU interface,被disable的中断组中的中断不能发送中断信号到PE。
中断使能
单独disable的中断能够被pending,但是不能路由到PE。
路由控制
中断控制器根据中断类型决定该中断由哪个PE能够处理。
SPI中断路由依赖GICD_IROUTERn寄存器设置,SPI中断能够被路由到特定的PE或者
连接任意PE。
LPI中断路由信息来自ITS。
PPI中断路由指定的PE。
SGI中断被路由到目标列表中的PE
中断优先级和优先级掩码
每个PE在CPU interface中有独立的优先级掩码寄存器(ICC_PMR_EL1),该寄存
器设定可以路由到对应PE处理的中断的最小优先级。只有大于该寄存器值优先级的中断
才可被连接PE处理。
运行优先级
后续介绍。PE没有没有处理中断时,该PE的运行优先级为0xFF(最小优先级,意
味着任意中断都可抢占该PE运行)。高于运行优先级的中断可以抢占当前中断的运行资源。
3.2 中断应答
CPU interface有两个中断应答寄存器(IAR: ICC_IAR0_EL1、ICC_IAR1_EL1),read IAR会返回中断号并推进中断状态机。典型中断处理过程,处理中断的第一步是读取IAR。
3.3 特定中断
中断号1020 - 1023 位特定目的中断,读取IAR寄存器返回该中断ID时表示特定情况的异常
处理。
INTID | 意义 | 场景示例 |
1020 | >可能读取ICC_IAR0_EL1寄存器获取 >Secure Group1中断组中最高等级的pending中断 >仅在FIQ中断进入EL3运行环境时遇到 | 运行在非安全环境的PE收到需要在安全环境执行的中断信号,该中断被认为EL3的FIQ类型中断、安全监控到该中断时切换系统到安全运行环境。 |
1021 | >可能读取ICC_IAR0_EL1寄存器获取 >Non-Secure Group1中断组中最高等级的pending中断 >仅在FIQ中断进入EL3运行环境时遇到 | 运行在安全环境的PE收到需要在非安全环境执行的中断信号,该中断被认为EL3的FIQ类型中断、安全监控到该中断时切换系统到非安全运行环境。 |
1022 | >仅使用在兼容操作是使用 | |
1023 | >特殊中断,没有使能的中断在pending状态或者所有的pending状态的中断不满足优先级的的要求而不能执行 | 读取IAR时返回该值表示没有可响应的中断 |
1021 特定中断处理,例:
手机接收到modem的来电中断信号,该中断需要在Rich OS(UnTrusted OS)环境下执行。如下展示Non-Secure Group 1中断触发处理器从安全状态退出、得到执行的过程。
- 因为PE执行在Trusted OS环境下,故此时Modem的中断被pending。又因为该modem中断被配置为Non-Secure Group 1, 故该中断信号被作为FIQ类型中断,同时因SCR_EL3.FIQ =1 ,故异常进入到EL3状态。
- 执行在EL3模式的安全监控软件读取IAR寄存器返回1021,该值表示中断期望在Non-Secure state执行,故安全监控执行必要的上下文切换操作准备切换到Non-Secure状态。
- PE被切到Non-Secure 状态,该中断被作为IRQ类型中断在Non-Secure EL1 状态的非安全环境下处理。
替换路由设置,同为modem来电中断,SCR_EL3.FIQ 设置值不同导致断处理的路由不同。
- 因为PE执行在Trusted OS环境下,故此时Modem的中断被pending。又因为该modem中断被配置为Non-Secure Group 1, 故该中断信号被作为FIQ类型中断,同时因SCR_EL3.FIQ =0 ,故异常进入到安全EL1。
- Trusted OS执行被激活去整理内部状态,状态就绪后执行SMC执行切换到Non-Secure 状态
- SMC执行在进入到EL3状态,EL3状态的安全监控软件执行不要的上下文切换操作为状态模式切换。
- PE被切到Non-Secure 状态,该中断被作为IRQ类型中断在Non-Secure EL1 状态的非安全环境下处理。
3.4 运行优先级和竞态
PMR寄存器配置可路由到对应PE的最小中断优先级,GICv3架构也有运行优先级的原则。当PE应答中断后,他的运行优先级变成该中断的优先级;当PE设置EOI寄存器时,该PE的运行优先级返回到他原先的级别。
CPU interface寄存器ICC_RPR_EL1保存该PE的当前运行优先级值。
对于竞态状态,运行优先级是非常重要。当PE已经在处理一个低优先级的中断时收到一个高优先级的中断信号,此时就有可能发生中断对PE的竞争。对于软件来说中断竞争是相当复杂,但是他能够防止低优先级的中断阻塞高优先级中断的执行。
如上是两个中断的竞态情况,现实系统中可能有多个中断的竟态情况出现。GICv3中断控制器允许通过ICC_BRPn_EL1寄存器用于不同优先级中断的竞态控制,BRP寄存器分为两部分:group proirity & subproirity。
3.5 EOI(End of Interrupt)
中断已经被处理时,软件必须通知到中断控制器以便状态机能够被切换到下个状态。在GICv3架构会执行两个动作:
回退运行优先级
回退到该中断处理前的运行优先级
切换到非激活状态
更新当前处理中断的状态从激活状态到非激活状态
GICv3架构中回退运行优先级和切换到非激活状态动作可以同时发生或者独立发生,这个取决于ICC_CTLR_ELn.EOImode。
ICC_CTLR_ELn.EOImode - 0 表示Group n组的中断同时执行回退运行优先级和切
换到非激活状态
ICC_CTLR_ELn.EOImode - 1 表示Group n组的中断执行回退运行优先级,切换到
非激活状态通过写ICC_DIR_EL1实现;这种操作通常被用于虚拟化中。
3.6 系统当前状态检查
HPPIR(Highest proirity pending interrupt)
ICC_HPPIR0_EL1& ICC_HPPIR1_EL1 :对应PE的最高优先级的pending状态的中断号
中断状态
Distributor 寄存器可表示SPI类型中断状态,Redistributor寄存器可表示对应PE的PPI和SGI类型中断的状态。
Register | Description |
GICD_ISACTIVERn | >设置SPI类型中断的active状态 >每bit对应一个中断 >读取bit获取对应的中断的状态, 1 - 激活状态、0 - 非激活状态 >写1到bit位激活该位对应的中断,写0到bit时没有影响 |
GICD_ICACTIVERn | >清除SPI类型中断的active状态 >每bit对应一个中断 >读取bit获取对应的中断的状态, 1 - 激活状态、0 - 非激活状态 >写1到bit位时设置该位对应中断到非激活状态,写0到bit位时没有影响 |
GICR_ISACTIVER0 | >设置SGI & PPI类型中断的active状态 >每bit对应一个中断(0 - 31中断号,每个PE私有的中断) >读取bit获取对应的中断的状态, 1 - 激活状态、0 - 非激活状态 >写1到bit位激活该位对应的中断,写0到bit时没有影响 |
GICR_ICACTIVER0 | >设置SGI & PPI类型中断的active状态 >每bit对应一个中断(0 - 31中断号,每个PE私有的中断) >读取bit获取对应的中断的状态, 1 - 激活状态、0 - 非激活状态 >写1到bit位时设置该位对应中断到非激活状态,写0到bit位时没有影响 |
在Affinity路由被使能时,ICD_ISACTIVER0 & GICD_ICACTIVER0
作为预留使用,因为ICD_ISACTIVER0 & GICD_ICACTIVER0对应中中断号为0-31 ,该
中断被连接到每个PE、并通过对应PE的redistributor进行分发。
非安全环境时系统不能访问Group 0 和 安全Group 1组的中断状态,除
非GICD_NASCRn和GICR_NASCRn寄存器中设置允许。
4. LPI中断的配置
只有在Affinity路由使能时,LPI中断被支持。LPI中断的配置不同于其他类型中断。LPI中断配置需要设置:
Redistributors
The optional ITS(Interrupt Translation Service)
LPI是基于message-based的中断,依赖于ITS实现。ITS用于接受设备中断并将中断传递给合适的Redistributor。系统中可以有多个ITS,每个ITS有独立的配置。设备也可以bypass掉ITS直接发送ITS中断到Redistributor,但是ITS可以使大量中断高效地处理。
4.1 ITS
4.1.1 ITS相关操作
设备通过写ITS中的GITS_TRANSLATER产生LPI中断。ITS提供的信息有:
EventID: 被写入GITS_TRANSLATER,EventID表示设备发送的哪
个中断,EventID可以与中断ID相同,也可以通过ITS传输给中断。
DeviceID: 表示哪个设备产生中断;
ITS将设备写入GITS_TEANSLATER的EventID转化为中断号,每个设备有指定的中断号,所以DeviceID是必须。
LPI中断的中断号是被组织到cellections。在同一cellections的中断会路由到同一个Redistributor。软件分配LPI中断的中断号到Collections,便于高效的移动中断从一个PE到另一个PE。
ITS使用3种table来处理LPI中断的转换和路由:
Device Tables ,DeviceID到中断的转化表
Interrupt Translation Tables , 包含了DeviceID指定的EventID和INTID之间的映射,也包含中断所属的Collection。
Collection Tables , Collection和Redistributor之间的映射
当设备写入GITS_TRANSLATER时,ITS中断:
- 依据DeviceID选择合适的入口从Device Table,该入口即为要使用的中断转化表;
- 依据EventID选择合适的入口从Interrupt Translation Table,该入口包含了中断号和Collection ID
- 依据Collection ID选择合适的入口从 Collection Table,该入口包含路由信息
- 将中断转交给目标Redistributor
ITS默认支持数个硬件cellections。硬件celections是ITS持有的内部配置,而不是将配置设置保存在内存中。GITS_TYPER.HCC反应了支持硬件collection的个数。
4.1.2 ITS的命令队列
ITS在内存中的命令队列进行控制,该命令队列是一个环形buffer,他的相关定义在三个寄存器中:
- GITS_CBASER 命令队列的及地址和大小,命令队列必须64Kb对齐、命令队列大
- 小是4KB的倍数。命令队列的每个入口是32Bytes。该寄存器还指定了ITS访问命令队列
- 时使用的可缓存、可共享设置。
- GITS_CREADR 此寄存器指向ITS将处理的下一条命令
- GITS_CWRITER 此寄存器指向下一条新命令应当被写入到的队列入口
4.1.3 ITS的初始配置
系统开始运行时,软件需要进行ITS配置:
1.为Device & Collection Table分配内存
GITS_BASER[0…7] 寄存器指定ITS Device&Collection Table的基地址和大小,软
件使用这些寄存器管理ITS表的类型和数量。系统软件必须分配需要的内存,并保存该内
存指针到GITS_BASERn寄存器。
2.为命令对列分配内存
软件必须分配为命令队列并将该内存指针设置到GITS_CBASER
GITS_CWRITER寄存器。
3.使能ITS
当表和命令队列被分配后,可以通过设置GITS_CTLR.Enalbe使能ITS.一旦
GITS_CTLR.Enable被设置,GITS_CBASER、GITS_CWRITER寄存器变为只读。
4.1.4 Collection & Device 表的size和构造
Collection& Device 表的位置和大小配置在GITS_BASERn寄存器中,软件需要分配足够的内存为该表、并配置GITS_BASERn寄存器在使能ITS前。
软件能够根据GITS_BASERn.Indirect的值,分配单级或者多级表。
单级表
单独连续的块内存被分配给ITS用来记录映射。在使能ITS前,需要立即填冲该内存,此后该表将被ITS用于保存要处理命令的命令队列
GITS_BASERn.Entry_Size : entry size
GITS_BASERn.Page_Size : page size ,as 4KB 16KB or 64KB
两级表
两级表时,也是通过软件进行First & Second表的分配。通过软件分配的第一级表中每个入口都指向一个第二级表或者被标记为无效。第二级表必须用0填充,在该表被移交给ITS前。
GITS_Enabled=1时,软件可以分配二级表并将该表更新到一级表中指向该二级表的入口。ITS使能时,软件不能移除或者改变已分配的表位置。
每个二级表占一个page(GITS_BASERn.Page_Size)。
4.1.5 添加新的cmd到名cmd queue
添加新的cmd到cmd queue时软件动作:
1.写新的命令到队列
GITS_CWRITER 指向命令队列中非有效命令的入口,软件需要将新的命令写到该入口
2.更新GITS_CWRITER
软件需要更GITS_CWRITER用新命令的入口,用以通知ITS新的命令已经被添加。在确
保命令队列空间足够情况下,软件可以同时添加多个命令到命令队列。
3.等到命令被ITS读取
软件可以通过轮询GITS_CREADER状态来检查,命令是否被ITS读取。
当GITS_CWRITER.Offset = GITS_CREADER.Offset时表示所有ITS读取了所有命
令(GITS_CWRITER.Offset > GITS_CREADER.Offset 表示cmd queue是满的)。
或者,添加中命令产生中断信信号、用于命表示令组被ITS读取。
ITS是按照顺序读取命令从命令队列中,然而在Redistibutor上的名利给可能是乱
序的,SYN命令可以保证此前的命令的有序性。
4.1.6 映射中断到Redistributor
映射DeviceID到Translation table
每个能够产生中断到ITS的外设都有自己的DeviceID,每个DeviceID有自己的中断转换
表(ITT),将EventID转化为中断映射。软件必须分配内存给ITT,并使用MAPD命令实
现DeviceDI到ITT的映射。
MAPD <DeviceID>, <ITT_Address>,<Size>
映射INTID到Collection,从Collection到Redistributor
当设备的DeviceID被映射到ITT时,其发送的EventID也必须被映射到INTID,这些
INTID必须被映射到collections,每个collection必须被映射到目标Redistributor。
INTID可以通过MAPTI和MAPI命令映射到Collections。EventID = INTID时,使用
MAPI命令;否则使用MAPTI命令。
MAPTI <DeviceID>,<EventID>,<INTID>,<CollectionID>
MAPI <DeviceID>,<EventID>,<CollectionID>
Collection通过MAPC命令映射到Redistributor
MAPC <ColectionID>,<Target Redistributor>
Target Redistrbutord的ID依赖于GITS_TYPE.PTA:
- GITS_TYPER.PTA = 0 : Redistributor ID取决于 GICR_TYPER.Processor_Number
- GITS_TYPER.PTA = 1 : Redistributor ID通过地址指定
4.1.7 在Redistributor之间迁移中断
有多种方式实现中断在不同的Redistirbutor间迁移:
重映射collection
软件可以迁移所有中断从一个Redistributor到另一个Redistributor,通过重新映
射collection。这是一种典型的实现中断迁徙的方式,当PE连接的Redistributor被关
闭时中断必须移到其他Redistributor。
实现该动作的命令序列如下:
MAPC <CollectionID>,<RDADDR2> //映射Collection到新的Redistributor
SYNC <RDADDR2> //确保映射生效,RDADDR2表示新的Redistributor
MOVALL <RDADDR1>,<RDADDR2> //从之前的Redistributor迁移到新的Redistributor
SYNC <RDADDR1>//确保迁移生效,RDADDR1表示老的Redistributor
映射中断到不同的collection
中断可以通过如下命令序列实现到不同collection的映射。
MOVI <DeviceID>,<EventID>,<ID of new collection>
SYNC <RDADDR1>
4.1.8 移除中断映射
重映射或者移除一个已被映射的中断,软件动作:
1.从LPI配置表中disable已映射的物理中断
2.执行discard命令,用来移除中断映射并清除中断的pending状态;
3.执行sync命令、并等待该命令的完成
4.2 Redistributors
Redistribtor通过内存表实现所有物质LPI的控制、优先设置和pending信息。LPI配置信息存储在GICR_PROPBASER寄存器指向的内存表,LPI配置表是全局的,对所有Redustributor均可见并内容一致。通常系统有所有Redistributor共享的一个LPI配置表。
LPI的状态信息也是存在内存表,即GICR_PENDING寄存器指向的LPI Pending状态表。每个Redistributor有自己的LPI Pending状态表,不同的Redistributor有不同的LPI Pending表。
4.2.1 Redistributor的初始化配置
系统中初始化Redistributor步骤如下:
a.给LPI Configuration Table 分配内存,并位每个LPI完成Table的初始配配置;
b.将LPI配置表的地址设置到GICR_PROPBASER寄存器
c.为LPI Pending Table分配内存,并进行初始配置;系统启动时,所有的内存为
值为零,因此此时所有的LPI中断为非激活状态;
e.通过设置GICR_CTRL.EnableLPIS为1来使能LPI,
当GICR_CTRL.EnalbeLPIS设置为1时,
GCIR_PENDBASE & GICR_PROPBASER寄存器为只读状态。
LPI COnfiguration Table
LPI Configuration Table有一个字节为每个LPI中断,如下图:
SPI、PPI、SGI中断的优先级为8bit,但是LPI的中断优先级只有6bit,低两位通常作为0. LPI也总是被当作Non-Secure Group1 中断。
LPI配置表和所占用内存的大小依赖于LPI中断的数量,GICD_YPER.IDbits寄存器表示
GIC支持中断(包含 SPI、PPI、SGI和LPI)数量,LPI的使用大于8191的中断号,因此
可支持的LPI中断数量等于
支持的LPI中断数量可能小于上述计算,GICR_PROPBASER寄存器的IDbits位表示
了支持LPI中断的数量。这个数量需等于或者小于GICD_TYPER中相同IDbits值。软件
需要分配足够数量的entry,故需要分配2GICD_PROPBASER.IDbits+1 - 8192个LPI
配置表。
中断控制器能够读取为LPI配置表分配的内存但是不能写该内存。
LPI Pending table
LPI的状态信息也存储在内存中,LPI中断有两种状态:inactive&pending。
当LPI中断被ACK后,该中断状态从pending转化到inactive。因为LPI中断只有两
种状态,所以每个LPI中断状态在LPI Pending Table中仅占1bit。
GICR_PROPBASER.IDbit位也决定了LPI Pending Table的大小。
中断控制器可以读/写为LPI Pending Table分配的内存。典型地当有太多的pending
中断需要缓存或者进入低功耗状态时,Redistributor需要缓存最高优先级的pending状态
的中断在内部,写LPI中断状态信息到外部的LPI Pending Talbe。
4.2.2 重新配置LPI
LPI的配置信息存储在内存也非寄存器中,redistributor可以缓存LPI配置信息。故要
重新配置LPI,软件需要:
1.更新entry在LPI配置表中;
2.确保更新内容全局可见;
3.使用INV或者INVALL命令使redistributor中缓存的LPI配置信息失效;
5. 发送&接收SGI中断
SGI, software generated interrupt,软件中断,软件通过写中断控制器的寄存器触发的中断。
5.1 SGI中断的产生
通过写CPU interface的SGI寄存器产生SGI中断。
SGI ID:bit24 - bit27 ,产生的SGI的中断号,SGI中断的中断号范围 0 -15
IRM: bit40, interrupt routing mode 中断路由模式,表示SGI中断被发送给哪个PE。
IRM=1,SGI中断被发送给除了产生SGI的PE外的其他所有PE;
IRM=0,SGI中断发送给aff3.aff2.aff1.TargetList,TargetList是位编 码形式,其
中1个bit位表示aff1下的1个aff0 node。
5.2 安全状态与分组
安全状态和SGI的分组依赖于:
a.SG寄存器(ICC_SGI0R_El1、ICC_SGI1R_EL1、ICC_ASGIR_EL1),这些寄存
寄存器是在PE启动时通过软件进行配置
b.GICR_IGROUP、GICR_IGRPMODR0 配置目标PE寄存器
执行在安全环境的软件能够产生安全和非安全的SGI中断。执行在非安全环境的软件
可以通过控制GICR_NSACR寄存器产生安全的SGI中断,该寄存器仅在安全软件环境下访
问。下图为PE的不同的安全状态下、不同SGI寄存器状态时产生SGI中断的处理情况。
GICv3新增特性
支持message-based interrupt
系统可访问CPU register
参考文档
GICv3_Software_Overview_Official_Release