Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

第4章:物理中断处理和优先级

本章描述了GIC中断处理和优先级的基本方面。它包含以下部分:

  • 中断生命周期

  • 局部特定外设中断

  • 私有外设中断

  • 软件生成中断

  • 共享外设中断

  • 中断分组

  • 启用中断分发

  • 中断优先级

4.1 中断生命周期

GIC中断处理基于GIC中断生命周期,这是一系列适用于使用GIC架构的任何中断的高级流程。中断生命周期为描述中断处理过程的详细步骤提供了基础。GIC还维护一个状态机,在生命周期期间控制中断状态转换。

图4-1显示了物理中断的GIC中断生命周期。

图片文本

Start
Generate
A device generates an
interrupt
Distribute
Deliver The CPU interface
delivers interrupt to the
PE
Activate
The PE acknowledges
the interrupt
Priority
drop The PE ends the
interrupt
Deactivation [a]
End
a. This step does not apply to LPIs.

***图4-1 物理中断生命周期***

图4-1中的中断生命周期如下:

  1. 生成中断。中断由外设或软件生成。

  2. 分发。IRI执行中断分组、中断优先级处理,并控制中断向CPU interface的转发。

  3. 投递。物理CPU interface将中断投递到对应的PE。

  4. 激活。当在PE上运行的软件确认一个中断时,GIC将最高活跃优先级设置为被激活中断的优先级,对于SPI、SGI和PPI,中断变为活跃状态。

  5. 优先级下降。在PE上运行的软件向GIC发出信号,表示最高优先级中断已处理到可以下降运行优先级的程度。运行优先级然后具有中断确认之前的值。这是中断处理程序指示中断结束的点。中断结束也可以配置为同时执行中断去激活。

  6. 去激活。去激活清除中断的活跃状态,从而允许中断在挂起时再次被获取。LPI不需要去激活。去激活可以配置为与优先级下降同时发生,或者可以配置为稍后作为显式中断去激活操作的结果发生。后一种方法允许软件架构在将中断处理分为初始处理和调度处理方面有优势。

4.1.1 物理CPU interface

CPU interface为连接到GIC的PE提供接口。每个CPU interface连接到单个PE。

CPU interface接收由IRI优先级处理的挂起中断,并确定中断是否是在CPU interface中启用的组的成员,以及是否具有足够的优先级以向PE发送信号。在任何时候,连接的PE都可以确定:

  • 其最高优先级挂起中断的INTID,通过读取ICC_HPPIR0_EL1或ICC_HPPIR1_EL1。

  • CPU interface的运行优先级,通过读取ICC_RPR_EL1。

注意

尚未进行优先级下降的最高优先级活跃中断的优先级也称为运行优先级。

当确认LPI时,中断的挂起状态在Redistributor中变为非挂起。Redistributor不为LPI维护活跃状态。

当PE在CPU interface确认SGI、PPI或SPI时,如果满足以下条件,IRI将中断状态更改为活跃:

  • 它是边缘触发中断,并且自中断确认以来没有检测到另一个边缘。

  • 它是电平敏感中断,并且自中断确认以来电平已去断言。

当PE在CPU interface确认SGI、PPI或SPI时,如果满足以下条件,IRI将中断状态更改为活跃和挂起:

  • 它是边缘触发中断,并且自中断确认以来检测到另一个边缘。

  • 它是电平敏感中断,并且自中断确认以来电平未去断言。

当PE在CPU interface确认SGI、PPI或SPI时,CPU interface可以向PE发送另一个中断信号,以抢占在PE上活跃的中断。如果没有具有足够优先级向PE发送信号的挂起中断,interface去断言向PE的中断请求信号。

中断生命周期的以下阶段在本节的其余部分中描述:

  • 激活

  • 优先级下降

  • 去激活

优先级下降和去激活可以作为单个操作执行,也可以分开,由ICC_CTLR_EL1.EOImode和ICC_CTLR_EL3.EOImode_EL3定义。

激活

中断处理程序读取相应CPU interface中Group 0中断的ICC_IAR0_EL1和Group 1中断的ICC_IAR1_EL1来确认中断。这个读取返回以下之一:

  • 最高优先级挂起中断的INTID,如果该中断具有足够的优先级向PE发送信号。这是对中断确认的正常响应。

  • 在特定条件下,指示特殊中断号的INTID,参见_INTID_。

读取ICC_IAR0_EL1和ICC_IAR1_EL1是否返回有效INTID取决于:

  • 访问的是这两个寄存器中的哪一个。

  • PE的Security状态。

  • 是否有具有足够优先级向PE发送信号的挂起中断,如果有,是否:

    • 最高优先级挂起中断是Secure Group 1或Non-secure Group 1中断。

    • 该中断组的中断信号发送已启用。

  • PE执行的Exception level。

所有中断在确认时都会修改_Active Priorities Registers_。参见_系统寄存器访问Active Priorities寄存器_。

在某些情况下,SCR_EL3.NS的值影响PE确认中断时返回的值。也就是说,当PE在EL3执行时,ICC_IAR0_EL1的Secure读取返回一个特殊中断号,指示最高优先级挂起中断所需的Security状态转换。否则,返回INTID。

对于多处理器实现中的SGI,GIC使用目标列表模型,其中一个PE确认中断对其他CPU interface上的中断状态没有影响。当PE确认中断时,中断的挂起状态仅对该PE清除。中断对其他PE保持挂起。

读取ICC_IAR0_EL1和ICC_IAR1_EL1对返回INTID状态的影响在DSB执行之后才保证可见。

优先级下降

中断确认后,对Group 0中断的ICC_EOIR0_EL1的有效写入,或对Group 1中断的ICC_EOIR1_EL1的有效写入,导致优先级下降。

对ICC_EOIR0_EL1或ICC_EOIR1_EL1的有效写入以执行优先级下降对于每个确认的中断都是必需的,即使对于没有活跃状态的LPI也是如此。优先级下降必须由激活中断的同一个PE执行。

注意 有效写入是满足以下条件的写入:

  • 不是UNPREDICTABLE。

  • 不被忽略。

  • 不是写入不支持的或在1020-1023范围内的INTID。

对于每个CPU interface,GIC架构要求对ICC_EOIR0_EL1和ICC_EOIR1_EL1的有效写入的顺序与从ICC_IAR0_EL1和ICC_IAR1_EL1的读取顺序完全相反,如图4-2所示。

图片文本

Read order
ICC_IAR0_EL1 1
ICC_IAR1_EL1 2
ICC_IAR0_EL1 3
ICC_IAR0_EL1 4
Write order
4 ICC_EOIR0_EL1
3 ICC_EOIR0_EL1
2 ICC_EOIR1_EL1
1 ICC_EOIR0_EL1

***图4-2 读取和写入顺序***

在优先级下降时,运行优先级从由写入ICC_EOIR0_EL1或ICC_EOIR1_EL1指示的中断的优先级降低到:

  • 尚未写入ICC_EOIR0_EL1或ICC_EOIR1_EL1的最高优先级活跃中断的优先级。

  • 如果没有活跃中断,则为空闲优先级0xFF。

注意 为了与GIC架构规范的可能扩展兼容,软件在确认中断时必须保留从ICC_IAR0_EL1和ICC_IAR1_EL1读取的整个寄存器值,并使用该整个值由同一PE对ICC_EOIR0_EL1和ICC_EOIR1_EL1进行相应写入。

当GICD_CTLR.DS == 0时:

  • 对ICC_EOIR0_EL1的写入为Group 0中断执行优先级下降。

  • 如果PE在Non-secure状态或EL3操作,对ICC_EOIR1_EL1的写入为Non-secure Group 1中断执行优先级下降。

  • 在Secure状态操作时,对ICC_EOIR1_EL1的写入为Secure Group 1中断执行优先级下降。

当GICD_CTLR.DS == 1时:

  • 对ICC_EOIR0_EL1的写入为Group 0中断执行优先级下降。

  • 对ICC_EOIR1_EL1的写入为Group 1中断执行优先级下降。

