Physical Interrupt Handling and Prioritization

本文详细介绍了GIC(GenericInterruptController)中断处理的生命周期,包括中断的产生、分组、优先级管理、激活、去激活等步骤。GIC为每个中断维护状态机,处理物理和逻辑中断,如私有、共享和本地特定外围中断。中断优先级分为多个组,并通过中断优先级寄存器进行配置。此外,文章还讨论了中断的抢占和NMI的优先级特性。
摘要由CSDN通过智能技术生成

Interrupt lifecycle

GIC中断处理基于GIC中断生命周期。中断生命周期为描述中断处理过程的详细步骤提供了基础。GIC还维护一个状态机,用于控制生命周期期间的中断状态转换。
下图显示了物理中断的GIC中断生命周期。
在这里插入图片描述

  • Generate interrupt-中断由外围设备或软件产生。
  • Distribute-IRI执行中断分组、中断优先级排序,并控制向CPU interfaces转发中断。
  • Deliver-物理CPU接口将中断传送到相应的PE。
  • Activate-当PE上运行的软件acknowledges 中断时,GIC将最高活动优先级设置为active 中断的优先级,对于SPI、SGI和PPI,中断变为active。
  • Priority drop-当最高优先级中断已处理,在PE上运行的软件向GIC发出信号,丢弃运行优先级。然后,运行优先级恢复中断被acknowledged 之前的值。这是中断处理程序结束的点。中断的结束为执行中断的deactivation。
  • Deactivation-Deactivation将清除中断的active状态。从而允许pending中断执行。LPI不需要停用。Deactivation可以配置为与优先级下降同时发生。可以配置为中断deactivation操作之后发生。

Physical CPU interface

CPU interface为连接到GIC的PE提供接口。每个CPU interface都连接到
单个PE。
CPU interface:
接收由IRI确定优先级排序的pending中断。
确定该中断是否是CPU interface中启用的组的成员
具有足够的优先级以向PE发送信号。

其中PE可以:
通过读取ICC_HPPIR0_EL1或ICC_HPPIR1_EL1,获得其最高优先级pending中断的INTID。
读取ICC_RPR_EL1获取CPU interface的运行优先级。

当acknowledge LPI时,中断的挂起状态将在Redistributor中更改为未not pending。Redistributor不会为LPI保持active状态。

当PE acknowledges CPU acknowledges上的SGI、PPI或SPI时,如果出现以下情况,IRI会将中断状态更改为active状态:

  • 对于edge-triggered中断,并且自中断被acknowledge,还没有检测到另一个边缘。
  • 对于level-sensitive中断,中断被acknowledge,该级别已被取消断言。

当PE acknowledge CPU interface上的SGI、PPI或SPI时,如果出现以下情况,IRI会将中断状态更改为active和pending:

  • 对于edge-triggered中断,中断被acknowledge,后检测到另一个边缘。
  • 对于level-sensitive中断,中断被acknowledge,该级别未被解除断言。

当PE在CPU interface上确认SGI、PPI或SPI时,CPU interface可以向PE发出另一个中断信号,以抢占PE上活动的中断。如果没有具有足够优先级的pending中断,则接口将中断请求信号取消向PE发出。

Activation
中断处理程序读取Group 0中断的ICC_IAR0_EL1,Group 1中断的ICC-IAR1_EL1,在GICv3.3中,读取相应CPU interface中NMI中断的ICC_NMIAR1-EL1,以确认中断。同时获取INTID:

  • 对中断确认的正常响应,果该中断的优先级足以向PE发出信号,最高优先级pending中断的INTID。
  • 在某些情况下,INTID表示一个特殊中断号。

ICC_IAR0_EL1、ICC_IAR1_EL1或ICC_NMIR1_EL1的读取是否返回有效的INTID取决于:

  1. 访问三个寄存器中的哪一个。
  2. PE的安全状态。
  3. 是否有足够优先级的pending中断要发送给PE?
    –最高优先级pending 中断是Secure Group 1或Non-secure Group 1中断。
    –为该中断组启用中断信令。
  4. PE正在执行的异常级别。
  5. 中断是否具有不可屏蔽属性。
    所有中断在acknowledge后都会修改Active Priorities Registers。

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

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

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

Priority drop
在中断被确认后,对于Group 0中断,对ICC_EOIR0_EL1的有效写入,或者对于Group1中断,对ICC _EOIR1_EL1的无效写入,会导致优先级下降。

对于每个已acknowledged的中断,甚至对于没有active状态的LPI,都需要对ICC_EOIR0_EL1或ICC_EOIR1_EL1进行有效写入以执行priority drop。priority drop必须由activate中断的同一PE执行。

对于每个CPU interface,GIC架构要求ICC_EOIR0_EL1和ICC_EOIR1_EL1的有效写入顺序与ICC_IAR0_EL1和IC_IAR1_EL1的读取顺序完全相反,如图所示。
在这里插入图片描述在priority drop时,运行优先级从写入ICC_EOIR0_EL1或ICC_EOIR1_EL1时中断优先级降低到:

  • 没有写入ICC_EOIR0_EL1或ICC_EOIR1_EL1时候的highest-priority active中断的优先级。
  • 如果没有active中断,降低到idle priority。

GICD_CTLR.DS == 0:

  • 对ICC_EOIR0_EL1的写入对Group 0中断执行priority drop。
  • 如果PE在Non-secure state或EL3下运行,则对ICC_EOIR1_EL1的写入将对Non-secure Group 1中断执行priority drop。
  • 在Secure state操作时,对ICC_EOIR1_EL1的写入对Secure Group 1中断执行priority drop。

GICD_CTLR.DS == 1:
对ICC_EOIR0_EL1的写入对Group 0中断执行priority drop。
对ICC_EOIR1_EL1的写入执行Group 1中断的priority drop。

Deactivation
PPI、SGI和SPI在IRI中有state状态,必须deactivate。
activate中断的PE必须deactivate相应的SGI和PPI。SPIs可以由不同的PE 去deactivate。
需要中断deactivate才能更改中断状态:

  • 从活active and pending到pending。
  • 从active变为inactive。

根据异常级别和安全状态,相应CPU Interface控制寄存器中的ICC_CTLR_EL1.EOImode和ICC_CTLR.EL3.EOImode_EL3确定priority
drop和中断deactivation是同时发生还是单独发生:

  • 当CPU interface中的ICC_CTLR_EL1.EOImode或ICC_CTLR.EL3.EOImode_EL3为0,且PE写入ICC_EOIR0_EL1或ICC_EOIR1_EL1时,priority drop和中断deactivation同时发生。在这种情况下,不需要写入ICC_DIR_EL1。
  • 当CPU interface中的ICC_CTLR_EL1.EOImode或ICC_CTLR.EL3.EOImode_EL3为1,且PE写入ICC_EOIR0_EL1或ICC_EOIR1_EL1时,priority drop和中断deactivation被分离。在这种情况下:
  • 当PE写入ICC_EOIR0_EL1或ICC_EOIR1_EL1时,发生priority drop。
  • 稍后当PE写入ICC_DIR_EL1时,会发生中断deactivation。对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_EL31但中断在分发服务器中未激活时,必须忽略对ICC_DIR_EL1的写入。如果支持,实现可能会生成系统错误。
在这里插入图片描述安全状态对ICC_DIR_EL1写入的影响:
写入ICC_DIR_EL1的效果取决于GIC是否支持一个或两个安全状态:
如果GICD_CTLR.DS
0,则有效:

  • 对ICC_DIR_EL1的安全写入将停用指定的中断,无论该中断是Group 0中断还是Group 1中断。
  • 只有当指定中断是Non-secure Group 1中断时,对ICC_DIR_EL1的非安全写入才会deactivate该中断。

如果GICD_CTLR.DS==1,对ICC_DIR_EL1的有效写入将停用指定的中断,无论该中断是Group 0还是Group 1中断。
在这里插入图片描述

Interrupt handling state machine

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

  • Inactive.
  • Pending.
  • Active.
  • Active and pending.
    PPI、SGI和SPI可以具有active和pending状态。active和pending的中断永远不会向连接的PE发出信号。
    LPI具有pending状态,该状态保存在与Redistributor相关联的内存中。

下图显示中断处理状态机的实例以及可能的状态转换。
在这里插入图片描述
当Distributor的中断转发和CPU interface的中断信令被启用时,每个状态转换的条件如下:
Transition A1 or A2, add pending state
外围设备产生中断和软件产生中断时候,中断变为pending状态。

Transition B1 or B2, remove pending state
如果中断是一个级别敏感的中断,外设解除了中断时。或者软件改变了挂起状态时会解除pending状态。
对于LPI,它也发生在中断acknowledgment时。

Transition C, pending to active
PE对edge-triggered的SPI、SGI和PPI的中断acknowledgment时,会发生pending到active的转换。
对于SPI、SGI和PPI,当软件从ICC_IAR0_EL1或ICC_IAR1_EL1读取INTID值时,会发生pending到active的转换。

Transition D, pending to active and pending
PE对level-sensitive的SPI、SGI和PPI的中断确认时,会发生pending到active and pending的转换。

Transition E1 or E2, remove active state
当软件deactivate SPI、SGI和PPI的中断时,会发生解除active状态的转换。

Locality-specific Peripheral Interrupts