去激活

PPI、SGI和SPI在IRI中有活跃状态,必须被去激活。

SGI和PPI必须由激活中断的PE去激活。SPI可以由不同的PE去激活。

中断去激活需要将中断状态更改为:

  • 从活跃和挂起变为挂起。

  • 从活跃变为非活跃。

根据Exception level和Security状态,适当CPU Interface Control Register中的ICC_CTLR_EL1.EOImode和ICC_CTLR_EL3.EOImode_EL3确定优先级下降和中断去激活是一起发生还是分别发生:

  • 当CPU interface中的ICC_CTLR_EL1.EOImode或ICC_CTLR_EL3.EOImode_EL3为0时,优先级下降和中断去激活一起发生,PE写入ICC_EOIR0_EL1或ICC_EOIR1_EL1。在这种情况下,不需要写入ICC_DIR_EL1。

  • 当CPU interface中的ICC_CTLR_EL1.EOImode或ICC_CTLR_EL3.EOImode_EL3为1时,优先级下降和中断去激活分离,PE写入ICC_EOIR0_EL1或ICC_EOIR1_EL1。在这种情况下:

    • 当PE写入ICC_EOIR0_EL1或ICC_EOIR1_EL1时发生优先级下降。

    • 中断去激活稍后发生,当PE写入ICC_DIR_EL1时。对ICC_DIR_EL1的有效写入导致Group 0或Group 1中断的中断去激活。

对ICC_DIR_EL1的写入没有排序要求。如果软件在以下条件为真时写入ICC_DIR_EL1,结果是不可预测的:

  • 适当的EOIMode位清除为0。

  • ICC_CTLR_EL1.EOImode或ICC_CTLR_EL3.EOIMode_EL3设置为1,并且没有对ICC_EOIR0_EL1或ICC_EOIR1_EL1进行相应写入。

当ICC_CTLR_EL1.EOImode或ICC_CTLR_EL3.EOIMode_EL3 == 1但中断在Distributor中不活跃时,对ICC_DIR_EL1的写入必须被忽略。如果支持,实现可能生成系统错误。

表4-1显示了写入ICC_EOIR0_EL1或ICC_EOIR1_EL1如何影响去激活。

表4-1 写入ICC_EOIR0_EL1或ICC_EOIR1_EL1的影响

访问ICC_CTLR_EL1.EOImode或 ICC_CTLR_EL3.EOImode_EL3识别的 中断影响
ICC_EOIR1_EL10Group 0访问被忽略
ICC_EOIR0_EL10Group 0中断去激活
ICC_EOIR1_EL10Group 1中断去激活
ICC_EOIR0_EL10Group 1访问被忽略
-1-中断保持活跃

当GICD_CTLR.DS == 0时,对某些寄存器的访问受到限制。参见_中断分组和安全性_。

以下伪代码确定是否为当前Exception level和Security状态设置EOImode:

// EOImodeSet()
// ============

boolean EOImodeSet()

     if HaveEL(EL3) then
         // EL3 is implemented so return the value appropriate to the EL and security state
         if IsEL3OrMon() && ICC_SRE_EL3.SRE == '1'1 then
             // In EL3
             EOImode = ICC_CTLR_EL3.EOImode_EL3;

         elsif IsSecure() then
             EOImode = ICC_CTLR_EL3.EOImode_EL1S;

         else                                                  // Non-secure
              EOImode = ICC_CTLR_EL3.EOImode_EL1NS;
     else
         // No EL3 so return the value from ICC_CTLR_EL1
         EOImode = ICC_CTLR_EL1.EOImode;

     return EOImode == '1';

Security状态对ICC_DIR_EL1写入的影响

对ICC_DIR_EL1的写入的影响取决于GIC是否支持一个或两个Security状态:

  • 如果GICD_CTLR.DS == 0,有效的:

    - 对ICC_DIR_EL1的Secure写入去激活指定的中断,无论该中断是Group 0还是Group 1中断。
    
    • 对ICC_DIR_EL1的Non-secure写入仅在该中断是Non-secure Group 1中断时才去激活指定的中断。
  • 如果GICD_CTLR.DS == 1,对ICC_DIR_EL1的有效写入去激活指定的中断,无论该中断是Group 0还是Group 1中断。

表4-2显示了对ICC_DIR_EL1的有效写入的行为。在仅支持单个Security状态的实现中,有效写入具有对ICC_DIR_EL1的Secure写入所示的行为。

表4-2 对ICC_DIR_EL1写入的行为

对ICC_DIR_EL1写入的Security状态和Exception level中断组GICD_CTLR.DSSCR_EL3.IRQSCR_EL3.FIQ影响
EL3xxxx中断被去激活
Secure EL1或Secure EL2Group 0xx0中断被去激活
Secure EL1或Secure EL2Group 0xx1写入被忽略
Secure EL1或Secure EL2Group 1x0x中断被去激活
Secure EL1或Secure EL2Group 1x1x写入被忽略
EL2或Non-secure EL1Group 0或Secure Group 10xx写入被忽略
EL2或Non-secure EL1Group 01x0中断被去激活
EL2或Non-secure EL1Group 01x1写入被忽略
EL2或Non-secure EL1Non-secure Group 100x中断被去激活
EL2或Non-secure EL1Non-secure Group 101x写入被忽略
EL2或Non-secure EL1Group 110x中断被去激活
EL2或Non-secure EL1Group 111x写入被忽略

只有当SCR_EL3.EEL2 == 1时,才能进入Secure EL2。

4.1.2 中断处理状态机

GIC为每个支持的中断维护状态机。中断的可能状态是:

  • 非活跃。

  • 挂起。

  • 活跃。

  • 活跃和挂起。

PPI、SGI和SPI可以具有活跃和挂起状态。活跃和挂起的中断永远不会向连接的PE发送信号。

LPI具有保存在与Redistributor相关联的内存中的挂起状态,因此也与PE相关联。这也适用于直接注入的虚拟LPI,参见_关于GICv4.0虚拟局部特定外设中断支持_。

注意 LPI没有活跃或活跃和挂起状态。

图4-3显示了中断处理状态机的实例和可能的状态转换。

图片文本

Active and
D pending [a]
A1
E2
Inactive Pending A2 B2
B1 C
Active [a]
E1

![](images/gicv3_ihi0069.pdf-0054-06.png)

a. 当GICD_CTLR.nASSGIreq==1时不适用于SGI,
对LPI也不适用。 图4-3 中断处理状态机

注意 LPI在Redistributor中没有活跃状态,但在CPU interface中需要活跃优先级。参见第5章_局部特定外设中断和ITS_获取更多信息。

Arm期望硬件实现报告GICD_TYPER2.nASSGIcap==0,表示GICD_CTLR.nASSGIreq为RES0。

当Distributor的中断转发和CPU interface的中断信号发送启用时,引起每个状态转换的条件如下:

转换A1或A2,添加挂起状态

当中断变为挂起时发生此转换,要么是由于外设生成中断,要么是由于软件生成中断。

转换B1或B2,移除挂起状态

当中断被外设去断言时(如果中断是电平敏感中断),或当软件更改挂起状态时,发生此转换。

对于LPI,它也在中断确认时发生。

转换C,挂起到活跃

对于边缘触发的SPI、SGI和PPI,此转换在PE确认中断时发生。

对于SPI、SGI和PPI,此转换在软件从ICC_IAR0_EL1或ICC_IAR1_EL1读取INTID值时发生。

转换D,挂起到活跃和挂起

对于电平敏感的SPI、SGI和PPI,此转换在PE确认中断时发生。

转换E1或E2,移除活跃状态

对于SPI、SGI和PPI,此转换在软件去激活中断时发生。

4.2 局部特定外设中断

LPI是目标外设中断,路由到亲和性层次结构内的特定PE。在启用两个Security状态的系统中,LPI始终是Non-secure Group 1中断。LPI仅支持边缘触发行为。有关LPI的更多信息,参见_LPI_。