LPI是目标外围中断,这些中断被路由到关联层次结构中的特定PE。
在启用两个安全状态的系统中,LPI总是非Non-secure Group 1中断。LPI仅支持edge-triggered行为。

Private Peripheral Interrupts

PPI是针对单个特定PE的中断,不同PE可以使用相同的INTID来指示不同的事件。PPI可以是Group 0中断、Secure Group 1中断或Non-secure Group 1。它们可以支持edge-triggered或level-sensitive。

可选扩展PPI范围使用INTID 1056-1119。当GIC以传统模式运行时,此PPI范围不可用。GICR_TYPER.PPInum指示是否支持扩展PPI范围。

Software Generated Interrupts

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

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

  • PE通过写入ICC_SGI1R_EL1或ICC_ASGI1R_EL1生成Group 1 SGI
  • PE通过写入ICC_SGI0R_EL1生成Group0 SGI。
  • 路由信息作为位字段值提供给生成SGI的寄存器。SGI可以路由到:
    —targetlist指定的PE组。这可以包括原始PE
    —系统中的所有参与PE,不包括发起PE

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

Shared Peripheral Interrupts

SPI是外围中断,Distributor可以将其路由到可以处理中断的指定PE,或者路由到系统中已配置为接受此类中断的PE组之一的PE。SPI可以是Group 0或Group 1中断,它们可以支持edge-triggered或level-sensitive行为。
可选扩展SPI范围使用INTID 4096-5119。GICD_TYPER.ESPI指示是否支持扩展SPI范围。
SPI可以是基于有线或基于消息的中断。
对基于消息的SPIs的支持是可选的,可以通过GICD_TYPER.MBIS发现。基于消息的SPI可以是:

  • 通过写入GICD_SETSPI_NSR或GICD_SETSI_SR生成
  • 通过写入GICD_CLRSPI_NSR或GICD_CLR
    SPI_SR清除。

写入这些寄存器的效果取决于目标SPI是被配置为edge-triggered还是
level-sensitive中断:

  • 对于edge-triggered中断,写入GICD_SETSPI_NSR或GICD_SETSI_SR将中断设置为pending。当中断被激活或通过写入GICD_CLRSPI_NSR、GICD_CLRSPI_SR或GICD_ICPENDR清除时,中断不再挂起。
  • 对于level-sensitive中断,写入GICD_SETSPI_NSR或GICD_SETSI_SR会将中断设置为pending。它保持pending状态,直到通过对GICD_CLRSPI_NSR或GICD_CLRSPI_SR的写操作取消断言。如果中断在写入GICD_SETSPI_NSR或GICD_SETSI_SR断言的时间和写入GICD_CLRSPI_NSR或GICD_CLRSPI_SR停用的时间之间被激活,则中断变为active and pending。
  • 当存在pending中断时,将中断配置从level-sensitive更改为edge-triggered,或从edge-triggered更改为level-sensitive,会使中断处于未知状态。
    在这里插入图片描述

Interrupt grouping

GICv3使用中断分组作为一种机制,使中断处理与Armv8异常模型和安全模型相一致。
在具有两种安全状态的系统中,中断配置为以下之一:

  • Group 0物理中断: —Arm希望在EL3处处理这些中断。
  • Secure Group 1物理中断:—Arm希望在安全EL1或安全EL2处处理这些中断。
  • Non-secure Group 1物理中断:—Arm希望在非安全EL1或非安全EL2处处理这些中断。

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

  • Group 0
  • Group 1

在系统级,GICD_CTLR.DS指示GIC是否配置了一个或两个安全状态。

这些中断组被映射到Armv8 FIQ和IRQ异常。

GICD_IGROUPR和GICD_IGRPMODR为SPI配置中断组,GICD_IGROUPE和GICD-IGRPMODRE为扩展的SPI范围配置中断组。n大于零。

GICR_IGROUPR0和GICR_IGRPMODR0为SGI和PPI配置中断组,GICR_IGROUP<n>E和GICR-IGRPMODR<n>D为扩展PPI范围配置中断组。n大于零。

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

  • 对于Group 0中断,软件使用:
    —ICC_IAR0_EL1在中断确认时读取Group 0 INTID。
    —ICC_EOIR0_EL1写入Group 0中断完成。
    —ICC_BPR0_EL1配置Group 0优先级。当ICC_CTLR_EL1.CBPR==1时,此寄存器也用于Group 1优先级。
    —ICC_HPPIR0_EL1读取当前挂起的最高Group 0中断。
    —ICC_IGRPEN0_EL1在CPU接口上启用Group 0中断。
  • 对于Group 1中断,软件使用:
    —ICC_IAR1_EL1在中断确认时读取Group 1 INTID。
    —ICC_EOIR1_EL1写入Group 1中断完成。
    —ICC_BPR1_EL1为配置当前安全状态的Group 1优先级。
    —ICC_HPPIR1_EL1读取当前pending的最高优先级Group 1中断。
    —ICC_IGRPEN1_EL1为中断的目标安全状态启用Group 1中断。

在具有两种安全状态的系统中,Group 0中断总是安全的。

Interrupt grouping and security

Arm体系结构提供两种安全状态,每种状态都有一个相关的物理内存地址空间:
安全状态。
非安全状态。

用户和特权代码的软件层次结构可以在任一状态下执行,而在非安全状态下执行的软件只能通过对安全监视器的系统调用访问安全状态。GIC体系结构支持路由和处理与两种安全状态相关的中断。

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

  • 寄存器访问。
  • 支持的中断组。

当GICD_CTLR.DS==0时:

  • GIC支持两种安全状态,安全状态和非安全状态。
  • GIC支持三个中断组:
    —Group 0.
    —Secure Group 1.
    —Non-secure Group 1.
  • 安全状态和GICR_NSACR都决定是否可以生成SGI。
  • 在以下过程中检查安全状态:
    —中断的配置。
    —中断的Acknowledgment。
    —Priority drop。
    —Deactivation。
    如果出现以下情况,CPU interface将安全Group 1中断视为Group0:
    —PE不执行EL3。
    —ICC_SRE_EL1(S).SRE==0。

当GICD_CTLR.DS==1时:

  • GIC仅支持单个安全状态。这可以是安全状态或非安全状态。
  • GIC支持两个中断组:
    —Group 0.
    —Group 1.
  • 无论GICR_NSACR中的设置如何,都可以生成SGI。
  • 在以下期间不检查安全状态:
    —中断的配置。
    —中断的Acknowledgment。
    —Priority drop。
    —Deactivation。

在多处理器系统中,系统中的一个或多个PE可能支持对仅在安全状态下可用的资源的访问,或对仅在非安全状态下可使用的资源的存取。
以下软件配置是不对的:

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

每个中断组的优先级分组有一个专用寄存器,ICC_BPR0_EL1用于组0中断,ICC_BPR1_EL1用于组1中断。但是,可以使用以下方法为两个组配置通用二进制点寄存器:

  • ICC_CTLR_EL1.CBPR。
  • ICC_CTLR_EL3.CBPR_EL1NS和ICC_CTLR.EL3.CBPR_EL1S,用于非安全组1和安全组1中断的独立公共二进制点寄存器配置。

Interrupt assignment to IRQ and FIQ signals

有最高优先级的pending中断并且具有足够的优先级的Group 0物理中断,它总是作为FIQ发出信号。
有最高优先级pending中断且具有足够优先级的Group 1物理中断 ,如果以下任一条件为真,则将其作为FIQ发出信号,否则将其作为IRQ发出信号:

  • 这是另一个安全状态的中断,即PE未执行的安全状态。
  • PE在EL3执行。
    在这里插入图片描述在这里插入图片描述在这里插入图片描述
    IRQ和FIQ的断言和取消断言受当前异常级别和安全状态的影响
    作为作为获取异常或从异常返回的结果而发生的上下文同步的一部分,CPU interface确保IRQ和FIQ对于PE正在进入的异常级别和安全状态都被适当地断言或取消断言。

Interrupt superpriority

当实现FEAT_NMI时,Arm架构将NMI属性称为超优先级。
当NMI被信号通知给PE时,如果它被信号通知为IRQ或虚拟IRQ,则它被呈现为具有超优先级。在所有其他情况下,GIC不会向PE提供具有超优先级的任何中断。
NMI仅在呈现给其所属的安全状态和异常级别时才显示为具有超优先级。

Interrupt routing and System register access

在AArch64状态下执行时,到异常级别的中断路由由以下位控制:

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

该路由还控制EL1 CPU interface系统寄存器可访问的异常级别,该寄存器控制和acknowledge 中断。。这适用于:

  • ICC_IAR0_EL1、ICC_EOIR0_EL1、IC_HPPIR0_EL1和ICC_BPR0_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_sg0r_EL1、ICC_sg1r_EL1,MR_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。

如果Distributor持两种安全状态,PE可能不会实现EL2或EL3。

Enabling the distribution of interrupts

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

  • GICD_CTLR.EnableGrp1S.
  • GICD_CTLR.EnableGrp1NS.
  • GICD_CTLR.EnableGrp0.

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

  • ICC_IGRPEN0_EL1.为Group 0中断启用。
  • ICC_IGRPEN1_EL1.启用Group 1中断。
  • ICC_IGRPEN1_EL3.{EnableGrp1S,EnableGrp1NS}。
    通过写入GICR_CTLR.EnableLPI来启用物理LPI。