4.3 私有外设中断

PPI是针对单个特定PE的中断,不同的PE可以使用相同的INTID来指示不同的事件。PPI可以是Group 0中断、Secure Group 1中断或Non-secure Group 1中断。它们可以支持边缘触发或电平敏感行为。

可选的扩展PPI范围使用INTID 1056 - 1119。当GIC在legacy mode操作时,此PPI范围不可用。GICR_TYPER.PPInum指示是否支持扩展PPI范围。

注意 通常,Arm期望PPI由每个PE上相同中断源的不同实例使用,从而允许为PE特定事件(例如来自私有定时器的中断)使用通用INTID。

4.4 软件生成中断

SGI通常用于处理器间通信,通过写入GIC中的SGI寄存器生成。SGI可以是Group 0或Group 1中断,它们只能支持边缘触发行为。

与SGI生成相关的寄存器是CPU interface的一部分:

  • PE通过写入ICC_SGI1R_EL1或ICC_ASGI1R_EL1生成Group 1 SGI。

  • PE通过写入ICC_SGI0R_EL1生成Group 0 SGI。

  • 路由信息作为生成SGI的寄存器写入中的位域值提供。SGI可以路由到:

    • 由a.b.c.targetlist指定的PE组。这可以包括发起PE。

    • 系统中的所有参与PE,除了发起PE。

有关更多信息,参见_按PE亲和性路由SPI和SGI_。

ICC_SGI1R_EL1允许在Secure状态执行的软件生成Secure Group 1 SGI。

ICC_SGI1R_EL1允许在Non-secure状态执行的软件生成Non-secure Group 1 SGI。

ICC_ASGI1R_EL1允许在Secure状态执行的软件生成Non-secure Group 1 SGI。

ICC_ASGI1R_EL1允许在Non-secure状态执行的软件生成Secure Group 1 SGI,如果目标PE对应的Redistributor中的GICR_NSACR设置允许的话。

ICC_SGI0R_EL1允许在Secure状态执行的软件生成Group 0 SGI。

ICC_SGI0R_EL1允许在Non-secure状态执行的软件生成Group 0 SGI,如果目标PE对应的Redistributor中的GICR_NSACR设置允许的话。

有关使用控制寄存器将SGI转发到目标PE的更多信息,参见表12-14。

4.5 共享外设中断

SPI是外设中断,Distributor可以将其路由到可以处理中断的指定PE,或路由到系统中已配置为接受此类中断的一组PE中的一个PE。SPI可以是Group 0或Group 1中断,它们可以支持边缘触发或电平敏感行为。

可选的扩展SPI范围使用INTID 4096 - 5119。当GIC在legacy mode操作时,此SPI范围不可用。GICD_TYPER.ESPI指示是否支持扩展SPI范围。

SPI可以是基于线的或基于消息的中断。

对基于消息的SPI的支持是可选的,可以通过GICD_TYPER.MBIS发现。基于消息的SPI可以是:

  • 通过写入GICD_SETSPI_NSR或GICD_SETSPI_SR生成

  • 通过写入GICD_CLRSPI_NSR或GICD_CLRSPI_SR清除。

写入这些寄存器的影响取决于目标SPI是否配置为边缘触发或电平敏感中断:

  • 对于边缘触发中断,写入GICD_SETSPI_NSR或GICD_SETSPI_SR设置中断挂起。当中断被激活时,或通过写入GICD_CLRSPI_NSR、GICD_CLRSPI_SR或GICD_ICPENDR清除时,中断不再挂起。

  • 对于电平敏感中断,写入GICD_SETSPI_NSR或GICD_SETSPI_SR设置中断挂起。它保持挂起直到通过写入GICD_CLRSPI_NSR或GICD_CLRSPI_SR去断言。如果中断在通过写入GICD_SETSPI_NSR或GICD_SETSPI_SR断言和通过写入GICD_CLRSPI_NSR或GICD_CLRSPI_SR去激活之间被激活,则中断变为活跃和挂起。

    • 对于电平敏感中断,写入GICD_ICPENDR对通过写入GICD_SETSPI_NSR或GICD_SETSPI_SR设置为挂起的中断是否有任何影响,或者写入GICD_CLRSPI_NSR或GICD_CLRSPI_SR对通过写入GICD_ISPENDR设置为挂起的中断是否有任何影响,是IMPLEMENTATION DEFINED。

    • 确认通过写入GICD_ISPENDR设置为挂起的中断是否清除挂起状态是IMPLEMENTATION DEFINED。

  • 当有挂起中断时将中断配置从电平敏感更改为边缘触发,或从边缘触发更改为电平敏感,会使中断处于UNKNOWN状态。

图4-4显示基于消息的中断请求如何触发SPI。

Wire-basedWire-basedWire-basedWire-basedWire-basedWire-basedSPIsSPIsSPIs
Message-Distributor
based SPIsGICD_SETSPI_SR registersGICD_SETSPI_NSRregisters
GICD_CLRSPI_SR registersGICD_CLRSPI_NSRregisters
x.y.0.0PE RedistributorCluster C0x.y.0.1PEx.y.0.2PECPU interfacex.y.n.0PEClusterPE x.y.n.1 Cn

图4-4 触发SPI

4.6 中断分组

GICv3使用_中断分组_作为将中断处理与Armv8 Exception模型和Security模型对齐的机制。

在具有两个Security状态的系统中,中断配置为以下之一:

  • Group 0物理中断:

    • Arm期望这些中断在EL3处理。
  • Secure Group 1物理中断:

    • Arm期望这些中断在使用Secure虚拟化的系统中在Secure EL1或Secure EL2处理。
  • Non-secure Group 1物理中断:

    • Arm期望这些中断在使用虚拟化的系统中在Non-secure EL2处理,或在不使用虚拟化的系统中在Non-secure EL1处理。

在具有一个Security状态的系统中,中断配置为:

  • Group 0。

  • Group 1。

在系统级别,GICD_CTLR.DS指示GIC是否配置为一个或两个Security状态。有关Security的更多信息,参见_中断分组和安全性_。

这些中断组映射到Armv8 FIQ和IRQ异常,参见_中断分配到IRQ和FIQ信号_。

GICD_IGROUPR和GICD_IGRPMODR配置SPI的中断组,GICD_IGROUPRE和GICD_IGRPMODRE配置扩展SPI范围的中断组。_n_大于零。

GICR_IGROUPR0和GICR_IGRPMODR0配置SGI和PPI的中断组,GICR_IGROUPRE和GICR_IGRPMODRE配置扩展PPI范围的中断组。_n_大于零。

注意

当GICD_CTLR.DS == 0时,LPI始终是Non-secure Group 1中断。当GICD_CTLR.DS == 1时,LPI始终是Group 1中断。

系统寄存器控制和配置Group 0和Group 1中断:

  • 对于Group 0中断,软件使用:

    • ICC_IAR0_EL1在中断确认时读取Group 0 INTID。

    • ICC_EOIR0_EL1写入Group 0中断完成。

    • ICC_BPR0_EL1配置Group 0优先级的binary point。当ICC_CTLR_EL1.CBPR == 1时,此寄存器也用于Group 1优先级。

    • ICC_HPPIR0_EL1读取当前挂起的最高Group 0中断。

    • ICC_IGRPEN0_EL1在CPU interface启用Group 0中断。

  • 对于Group 1中断,软件使用:

    • ICC_IAR1_EL1在中断确认时读取Group 1 INTID。

    • ICC_EOIR1_EL1写入Group 1中断完成。

    • ICC_BPR1_EL1为当前Security状态配置Group 1优先级的binary point。

    • ICC_HPPIR1_EL1读取当前挂起的最高Group 1中断。

    • ICC_IGRPEN1_EL1为中断的目标Security状态启用Group 1中断。

在具有两个Security状态的系统中,Group 0中断始终是Secure的。有关分组和Security的更多信息,参见_中断分组和安全性_。