Enabling individual interrupts

PPIs
当为中断的安全状态启用关联路由时,可以通过写入GICR_ISENABLER0和GICR_ICENABLER0来启用和禁用PPI。也可以通过写入GICD_ISENABLERn和GICD_ICENABLERn来启用和禁用单个PPI。如果支持并配置了物理中断的传统操作,则PPI的n=0。
SPIs
通过写入GICD_ISENABLERn和GICD_ICENABLERn,可以启用和禁用单个SPI。SPIs的n>0。
SGIs
启用关联路由时,可以通过写入GICR_ISENABLER0和GICR_ICENABLER0来启用和禁用SGI。也可以通过写入GICD_ISENABLERn和GICD_ICENABLERn来启用和禁用单个SGI。如果支持并配置了物理中断的传统操作,则SGI的n=0。
LPIs
通过设置LPI配置表中编程的启用位,可以启用各个LPI。有关使用LPI配置表启用LPI的更多信息。

Interaction of group and individual interrupt enables

GICD_*和GICR_*寄存器为每个目标PE确定最高优先级pending中断。该中断被提供给PE的CPU interface ,以评估是否要向PE发送信号。中断的启用对该评估的影响如下:

  • 在GICD_*或GICR_*寄存器中单独禁用的pending中断 ,在确定最高优先级pending中断时不被考虑,因此不能用信号通知PE。
  • 在GICD_*或GICR_*寄存器中单独启用的pending中断,但是在GICD_CTLR中禁用的组的成员,在确定最高优先级挂起中断时不被考虑,因此不能用信号通知PE。
  • 在GICD_*寄存器中单独启用并且是在GICD_CTLR中启用的组的成员的未决N中1的中断,但是是在ICC_IGRPEN0_EL1、ICC_IGRPEN1_EL1或ICC_IGRPEN1_EL3中为PE禁用的组的成员,不能为该PE选择。在确定最高优先级未决中断时不考虑这种中断,因此不能用信号通知PE。
  • 在LPI配置表中单独启用LPI。

Effect of disabling interrupts

通过写入适当的GICD_ICENABLER<n>或GICR_ICENABLER0,或通过写入LPI配置表来禁用中断,不会阻止该中断改变状态,例如变为pending。当GICR_CTLR.EnableLPI==0时,LPI从不设置为挂起。

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

当软件从1到0写入ICC_IGRPEN0_EL1.Enable、ICC_IGRPEN0_EL1、ICC_IGRPEN1.Enable或ICC_IGRPN1_EL3.Enable时,如果CPU interface上挂起中断,则CPU interface必须释放中断,以允许Distributor将中断转发到其他PE。

Interrupt prioritization

本节介绍了GIC体系结构中的中断优先级。优先级描述:

  1. 中断优先级的配置和控制。
  2. 挂起中断的执行顺序。
  3. 确定中断何时对目标PE可见,包括:
  • 中断优先级屏蔽。
  • 优先级分组。
  • 主动中断的抢占。

软件通过为每个中断源分配优先级值来配置GIC中的中断优先级。优先级值是一个8位无符号二进制数。支持两个安全状态的GIC实现必须实现最低32级和最高256级的物理优先级。仅支持单个安全状态的GIC实现必须实现最低16级和最高256级的物理优先级。
如果GIC实现的优先级低于256,则优先级字段的低阶位为RAZ/WI。
下表给出了优先级字段比特与实现所支持的优先级等级的数量之间的关系。
**加粗样式
**
在GIC优先级排序方案中,数字越低,优先级越高。这意味着分配的优先级值越低,中断的优先级就越高。优先级字段值0总是表示可能的最高中断优先级,而最低优先级值取决于实现的优先级的数量。

GICD_IPRIORITYR寄存器保存每个受支持SPI的优先级值。一个实现可能会为特定目的保留SPI,并为该中断分配固定的优先级,这意味着该中断的优先级值是只读的。对于其他SPI,GICD_IPRIORITYR寄存器可以由软件编写,以设置中断优先级。

在多处理器实现中,GICR_IPRIORITYR寄存器为每个目标PE独立定义每个SGI和PPI INTID的中断优先级。CPU interface串行化这些SGI的顺序是特定于实现的。

内存中的LPI配置表和LPI挂起表存储LPI优先级信息和pending状态。

GIC安全模型提供对中断优先级设置的安全和非安全访问。非安全访问只能在支持的优先级值的较低优先级的一半中配置中断。因此,如果GIC实现32个优先级值,那么非安全访问只能看到16个优先级值。

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

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

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

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

GICv3保证最高优先级、未屏蔽、启用的中断将在有限时间内传递到目标PE。但不能保证高优先级中断总是在低优先级中断之前进行,尽管通常情况下都是这样。

NMI prioritization

GICv3.3引入了SPI、PPI和SGI的不可屏蔽属性。
当GICD_CTLR.DS==0时,NMI具有以下优先级:

  1. 安全NMI的优先级高于优先级为0x00的非NMI。
  2. 非安全NMI具有以下优先级:
  • 优先级高于优先级为0x80的非NMI。
  • 优先级低于优先级为0x7F的非NMI。

当GICD_CTLR.DS==1时,NMI的优先级高于优先级为0x00的非NMI。
GICv3.3将新的优先级插入到现有的GIC优先级空间中。
在这里插入图片描述对于配置为不可屏蔽的INTID,GIC[D|R]_IPRIORITYR{E}。Priority_x为RES 0。
属于给定安全状态的所有NMI都具有相同的优先级。GIC在具有相同优先级的中断之间不提供排序保证。

Non-secure accesses to register fields for Secure interrupt priorities

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

  • Group 0中断为安全中断。
  • Secure Group 1 中断。
  • Non-secure Group 1中断。
    为了支持Armv8安全模型,与安全中断相关的寄存器字段是用于非安全访问的RAZ/WI。此外,以下规则适用:
    For Non-secure access to a priority field in GICx_IPRIORITYR:
    如果优先级字段对应于中断的软件访问中的 Non-secure Group 1中断
  • 对于SPI,优先级字段由GICD_IPRIORITYR-n或 GICD_IPRIORITYR-n E。
  • 对于PPI和SGI,优先级字段由GICR_IPRIORITYR或 GICR_IPRIORITYR-n E。

For Non-secure access to ICC_PMR_EL1 and ICC_RPR_EL1 when SCR_EL3.FIQ == 1:
如果当前优先级掩码值在0x00-0x7F的范围内:

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

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

  • 读取访问返回当前值的非安全读取。
  • 基于对的非安全读取,对ICC_PMR_EL1的写访问成功 写入寄存器的优先级掩码值。

这意味着非安全写入无法设置0x00-0x7F范围内的优先级掩码值。

For Non-secure access to ICC_PMR_EL1 and ICC_RPR_EL1 when SCR_EL3.FIQ == 0:
提供了伪代码,用于描述对支持两种安全状态的GIC中以下系统寄存器的访问:

  • ICC_PMR_EL1。
  • ICC_RPR_EL1。

Priority grouping

优先级分组使用以下Binary Point Registers:

  • ICC_BPR0_EL1用于Group 0中断。此寄存器在所有GIC实现中都可用。
  • 用于Non-secure Group 1中断的ICC_BPR1_EL1的非安全副本。如果一个实现支持两种安全状态,则该寄存器有一个安全副本和一个非安全副本。如果一个实现只支持一个安全状态,则该寄存器只有一个副本。
  • 用于Secure Group 1中断的ICC_BPR1_EL1的安全副本。此寄存器仅在支持两种安全状态的GIC实现中可用。

Binary Point Registers将优先级值分为两个字段,即组优先级(group priority)和子优先级(subpriority)。当确定抢占时,具有相同组优先级的所有中断都被认为具有相同的优先级,而不考虑次优先级。

当多个pending中断具有相同的组优先级时,GIC使用子优先级字段来解析组内的优先级。

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 Group 1中断的优先级分组。
  • 当ICC_CTLR_EL3.CBPR_EL1NS清除为0时,ICC_BPR1_EL1的非安全副本决定Non-secure Group 1中断的优先级分组。

下图显示了Secure ICC_BPR1_EL1的中断优先级字段的拆分。
在这里插入图片描述在这里插入图片描述下图显示了非安全ICC_BPR1_EL1的中断优先级字段的拆分。
在这里插入图片描述下图显示了ICC_BPR0_EL1的中断优先级字段的拆分。
在这里插入图片描述支持的binary point value取决于优先级比特的执行定义数量
在这里插入图片描述所实现的优先级比特的数量由ICC_CTLR_EL1.PRIBits和ICC_CTLR_EL3.PRIBits指示。

在支持两种安全状态的GIC中,当:
ICC_CTLR_EL3.CBPR_EL1S1:
-在安全EL1写入ICC_BPR1_EL1修改ICC_BPR0_EL1。
-在安全EL1处从ICC_BPR1_EL1读取将返回ICC_BPR0_EL1的值。
ICC_CTLR_EL3.CBPR_EL1NS
1:
-忽略对ICC_BPR1_EL1的非安全写入。
-从ICC_BPR1_EL1进行的非安全读取返回ICC_BPR0_EL1+1到0b111。

System register access to the Active Priorities registers