4.6.1 中断分组和安全性

Arm架构提供两个Security状态,每个状态都有相关的物理内存地址空间:

  • Secure状态。

  • Non-secure状态。

用户和特权代码的软件层次结构可以在任一状态执行,在Non-secure状态执行的软件只能通过对Secure monitor的系统调用访问Secure状态。GIC架构支持与两个Security状态相关的中断的路由和处理。

GICD_CTLR.DS指示GIC是否配置为支持Armv8-A Security模型。此配置影响:

  • 寄存器访问,参见_GIC系统寄存器访问_。

  • 支持的中断组。

当GICD_CTLR.DS == 0时:

  • GIC支持两个Security状态,Secure状态和Non-secure状态。

  • GIC支持三个中断组:

    - Group 0。
    
    - Secure Group 1。
    
    • Non-secure Group 1。
  • Security状态和GICR_NSACR都确定是否可以生成SGI。

  • 在以下期间检查Security状态:

    - 中断配置。
    
    - 中断确认。
    
    • 优先级下降。

    • 去激活。

  • 如果满足以下条件,Secure Group 1中断被CPU interface视为Group 0:

    • PE未实现EL3。

    • ICC_SRE_EL1(S).SRE == 0。

当GICD_CTLR.DS == 1时:

  • GIC仅支持单个Security状态。这可以是Secure状态或Non-secure状态。

  • GIC支持两个中断组:

    • Group 0。

    • Group 1。

  • 无论GICR_NSACR中的设置如何,都可以生成SGI。

  • 在以下期间不检查Security状态:

    • 中断配置。

    • 中断确认。

    • 优先级下降。

  • 去激活。

在多处理器系统中,系统内的一个或多个PE可能支持访问仅在Secure状态可用的资源,或访问仅在Non-secure状态可用的资源。如果软件配置以下情况,这是编程错误:

  • Group 0或Secure Group1中断转发到仅支持Non-secure状态的PE。

  • Non-secure Group1中断转发到仅支持Secure状态的PE。

每个中断组都有专用的优先级分组寄存器,Group 0中断的ICC_BPR0_EL1和Group 1中断的ICC_BPR1_EL1。但是,可以使用以下方法为两个组配置通用Binary Point Register:

  • ICC_CTLR_EL1.CBPR。

  • ICC_CTLR_EL3.CBPR_EL1NS和ICC_CTLR_EL3.CBPR_EL1S用于Non-secure Group 1和Secure Group 1中断的独立通用Binary Point Register配置。

有关中断分组和legacy operation的信息,参见第14章_Legacy Operation和不对称配置_。

4.6.2 中断分配到IRQ和FIQ信号

本小节适用于启用亲和性路由的实现。

Group 0物理中断,当它是最高优先级挂起中断并具有足够优先级时,始终作为FIQ发送信号。

Group 1物理中断,当它是最高优先级挂起中断并具有足够优先级时,如果以下任一条件为真,则作为FIQ发送信号,否则作为IRQ发送信号:

  • 它是另一个Security状态的中断,即PE未执行的Security状态。

  • PE在EL3执行。

表4-3总结了EL3使用AArch64状态时的中断信号发送。

表4-3 EL3使用AArch64状态时两个Security状态的中断信号

当前Exception levelGroup 0中断Secure Group 1中断Non-secure Group 1中断
Secure EL1或EL0或EL2FIQIRQFIQ
Non-secure EL1或EL0,或Non-secure EL2FIQFIQIRQ
EL3FIQFIQFIQ

表4-4总结了EL3使用AArch32状态时的中断信号发送。当EL3使用AArch32状态时,Secure EL2不存在。

表4-4 EL3使用AArch32状态时两个Security状态的中断信号

当前Exception levelGroup 0中断Secure Group 1中断Non-secure Group 1中断
Secure EL0FIQIRQFIQ
Non-secure EL1或EL0,或Non-secure EL2FIQFIQIRQ
EL3FIQIRQFIQ

表4-5总结了仅支持单个Security状态的系统中的中断信号发送,即未实现EL3或GICD_CTLR.DS == 1。

表4-5 单个Security状态的中断信号

当前Exception levelGroup 0中断Group 1中断
任意FIQIRQ

IRQ和FIQ的断言和去断言受PE的当前Exception level和Security状态影响。作为由于接受或从异常返回而发生的Context Synchronization的一部分,CPU interface确保IRQ和FIQ都适当地为PE进入的Exception level和Security状态断言或去断言。

注意 有关GICC_CTLR.FIQEn对不对称配置中中断信号发送的影响,参见_不对称配置_。

4.6.3 中断路由和系统寄存器访问

在AArch64状态执行时,到Exception level的中断路由由以下位控制:

  • SCR_EL3.FIQ、SCR_EL3.NS和HCR_EL2.FMO控制FIQ。

  • SCR_EL3.IRQ、SCR_EL3.NS和HCR_EL2.IMO控制IRQ。

此路由还控制控制和确认中断的EL1 CPU interface系统寄存器可访问的Exception level。这适用于:

  • ICC_IAR0_EL1、ICC_EOIR0_EL1、ICC_HPPIR0_EL1、ICC_BPR0_EL1、ICC_AP0R_EL1和ICC_IGRPEN0_EL1。这些是与Group 0中断相关的寄存器。

  • ICC_IAR1_EL1、ICC_EOIR1_EL1、ICC_HPPIR1_EL1、ICC_BPR1_EL1、ICC_AP1R_EL1和ICC_IGRPEN1_EL1。这些是与Group 1中断相关的寄存器。

  • ICC_SGI0R_EL1、ICC_SGI1R_EL1、ICC_ASGI1R_EL1、ICC_CTLR_EL1、ICC_DIR_EL1、ICC_PMR_EL1和ICC_RPR_EL1。这些是通用寄存器。

当(SCR_EL3.NS == 1 || SCR_EL3.EEL2== 1) && (HCR_EL2.FMO ==1 || HCR_EL2.IMO == 1))时,EL1的访问是虚拟访问。对ICC_SGI0R_EL1、ICC_SGI1R_EL1和ICC_ASGI1R_EL1的虚拟访问始终生成被接受到EL2的Trap异常。

当Distributor支持两个Security状态时,PE可能不实现EL2或EL3。表4-6显示了这些情况下支持的配置。

表4-6 未实现EL3时支持的配置

DistributorEL3EL2Security状态描述
两个Security状态,GICD_CTLR.DS == 0-Non-securePE始终是Non-secure,只能接收Non-secure Group 1中断。PE必须表现为软件已经:将ICC_SRE_EL3.Enable设置为1;将ICC_SRE_EL3.DFB设置为1;将SCR_EL3.FIQ设置为1;将SCR_EL3.IRQ清除为0;将SCR_EL3.NS设置为1;将ICC_IGRPEN0_EL1.Enable清除为0;将ICC_IGRPEN1_EL1.Enable的Secure副本设置为0。
两个Security状态,GICD_CTLR.DS == 0SecurePE始终是Secure,只能接收Group 0和Secure Group 1中断。PE必须表现为软件已经:将ICC_SRE_EL3.Enable设置为1;将SCR_EL3.FIQ清除为0;将SCR_EL3.IRQ清除为0;将SCR_EL3.NS清除为0;将ICC_IGRPEN1_EL1.Enable的Non-secure副本清除为0。
一个Security状态,或两个Security状态且GICD_CTLR.DS == 1--Distributor和所有PE始终在单个Security状态,可以接收Group 0和Group 1中断。所有PE必须表现为软件已经:将ICC_SRE_EL3.Enable设置为1;将SCR_EL3.FIQ清除为0;将SCR_EL3.IRQ清除为0;将SCR_EL3.NS设置为1。

4.7 启用中断分发

以下控制位启用和禁用中断分发:

  • GICD_CTLR.EnableGrp1S。

  • GICD_CTLR.EnableGrp1NS。

  • GICD_CTLR.EnableGrp0。