Physical Group0和Group1中断访问不同的Active Priorities寄存器,具体取决于中断组。
对于Group 0中断,这些寄存器为ICC_AP0R_EL1,其中n=0-3:

  • 如果实现了32个或更少的优先级,则对ICC_AP0R_EL1的访问(其中n=1-3)是未定义的。
  • 如果实现的优先级大于32且小于65,则对ICC_AP0R_EL1的访问(其中n=2-3)是未定义的。

对于Group1中断,这些寄存器为ICC_AP1R_EL1,其中n=0-3

  • 如果实现了32个或更少的优先级,则对ICC_AP1R_EL1的访问(其中n=1-3)是未定义的。
  • 如果实现的优先级大于32且小于65,则对ICC_AP1R_EL1的访问(其中n=2-3)为未定义。

ICC_AP0R_EL1、安全ICC_AP1R_EL1和非安全ICC_AP1 R1的内容是IMPLEMENTATION DEFINED。但是,值0x00000000必须与没有处于活动状态的优先级一致。
将除上次读取值或0x00000000以外的任何值写入这些寄存器可能会导致:

  • 原本会抢占执行而不是抢占执行的中断。
  • 否则不会抢占执行的中断将抢占执行。

对非安全ICC_AP1R_EL1的非安全写入不能阻止正确的优先级排序,也不能阻止转发优先级高于非安全优先级范围内的中断。以以下以外的任何顺序写入这些寄存器都可能导致不可预测的行为:

  • ICC_AP0R_EL1。
  • Secure ICC_AP1R_EL1。
  • Non-secure ICC_AP1R_EL1。
    在这里插入图片描述在这里插入图片描述在这里插入图片描述

Preemption

CPU interface支持在active中断完成之前向目标PE发送更高优先级的未决中断的信令。只有当以下情况之一为真时,才会发出挂起中断的信号:
最高优先级的挂起中断不是NMI,以下两种情况均为真:

  • 它的优先级高于该CPU接口的优先级掩码。
  • 它的组优先级高于CPU接口上的运行优先级。
    最高优先级的挂起中断是NMI,以下情况之一为真:
  • 优先级较高的pending中断的组优先级高于正在运行的优先级。
  • 优先级较高的pending中断的组优先级等于运行优先级,并且ICC_AP1R0_EL1.NMI对于拥有中断的安全状态为0。

抢占发生在PE接收新中断时,并开始处理新中断,而不是以前活动的中断或当前运行的进程。当这种情况发生时,称initial active 中断已被抢占。
进程状态中的I或F位的值,PSTATE,以及软件和硬件中的异常级别和中断路由控制,确定PE是否通过接受中断来响应信号中断。
Preemption level control
ICC_BPR0_EL1确定是否用信号向PE发送组0中断以进行可能的抢占。此外:

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

ICC_BPR1_EL1确定是否用信号向PE发送Group 1中断以进行可能的抢占。此寄存器的Non-secure副本用于Non-secure Group 1中断。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状态时,在监视器模式下对ICC_BPR1_EL1的访问不受到ICC_CTLR_EL3.CBPR _EL1NS影响。
  • 忽略在EL1或EL2对ICC_BPR1_EL1的非安全写入。
  • 在EL1或EL2处对ICC_BPR1_EL1的非安全读取返回ICC_BPR0_EL1+1的值,在7处饱和。

当ICC_CTLR_EL3.CBPR_EL1S设置为1时:

  • 对ICC_BPR1_EL1的安全读取返回ICC_BPR0_EL1的值。
  • 对ICC_BPR1_EL1的安全写入更新ICC_BPR0_EL1。

Priority masking

CPU interface的优先级掩码寄存器ICC_PMR_EL1定义了目标PE的优先级阈值。当以下任一情况为真时,最高挂起中断由ICC_PMR_EL1掩码:
1.中断不是NMI,并且中断优先级等于或低于ICC_PMR_EL1.priority。
2.GICD_CTLR.DS为0,且以下任意一项为真:

  • 中断为非安全NMI,ICC_PMR_EL1。优先级设置为安全范围内的优先级。
  • 中断为非安全NMI,当前安全状态为安全或根,并且
    ICC_PMR_EL1.Priority被设置为实现的最高非安全优先级。

当GICD_CTLR.DS为0时,ICC_PMR_EL1永远不会屏蔽安全NMI。当GICD_CTLR.DS为1时,NMI从不被ICC_PMR_EL1屏蔽。
GIC仅向目标PE发送优先级高于此优先级阈值的挂起中断信号。寄存器重置值为零会屏蔽所有中断,使其无法向相关PE发送信号。在将挂起中断的优先级与优先级阈值进行比较时,GIC不使用优先级分组。
GIC总是屏蔽具有最低支持优先级的中断。此优先级有时被称为
idle priority.