以下控制位在CPU interface启用和禁用中断组的分发:

  • ICC_IGRPEN0_EL1.Enable用于Group 0中断。

  • ICC_IGRPEN1_EL1.Enable用于Group 1中断。

注意

  • 此寄存器有Secure和Non-secure副本。

  • ICC_IGRPEN1_EL3.{EnableGrp1S, EnableGrp1NS}。

通过写入GICR_CTLR.EnableLPIs启用物理LPI。

4.7.1 启用单个中断

PPI

当为中断的Security状态启用亲和性路由时,可以通过写入GICR_ISENABLER0和GICR_ICENABLER0启用和禁用PPI。如果支持并配置了物理中断的legacy operation,单个PPI也可以通过写入GICD_ISENABLER和GICD_ICENABLER启用和禁用。对于PPI,n = 0。

可选扩展PPI范围中的PPI通过写入GICR_ISENABLERE和GICD_ICENABLERE启用和禁用。

SPI

单个SPI可以通过写入GICD_ISENABLER和GICD_ICENABLER启用和禁用。对于SPI,n >0。

可选扩展SPI范围中的SPI通过写入GICD_ISENABLERE和GICD_ICENABLERE启用和禁用。

SGI

当启用亲和性路由时,SGI可以通过写入GICR_ISENABLER0和GICR_ICENABLER0启用和禁用。如果支持并配置了物理中断的legacy operation,单个SGI也可以通过写入GICD_ISENABLER和GICD_ICENABLER启用和禁用。对于SGI,n = 0。

注意 SGI是永久启用的,还是可以通过写入GICR_ISENABLER0和GICR_ICENABLER0启用和禁用,是IMPLEMENTATION DEFINED。

LPI

单个LPI可以通过设置LPI Configuration表中编程的启用位来启用。有关使用LPI Configuration表启用LPI的更多信息,参见_LPI配置表_。

4.7.2 组和单个中断启用的交互

GICD_*和GICR_*寄存器在任何时刻确定硬件为每个目标PE知晓的最高优先级挂起中断。此中断呈现给PE的CPU interface以评估是否向PE发送信号。中断启用影响此评估如下:

  • 在GICD_*或GICR_*寄存器中单独禁用的挂起中断不是确定最高优先级挂起中断时考虑的中断,因此无法向PE发送信号。

  • 在GICD_*或GICR_*寄存器中单独启用但在GICD_CTLR中是禁用组成员的挂起中断不是确定最高优先级挂起中断时考虑的中断,因此无法向PE发送信号。

  • 在GICD_*寄存器中单独启用且在GICD_CTLR中是启用组成员但在PE的ICC_IGRPEN0_EL1、ICC_IGRPEN1_EL1或ICC_IGRPEN1_EL3中是禁用组成员的挂起1 of N中断无法为该PE选择。这样的中断在确定最高优先级挂起中断时不被考虑,因此无法向PE发送信号。

  • 对于在GICD_*或GICR_*寄存器中单独启用且在GICD_CTLR中是启用组成员但在ICC_IGRPEN0_EL1、ICC_IGRPEN1_EL1或ICC_IGRPEN1_EL3中是禁用组成员的挂起直接中断,是否在确定最高优先级挂起中断时考虑该中断是IMPLEMENTATION DEFINED。如果确定为最高优先级挂起中断,中断不向PE发送信号,但将掩码在ICC_IGRPEN0_EL1、ICC_IGRPEN1_EL1或ICC_IGRPEN1_EL3中是启用组成员的较低优先级挂起中断。

LPI在LPI配置表中单独启用,参见_LPI配置表_。

4.7.3 禁用中断的影响

通过写入适当的GICD_ICENABLER或GICR_ICENABLER0,或通过写入LPI配置表禁用中断,不会阻止该中断更改状态,例如变为挂起。当GICR_CTLR.EnableLPIs == 0时,LPI永远不会设置为挂起。

如果GICD_CTLR.EnableGrp0、GICD_CTLR.EnableGrp1S和GICD_CTLR.EnableGrp1NS都清除为0,是否满足以下条件是IMPLEMENTATION DEFINED:

  • 边缘触发中断信号将中断移动到挂起状态。

  • 通过写入GICD_SGIR、ICC_SGI0R_EL1、ICC_SGI1R_EL1或ICC_ASGI1R_EL1可以设置SGI为挂起。

如果当相应的GICD_CTLR.EnableGrp0、GICD_CTLR.EnableGrp1NS或GICD_CTLR.EnableGrp1S位从1写入0时中断在CPU interface上挂起,则必须从CPU interface检索中断。

注意 如果中断已经被激活,这可能对转发的中断没有影响。

如果当软件将ICC_IGRPEN0_EL1.Enable、ICC_IGRPEN0_EL1、ICC_IGRPEN1_EL1.Enable或ICC_IGRPEN1_EL3.Enable从1写入0时中断在CPU interface上挂起,中断必须由CPU interface释放以允许Distributor将中断转发到不同的PE。

4.8 中断优先级

本节描述GIC架构中的中断优先级。优先级描述:

  • 中断优先级的配置和控制。

  • 挂起中断的执行顺序。

  • 确定中断何时对目标PE可见,包括:

    • 中断优先级掩码。

    • 优先级分组。

    • 活跃中断的抢占。

软件通过为每个中断源分配优先级值在GIC中配置中断优先级。优先级值是8位无符号二进制数。支持两个Security状态的GIC实现必须实现最少32个和最多256个物理优先级。仅支持单个Security状态的GIC实现必须实现最少16个和最多256个物理优先级。如果GIC实现少于256个优先级,优先级字段的低位是RAZ/WI。这意味着实现的优先级字段位数是IMPLEMENTATION DEFINED,范围4-8。表4-7显示了优先级字段位与实现支持的优先级数量之间的关系。

表4-7 不实现某些优先级字段位的影响

实现的优先级位可能的优先级字段值优先级数量
[7:0]0x00-0xFF(0-255),所有值256
[7:1]0x00-0xFE,(0-254),仅偶数值128
[7:2]0x00-0xFC(0-252),步长为464
[7:3]0x00-0xF8(0-248),步长为832
[7:4]0x00-0xF0(0-240),步长为1616

在GIC优先级方案中,较小的数字具有较高的优先级。这意味着分配的优先级值越低,中断的优先级越高。优先级字段值0始终指示可能的最高中断优先级,最低优先级值取决于实现的优先级数量。

GICD_IPRIORITYR寄存器保存每个支持的SPI的优先级值。实现可能为特定目的保留SPI并为该中断分配固定优先级,意味着该中断的优先级值是只读的。对于其他SPI,GICD_IPRIORITYR寄存器可以由软件写入以设置中断优先级。写入GICD_IPRIORITYR是否更改任何活跃SPI的优先级是IMPLEMENTATION DEFINED。

在多处理器实现中,GICR_IPRIORITYR和GICR_IPRIORITYRE寄存器为每个目标PE独立定义每个SGI和PPI INTID的中断优先级。

内存中的LPI配置表和LPI挂起表存储LPI优先级信息和挂起状态,参见_LPI配置表_和_LPI挂起表_。

GIC安全模型为中断优先级设置提供Secure和Non-secure访问。Non-secure访问只能在支持的优先级值的较低优先级一半中配置中断。因此,如果GIC实现32个优先级值,Non-secure访问只看到16个优先级值。参见_中断优先级的软件访问_获取更多信息。

要确定SPI实现的优先级位数,软件可以向可写的GICD_IPRIORITYR优先级字段写入0xFF并读回存储的值。

要确定SGI和PPI实现的优先级位数,软件可以向GICR_IPRIORITYR优先级字段写入0xFF并读回存储的值。

GIC架构不要求系统中的所有PE使用相同数量的优先级位来控制中断优先级。

在多处理器实现中,ICC_CTLR_EL1.PRIbits和ICC_CTLR_EL3.PRIbits为每个目标PE独立指示实现的优先级位数。

注意 Arm建议实现为每个PE支持相同数量的优先级位。

有关虚拟中断支持的优先级范围的信息,参见第6章_虚拟中断处理和优先级_。

注意 Arm建议在以这种方式检查优先级范围之前:

  • 对于外设中断,软件首先禁用中断。

  • 对于SGI,软件首先检查中断是非活跃的。

如果在特定CPU interface上,多个挂起中断具有相同优先级,并且具有足够优先级供interface向PE发送信号,interface如何选择向哪个中断发送信号是IMPLEMENTATION DEFINED。

GICv3保证最高优先级、未掩码、启用的中断将在有限时间内投递到目标PE。

不保证较高优先级中断总是在较低优先级中断之前获取,尽管这通常是这种情况。

本节的其余部分描述:

  • 对Secure中断优先级寄存器字段的Non-secure访问

  • 优先级分组

  • 对Active Priorities寄存器的系统寄存器访问

  • 抢占

  • 优先级掩码

  • 中断优先级的软件访问

  • 更改启用的PPI、SGI和SPI的优先级

4.8.1 对Secure中断优先级寄存器字段的Non-secure访问

当GICD_CTLR.DS == 0时,GIC支持使用:

  • Group 0中断作为Secure中断。

  • Secure Group 1中断。

  • Non-secure Group 1中断。

为了支持Armv8 Security模型,与Secure中断相关的寄存器字段对Non-secure访问是RAZ/WI。此外,以下规则适用:

对GICx_IPRIORITYR中优先级字段的Non-secure访问:

如果优先级字段对应于_中断优先级的软件访问_中的Non-secure Group 1中断:

  • 对于SPI,优先级字段由GICD_IPRIORITYR或GICD_IPRIORITYRE确定。

  • 对于PPI和SGI,优先级字段由GICR_IPRIORITYR或GICR_IPRIORITYRE确定。

当SCR_EL3.FIQ == 1时对ICC_PMR_EL1和ICC_RPR_EL1的Non-secure访问:

  • 如果当前优先级掩码值在0x00-0x7F范围内:

    • 读访问返回值0x00。
  • GIC忽略对ICC_PMR_EL1的写访问。

  • 如果当前优先级掩码值在0x80-0xFF范围内:

  • 读访问返回当前值的Non-secure读取。

  • 基于写入寄存器的优先级掩码值的Non-secure读取,对ICC_PMR_EL1的写访问成功。

注意

这意味着Non-secure写入无法在0x00-0x7F范围内设置优先级掩码值。

当SCR_EL3.FIQ == 0时对ICC_PMR_EL1和ICC_RPR_EL1的Non-secure访问:

适用Secure、未移位视图。

_AArch64函数_提供了伪代码,描述了在支持两个Security状态的GIC中对以下系统寄存器的访问:

  • ICC_PMR_EL1。

  • ICC_RPR_EL1。

4.8.2 优先级分组

优先级分组使用以下_Binary Point Registers_:

  • ICC_BPR0_EL1用于Group 0中断。此寄存器在所有GIC实现中可用。

  • ICC_BPR1_EL1的Non-secure副本用于Non-secure Group 1中断。如果实现支持两个Security状态,此寄存器有Secure和Non-secure副本。如果实现仅支持一个Security状态,此寄存器只有一个副本。

  • ICC_BPR1_EL1的Secure副本用于Secure Group 1中断。此寄存器仅在支持两个Security状态的GIC实现中可用。

Binary Point Registers将优先级值分为两个字段,组优先级_和_子优先级。在确定抢占时,具有相同组优先级的所有中断被认为具有相同优先级,无论子优先级如何。

当多个挂起中断具有相同组优先级时,GIC使用子优先级字段解决组内的优先级。当一组中有两个或更多挂起中断具有相同子优先级时,GIC如何在中断之间选择是实现特定的。

GIC使用组优先级字段确定挂起中断是否具有足够优先级抢占PE上的执行,如下:

  • 中断的组优先级字段值必须低于PE的运行优先级值。运行优先级是该PE上尚未接收到优先级下降的最高优先级活跃中断的组优先级。

  • 中断的优先级值必须低于其优先级掩码的值。

ICC_BPR0_EL1确定Group 0中断的优先级分组:

  • 当ICC_CTLR_EL3.CBPR_EL1S设置为1时,ICC_BPR0_EL1也确定Secure Group 1中断的优先级分组。

  • 当ICC_CTLR_EL3.CBPR_EL1NS设置为1时,ICC_BPR0_EL1也确定Non-secure Group 1中断的优先级分组。

ICC_BPR1_EL1确定Group 1中断的优先级:

  • 当ICC_CTLR_EL3.CBPR_EL1S清除为0时,ICC_BPR1_EL1的Secure副本确定Secure Group 1中断的优先级分组。

  • 当ICC_CTLR_EL3.CBPR_EL1NS清除为0时,ICC_BPR1_EL1的Non-secure副本确定Non-secure Group 1中断的优先级分组。

表4-8显示了Secure ICC_BPR1_EL1的中断优先级字段分割。

表4-8 当CBPR == 0时的Secure ICC_BPR1_EL1 Binary Point

ICC_BPR1_EL1 Binary point 优先级字段子优先级字段带binary point的字段
0[7:1][0]ggggggg.s
1[7:2][1:0]gggggg.ss
2[7:3][2:0]ggggg.sss
3[7:4][3:0]gggg.ssss
4[7:5][4:0]ggg.sssss
5[7:6][5:0]gg.ssssss
6[7][6:0]g.sssssss
7无抢占[7:0].ssssssss

表4-9显示了Non-secure ICC_BPR1_EL1的中断优先级字段分割。

表4-9 当CBPR == 0时的Non-secure ICC_BPR1_EL1 Binary Point

ICC_BPR1_EL1 Binary point 优先级字段子优先级字段带binary point的字段
0---
1[7:1][0]ggggggg.s
2[7:2][1:0]gggggg.ss
3[7:3][2:0]ggggg.sss
4[7:4][3:0]gggg.ssss
5[7:5][4:0]ggg.sssss
6[7:6][5:0]gg.ssssss
7[7][6:0]g.sssssss

表4-10显示了ICC_BPR0_EL1的中断优先级字段分割。

表4-10 当CBPR == 1时Group 1中断或Group 0中断的ICC_BPR0_EL1 Binary Point

Binary point值组优先级字段子优先级字段带binary point的字段
0[7:1]ᵃ[0]ggggggg.s
1[7:2]ᵃ[1:0]gggggg.ss
2[7:3]ᵃ[2:0]ggggg.sss
3[7:4]ᵃ[3:0]gggg.ssss
4[7:5]ᵃ[4:0]ggg.sssss
5[7:6]ᵃ[5:0]gg.ssssss
6[7]ᵃ[6:0]g.sssssss
7无抢占[7:0].ssssssss

a. 如果Non-secure写入为Non-secure中断设置优先级值字段,则bit[7] == 1。

支持的最小binary point值取决于IMPLEMENTATION DEFINED的优先级位数,如表4-11所示。

表4-11 最小binary point值支持

实现的优先级位数ICC_BPR0_EL1的最小值
80
70
61
52
43

实现的优先级位数由ICC_CTLR_EL1.PRIBits和ICC_CTLR_EL3.PRIBits指示。

在支持两个Security状态的GIC中,当:

  • ICC_CTLR_EL3.CBPR_EL1S == 1:

    • 在Secure EL1对ICC_BPR1_EL1的写入修改ICC_BPR0_EL1。

    • 在Secure EL1从ICC_BPR1_EL1的读取返回ICC_BPR0_EL1的值。

  • ICC_CTLR_EL3.CBPR_EL1NS == 1:

    • 对ICC_BPR1_EL1的Non-secure写入被忽略。

    • 从ICC_BPR1_EL1的Non-secure读取返回ICC_BPR0_EL1 + 1饱和到0b111。