如果GIC提供对两种安全状态的支持,则如果位[7]==0,则ICC_PMR_EL1为非安全访问的RAZ/WI。在正常操作期间,当使用这样的值编程时,在非安全状态下执行的软件不访问ICC_PMR_EL1。

Software accesses of interrupt priority

本节介绍中断优先级的安全读取和非安全读取,以及它们之间的关系。它还描述了对优先级值字段的写入。
当PE读取Non-secure Group 1中断的优先级值时,GIC返回该值的安全或非安全读取的值,具体取决于访问是安全还是非安全。

GIC实现最低32个优先级,最高256个优先级。这意味着它在适当的GICR_IPRIORITYRn和GICD_IPRIORITYRn register中实现8位优先级值字段的5-8位。所有实现的优先级比特都可以通过安全访问来访问,并且优先级字段的未实现的低阶比特是RAZ/WI。存储在Distributor中的优先级值相当于安全读取的值。下显示了中断的优先级值字段的安全读取。
在这里插入图片描述在此视图中:

  • 位H-D是GIC必须实现的位,对应于32个优先级。
  • 位C-A是GIC可能实现的位。如果未实施,则为RAZ/WI。
  • GIC必须实现位H-A,以提供最大256个优先级。

对于非安全访问,GIC支持其支持的安全访问优先级的一半,这意味着至少有16个优先级。下显示了非安全组1中断的优先级值字段的非安全视图。 在这里插入图片描述内容如下:

  • 比特G-D是GIC必须实现的比特,对应于16个优先级。
  • 位C-A是GIC可能实现的位,如果不实现,则为RAZ/WI。
  • GIC必须实现位G-A以提供最大128个优先级。
  • 位[0]为RAZ/WI。

优先级值的非安全读取不会显示该值是如何存储在分发服务器的寄存器中的。对于非安全写入非安全组1中断的优先级字段,在存储值之前:

  • 该值被右移一位。
  • 该值的位[7]设置为1

这种转换意味着非安全组1中断的优先级值在优先级的下半部分
范围。
对中断优先级值的安全读取将返回存储在Distributor中的值。下图显示了Non-secure Group 1中断的优先级值字段的安全读取,该中断的优先级值域由非安全访问设置,或具有由安全访问设置的位[7]==1的优先级值:
在这里插入图片描述对Non-secure Group 1中断的优先级值字段的安全写入可以将位[7]设置为0。如果安全写入将位[7]设置为0:

  • 非安全读取返回值GFEDCBA0。
  • 非安全写入可以更改字段的值,但只能更改为位[7]设置为1的值,用于字段的安全读取。

这种非安全访问行为仅适用于GICR_IPRIORITYRn和GICD_IPRIORITYRn中的优先级值字段,视情况而定:

  • 如果ICC_PMR_EL1中的优先级字段包含一个位[7]==0的值,则该字段为非安全访问的RAZ/WI。
  • 如果ICC_RPR_EL1中的优先级字段包含一个位[7]==0的值,则该字段为非安全读取的RAZ。
    Arm不建议以这种方式将Non-secure Group 1中断的位[7]设置为0,因为它将中断置于非安全代码维护优先级范围的错误一半。

下图显示了Non-secure Group 1中断的优先级值字段的读取之间的关系。
在这里插入图片描述下图显示了软件从安全和非安全访问读取中断优先级与Distributor中保存的优先级值以及安全和非安全访问可见的中断值之间的关系。下图适用于实现最大优先级值范围的GIC。
在这里插入图片描述下图显示了GIC实现的优先级值位数如何影响Non-secure Group 1中断优先级的安全和非安全读取。
在这里插入图片描述这种优先级值表示模型确保了为实现该GIC体系结构而编写的软件按预期运行,而不管GIC是否支持两种安全状态。然而,程序员必须确保软件为Group 0和Group 1中断分配适当的优先级。

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

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

这确保所有Group 0和Secure Group 中断(如果适用)的优先级高于所有Non-secure Group 1的中断。
下图显示了一个优先级分配方案示例,该方案确保:
某些Group0中断的优先级高于任何其他中断。
某些Secure Group 1中断的优先级高于任何Non-secure Group 1的中断。
在这里插入图片描述

软件可能不知道GIC支持两种安全状态,因此可能不知道它是对GIC寄存器进行安全访问还是非安全访问。然而,对于任何实现的中断,软件可以将0xFF写入相应的GICR_IPRIORITYRn优先级值字段,然后读回该字段中存储的值,以确定支持的中断优先级范围。Arm建议,在以这种方式检查优先级范围之前:

  • 对于外围设备中断,软件首先禁用该中断。
  • 对于SGI,软件首先检查中断是否处于非活动状态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值