注意

  • 当中断使用Non-secure ICC_BPR1_EL1时,有效binary point值是存储在寄存器中的值减一,如表4-9所示。这意味着对中断分组影响没有意识且支持两个Security状态的软件,无论它是在Secure状态还是Non-secure状态的PE上运行,都会看到相同的优先级分组机制。

  • 优先级分组总是对完整优先级操作,这是Secure读取可见的值。这与Non-secure读取对应于Non-secure中断的优先级值可见的值不同。参见图4-8和图4-9。

  • 当EL3使用AArch32且ICC_MCTLR.CBPR_EL1S == 1时,在EL3且不在Monitor模式下对ICC_BPR1的访问访问ICC_BPR0的状态。

伪代码

以下伪代码指示中断的组优先级。

// GroupBits()
// ===========
// Returns the priority group field for the current BPR value for the group

bits(8) GroupBits(bits(8) priority, IntGroup group)
    bit cbpr_G1NS = if HaveEL(EL3) then ICC_CTLR_EL3.CBPR_EL1NS else ICC_CTLR_EL1.CBPR;
    bit cbpr_G1S = if HaveEL(EL3) then ICC_CTLR_EL3.CBPR_EL1S else '0';

    if (group == IntGroup_G0 ||
         (group == IntGroup_G1NS && cbpr_G1NS == '1') ||
         (group == IntGroup_G1S && cbpr_G1S == '1')) then
         bpr = UInt(ICC_BPR0_EL1.BinaryPoint);
    elsif group == IntGroup_G1S then
         bpr = UInt(ICC_BPR1_EL1S.BinaryPoint);
    else
         bpr = UInt(ICC_BPR1_EL1NS.BinaryPoint) -1;

    mask = Ones(7-bpr):Zeros(bpr+1);

    return priority AND mask;

4.8.3 系统寄存器访问Active Priorities寄存器

物理Group 0和Group 1中断访问不同的Active Priorities寄存器,取决于中断组。

对于Group 0中断,这些寄存器是ICC_AP0R_EL1,其中n = 0-3:

  • 如果实现32个或更少的优先级,对ICC_AP0R_EL1的访问(其中n = 1-3)是UNDEFINED。

  • 如果实现超过32个且少于65个优先级,对ICC_AP0R_EL1的访问(其中n = 2-3)是undefined。

对于Group 1中断,这些寄存器是ICC_AP1R_EL1,其中n= 0-3:

  • 如果实现32个或更少的优先级,对ICC_AP1R_EL1的访问(其中n = 1-3)是undefined。

  • 如果实现超过32个且少于65个优先级,对ICC_AP1R_EL1的访问(其中n = 2-3)是undefined。

ICC_AP0R_EL1、Secure ICC_AP1R_EL1和Non-secure ICC_AP1R_EL1的内容是IMPLEMENTATION DEFINED。但是,值0x00000000必须与没有优先级活跃一致。

向这些寄存器写入最后读取值或0x00000000以外的任何值都可能导致:

  • 原本会抢占执行的中断不抢占执行。

  • 原本不会抢占执行的中断抢占执行。

对Non-secure ICC_AP1R_EL1的Non-secure写入无法阻止正确的优先级处理,无法阻止比Non-secure优先级范围中更高优先级的中断转发。

按照除以下顺序外的任何顺序写入这些寄存器都可能导致UNPREDICTABLE行为:

  1. ICC_AP0R_EL1。

  2. Secure ICC_AP1R_EL1。

  3. Non-secure ICC_AP1R_EL1。

注意 在每次写入ICC_AP0R_EL1、Secure ICC_AP1R_EL1和Non-secure ICC_AP1R_EL1之间不需要ISB。

表4-12显示了ICC_AP0R_EL1的实现。

表4-12 Group 0 Active Priorities Register实现

最小值:最大数量:
Secure ICC_BPR0_EL1Non-secure ICC_BPR1_EL1 优先级 抢占 级别ICC_AP0Rn实现
34416ICC_AP0R_EL1[15:0],其中n = 0
23532ICC_AP0R_EL1[31:0],其中n = 0
12664ICC_AP0R_EL1,其中n = 0-1
017128ICC_AP0R_EL1,其中n = 0-3

表4-13显示了ICC_AP1R_EL1的实现。

表4-13 Group 1 Active Priorities Register实现

最小值:最大数量:
Secure ICC_BPR0_EL1Non-secure ICC_BPR1_EL1 优先级 抢占 级别ICC_AP1Rn实现
34416ICC_AP1R_EL1[15:0],其中n = 0
23532ICC_AP1R_EL1[31:0],其中n = 0
12664ICC_AP1R_EL1,其中n = 0-1
017128ICC_AP1R_EL1,其中n = 0-3

4.8.4 抢占

CPU interface支持在活跃中断完成之前向目标PE发送更高优先级挂起中断的信号。挂起中断仅在以下两个条件都满足时才发送信号:

  • 其优先级高于该CPU interface的优先级掩码。参见_优先级掩码_。

  • 其组优先级高于CPU interface上的运行优先级。参见_优先级分组_获取更多信息。

抢占在PE接受新中断时发生,并开始处理新中断而不是先前活跃的中断或当前运行的进程。当这发生时,初始活跃中断被称为_被抢占_。

注意 Process State PSTATE中I或F位的值,以及Exception level和软件硬件中的中断路由控制,确定PE是否通过接受中断来响应发送信号的中断。有关更多信息,参见_Arm[®]架构参考手册,Armv8,针对Armv8-A架构配置文件_。

有关启用中断的更多信息,参见_启用中断分发_。

抢占级别控制

ICC_BPR0_EL1确定Group 0中断是否向PE发送信号以进行可能的抢占。此外:

  • 当ICC_CTLR_EL3.CBPR_EL1NS == 1时,ICC_BPR0_EL1也确定Non-secure Group 1中断是否向PE发送信号以进行可能的抢占。

  • 当ICC_CTLR_EL3.CBPR_EL1S == 1时,ICC_BPR0_EL1也确定Secure Group 1中断是否向PE发送信号以进行可能的抢占。

ICC_BPR1_EL1确定Group 1中断是否向PE发送信号以进行可能的抢占。此寄存器的Non-secure副本用于Non-secure Group 1中断。Secure副本用于Secure Group 1中断。

当ICC_CTLR_EL3.CBPR_EL1NS设置为1时:

  • EL3可以写入ICC_BPR1_EL1(NS)。当EL3使用AArch64状态时,从EL3对ICC_BPR1_EL1(NS)的访问不受ICC_CTLR_EL3.CBPR_EL1NS影响。

    • 当EL3使用AArch32状态时,从Monitor模式对ICC_BPR1_EL1(NS)的访问不受ICC_CTLR_EL3.CBPR_EL1NS影响。
  • 在EL1或EL2对ICC_BPR1_EL1的Non-secure写入被忽略。

  • 在EL1或EL2对ICC_BPR1_EL1的Non-secure读取返回ICC_BPR0_EL1 +1的值,在7处饱和。

当ICC_CTLR_EL3.CBPR_EL1S设置为1时:

  • ICC_BPR1_EL1的Secure读取返回ICC_BPR0_EL1的值。

  • ICC_BPR1_EL1的Secure写入更新ICC_BPR0_EL1。

4.8.5 优先级掩码

CPU interface的_Priority Mask Register_ ICC_PMR_EL1为目标PE定义优先级阈值。GIC仅向目标PE发送具有高于此优先级阈值的优先级的挂起中断信号。零值(寄存器重置值)掩码所有中断向关联PE发送信号。GIC在将挂起中断的优先级与优先级阈值比较时不使用优先级分组。

GIC始终掩码具有最低支持优先级的中断。此优先级有时称为空闲优先级。

注意 向ICC_PMR_EL1写入0xFF总是将其设置为最低支持优先级。表4-7显示了最低支持优先级如何随实现的优先级位数变化。

如果GIC提供两个Security状态的支持,如果bit[7] == 0,ICC_PMR_EL1对Non-secure访问是RAZ/WI。在正常操作期间,在Non-secure状态执行的软件在用这样的值编程时不访问ICC_PMR_EL1。

有关与不同GIC配置相关的信息,参见_对Secure中断优先级寄存器字段的Non-secure访问_。

4.8.6 中断优先级的软件访问

本节描述中断优先级的Secure和Non-secure读取,以及它们之间的关系。它还描述对优先级值字段的写入。

注意 本节适用于任何支持两个Security状态的GIC实现。

当PE读取Non-secure Group 1中断的优先级值时,GIC返回该值的Secure或Non-secure读取,取决于访问是Secure还是Non-secure。

GIC实现最少32个和最多256个优先级。这意味着它实现了适当GICR_IPRIORITYR和GICD_IPRIORITYR寄存器中8位优先级值字段的5-8位。所有实现的优先级位都可以通过Secure访问访问,优先级字段的未实现低位是RAZ/WI。图4-5显示了中断优先级值字段的Secure读取。存储在Distributor中的优先级值等效于Secure读取。

7 6 5 47 6 5 47 6 5 47 6 5 43 2 1 03 2 1 03 2 1 03 2 1 0
HGFEDCBA

图4-5 任何中断优先级字段的Secure读取

在此视图中:

  • 位H-D是GIC必须实现的位,对应32个优先级。

  • 位C-A是GIC可能实现的位。如果未实现,它们是RAZ/WI。

  • GIC必须实现位H-A以提供最大256个优先级。

对于Non-secure访问,GIC支持它为Secure访问支持的一半优先级,这意味着最少16个优先级。图4-6显示了Non-secure Group 1中断的优先级值字段的Non-secure视图。

7 6 5 47 6 5 47 6 5 47 6 5 43 2 1 03 2 1 03 2 1 03 2 1 0
GFEDCBA0

图4-6 Non-secure Group 1中断优先级字段的Non-secure读取

在此读取中:

  • 位G-D是GIC必须实现的位,对应16个优先级。

  • 位C-A是GIC可能实现的位,如果未实现则是RAZ/WI。

  • GIC必须实现位G-A以提供最大128个优先级。

  • 位[0]是RAZ/WI。

优先级值的Non-secure读取不显示值在Distributor的寄存器中如何存储。对于Non-secure Group 1中断优先级字段的Non-secure写入,在存储值之前:

  • 值右移一位。

  • 值的位[7]设置为1。

此转换意味着Non-secure Group 1中断的优先级值在优先级范围的下半部分。

中断优先级值的Secure读取返回存储在Distributor中的值。图4-7显示了由Non-secure访问设置优先级值字段或由Secure访问设置bit[7] == 1的优先级值的Non-secure Group 1中断的优先级值字段的Secure读取:

7 6 5 47 6 5 47 6 5 47 6 5 43 2 1 03 2 1 03 2 1 03 2 1 0
1GFEDCBA

图4-7 Non-secure Group 1中断优先级字段的Secure读取

Non-secure Group 1中断优先级值字段的Secure写入可以将位[7]设置为0。如果Secure写入将bit[7]设置为0:

  • Non-secure读取返回值GFEDCBA0。

  • Non-secure写入可以更改字段的值,但只能更改为字段的Secure读取具有位[7]设置为1的值。

注意

  • Non-secure访问的此行为仅适用于GICR_IPRIORITYR和GICD_IPRIORITYR中的优先级值字段,适当时:

    • 如果ICC_PMR_EL1中的Priority字段保存位[7] == 0的值,则该字段对Non-secure访问是RAZ/WI。

    • 如果ICC_RPR_EL1中的Priority字段保存位[7] == 0的值,则该字段对Non-secure读取是RAZ。

  • Arm不建议以这种方式为Non-secure Group 1中断将bit[7]设置为0,因为它将中断放在错误的优先级范围一半中以供non-secure代码维护。

图4-8显示了Non-secure Group 1中断优先级值字段读取之间的关系。

图片文本

7 6 5 4 3 2 1 0
Secure access H G F E D C B A Matches Secure view
7 6 5 4 3 2 1 0
Non-secure access
G F E D C B A 0 Translation of Secure view
7 6 5 4 3 2 1 0
Secure access
H G F E D C B A Matches Secure view

**图4-8 中断优先级字段的Secure和Non-secure读取之间的关系**

图4-9显示了来自Secure和Non-secure访问的中断优先级的软件读取如何与Distributor中保存的优先级值,以及Secure和Non-secure访问可见的中断值相关。图4-9适用于实现最大优先级值范围的GIC。

图片文本

Software view from Priority values in Software view from
Non-secure accesses Distributor Secure accesses
Highest 0x00 0x00 0x00
priority
Priority range for
Group 0 and Secure
Group 1 interrupts [ b]
Increasing 0x7F Increasing
priority [a] 0x80 priority
Priority range for
Non-secure Group 1
interrupts [ b]
Lowest
0xFE
priority 0xFF 0xFF
a. 在Non-secure访问的软件视图中,所有优先级值都是偶数(bit [0] == 0)。
b. Arm建议的范围。

**图4-9 Group 1和Group 0中断优先级的软件读取**

表4-14显示了GIC实现的优先级值位数如何影响Non-secure Group 1中断优先级的Secure和Non-secure读取。

注意 在Non-secure状态执行的软件无法看到Group 0中断或(如果适用)Secure Group 1中断的优先级设置。

表4-14 不实现某些优先级字段位的影响,两个Security状态

| 由Secure读取看到的实现优先级位 [7:0] | Non-secure Group 1中断的可能优先级字段值 Secure读取 Non-secure读取 | |—|— 0xFF-0x00(255-0),所有值 0xFE-0x00(254-0),仅偶数值 | | [7:1] | 0xFE-0x00(254-0),仅偶数值 0xFC-0x00(252-0),步长为4 | | [7:2] | 0xFC-0x00(252-0),步长为4 0xF8-0x00(248-0),步长为8 | | [7:3] | 0xF8-0x00(248-0),步长为8 0xF0-0x00(240-0),步长为16 |

此优先级值表示模型确保编写为与此GIC架构实现一起操作的软件按预期功能,无论GIC是否提供两个Security状态的支持。但是,程序员必须确保软件为Group 0和Group 1中断分配适当的优先级。

注意 为了控制优先级值,Arm强烈建议:

  • 对于Group 0中断,软件将优先级值字段的bit[7]设置为0。
  • 如果使用Secure写入设置Non-secure Group 1中断的优先级,软件将优先级值字段的bit[7]设置为1。

这确保所有Group 0和(如果适用)Secure Group 1中断具有比所有Non-secure Group 1中断更高的优先级。但是,系统可能有无法用此方案满足的要求。

表4-15显示了确保以下的示例优先级分配方案:

  • 一些Group 0中断具有比任何其他中断更高的优先级。

  • 一些Secure Group 1中断具有比任何Non-secure Group 1中断更高的优先级。

表4-15 示例优先级分配

中断安全配置GICR_IPRIORITYR[7:6]
Group 00b00
Secure Group 10b01
Non-secure Group 10b10 0b11
  • 软件可能不知道GIC支持两个Security状态,因此可能不知道它是否对GIC寄存器进行Secure或Non-secure访问。但是,对于任何实现的中断,软件可以向相应的GICR_IPRIORITYR优先级值字段写入0xFF,然后读回存储在字段中的值以确定支持的中断优先级范围。Arm建议在以这种方式检查优先级范围之前:

    • 对于外设中断,软件首先禁用中断。
  • 对于SGI,软件首先检查中断是非活跃的。

4.8.7 更改启用的PPI、SGI和SPI的优先级

如果软件在中断挂起时写入启用中断的GICD_IPRIORITYR、GICD_IPRIORITYRE、GICR_IPRIORITYR和GICR_IPRIORITYRE寄存器,GIC使用旧值还是新值是IMPLEMENTATION DEFINED。GIC确保没有中断被处理超过一次,没有中断丢失。写入的影响必须在有限时间内可见。