GICv2知识点总结

安全扩展:


ARM处理器安全扩展是ARMv7-A架构配置文件的可选扩展。这意味着ARMv7-A实现是否包括安全扩展是实现定义的。ARM安全扩展通过以下方式促进安全应用程序的开发:

  • 将硬件安全功能集成到架构中

  • 提供安全的虚拟内存空间,在安全状态下由内存访问访问

  • 提供非安全虚拟机内存空间,由处于非安全状态的内存访问访问。

当实现GIC安全扩展的GIC连接到实现ARM安全扩展的处理器时:

  • 组0是安全中断,组1是非安全中断

  • 在访问GIC寄存器时:

  • 对保存状态信息的寄存器字段的非安全读取,安全中断返回零

  • GIC忽略对寄存器字段保持状态的任何非安全写入,以形成安全中断。

非安全访问只能读取或写入与非安全中断对应的信息。安全访问可以读取或写入与非安全和安全中断相关的信息。

  • 安全系统软件单独将每个实现的中断定义为安全或非安全。

  • 非安全中断向目标处理器发出IRQ中断请求信号。

  • 安全中断可向目标处理器发出IRQ/FIQ中断请求信号。

  • 安全软件可以安全地管理中断源,而不会受到非安全软件的干扰。


虚拟化支持


  • ARM处理器虚拟化扩展是ARMv7-A架构配置文件的可选扩展。这意味着ARMv7-A实现是否包含虚拟化扩展是实现定义的。

  • 扩展支持系统使用虚拟机监视器(称为管理程序)来切换客户操作系统。

  • 无论是在单处理器还是在多处理器系统中实现,处理器虚拟化扩展都支持在单个处理器上运行多个虚拟机。

  • 中断处理是虚拟化实现中的一个主要考虑因素。管理程序可以自己处理物理中断,也可以生成相应的虚拟中断,并向虚拟机发出信号。管理程序也可以生成与物理中断不对应的虚拟中断。

  • GICv2扩展了GIC体系结构以包括GIC虚拟化扩展。除了物理中断之外,这些扩展还支持在支持处理器虚拟化的系统中处理虚拟中断。


术语


中断状态
  • Inactive:不活动或挂起的中断。

  • Pending:从源到GIC的中断,在硬件中被识别为断言,或由软件生成,并等待目标处理器提供服务。

  • Active:从源到GIC的中断,已被处理器确认,正在服务但尚未完成。

  • Active and pending:处理器正在处理中断,GIC有来自同一源的待处理中断。

中断类型
Peripheral interrupt

由GIC信号断言的中断,包含:

  • Private Peripheral Interrupt (PPI) :这是特定于单个处理器的外设中断。

  • Shared Peripheral Interrupt (SPI) :一个外设中断,分发器可以将其路由到任何指定的处理器组合。

每个外设中断是:

  • 边沿触发(Edge-triggered ):

在检测到中断的上升边缘时断言信号,然后,不管信号的状态如何,保持断言,直到它是通过本规范规定的条件清除。

  • 水平触发(Level-sensitive ):

只要中断信号电平处于活动状态,就会断言,并在level is not active时取消断言。

Software-generated interrupt (SGI) :
  • 这是由软件写入GIC中的GICD_SGIR寄存器产生的中断。系统使用SGI进行处理器间通信。

  • SGI具有边缘触发特性。中断的软件触发等效于中断请求信号的边缘转换。

  • 当多处理器实现中出现SGI时,中断确认寄存器GICC_IAR或别名中断确认寄存器GICC_AIAR中的CPUID字段标识请求中断的处理器。

在包含GIC虚拟化扩展的实现中:

  • 当SGI发生时,GIC虚拟化扩展中的管理寄存器使请求处理器能够按照GIC规范的要求向Guest OS报告

  • 通过写入GIC虚拟化扩展中的管理寄存器,管理程序可以生成一个虚拟中断,该中断在虚拟机中显示为SGI

虚拟中断:

在实现GIC虚拟化扩展的GIC中,针对在处理器上运行的虚拟机,通常由连接的虚拟CPU接口。

维护中断

在实现GIC虚拟化扩展的GIC中,一种级别敏感的中断,用于发出关键事件信号,例如部分中断组启用或禁用。

处理中断模型:

在多处理器实现中,有两种处理中断的模型:

1-N模型:

只有一个处理器处理此中断。系统必须实现一种机制来确定哪个处理器处理被编程为针对多个处理器的中断。

N-N模型:

所有处理器都独立地接收中断。当处理器确认中断时,仅为该处理器清除中断挂起状态。中断对其他处理器保持挂起状态。

Spurious interrupts(虚假中断):

可能不再需要GIC向处理器发出信号的中断。如果发生这种情况,当处理器确认中断时,GIC返回一个特殊的中断ID,将中断标识为虚假中断。虚假中断的示例原因是:

  • 在处理器确认中断之前:

  • 软件更改中断的优先级

  • 软件禁用中断

  • 软件更改中断目标的处理器

  • 对于1-N中断,另一个目标处理器先前已确认该中断。

处理器安全状态以及安全和非安全GIC访问
处于非安全状态的处理器只能对GIC进行非安全访问
安全状态中的处理器可以对GIC进行安全和非安全访问
在非安全状态下运行的软件被描述为非安全软件
在安全状态下运行的软件被描述为安全软件。

具有实现安全扩展的GIC的多处理器系统可能包括一个或多个不实现安全扩展的处理器。实现这样的处理器是为了:

  • 它只对GIC进行安全访问,这意味着处理器上运行的任何软件都是只能对GIC进行安全访问的安全软件

  • 它只对GIC进行非安全访问,这意味着处理器上运行的任何软件都是非安全软件。

banking:
Interrupt banking:

在多处理器实现中,对于PPI和SGI,GIC可以具有相同中断ID的多个中断。这种中断称为banked interrupt,并通过其中断ID和相关CPU接口的组合唯一标识。

Register banking:

Register banking是指在同一地址实现寄存器的多个副本。这发生在:

  • 在多处理器实现中,为每个处理器提供与存储中断对应的寄存器的单独副本

  • 在实现安全扩展的GIC中,提供某些寄存器的单独安全和非安全副本。


GIC partitioning(GIC分区):


概述:

GIC体系结构在逻辑上拆分为一个Distributor block(分发器块)和一个或多个CPU interface blocks(CPU接口块)。GIC虚拟化扩展将一个或多个虚拟CPU接口添加到GIC。如下图:

Distributor:

分发器块对连接到系统中处理器的CPU接口块执行中断优先级和分配。

分发器块寄存器由GICD_前缀标识。

CPU interfaces:

每个CPU接口块对系统中连接的处理器执行优先级屏蔽和抢占处理。

CPU接口块寄存器由GICC_前缀标识。

在描述包含GIC虚拟化扩展的GIC时,CPU接口有时称为物理CPU接口,以避免可能与虚拟CPU接口混淆。

Virtual CPU interfaces :

GIC虚拟化扩展为系统中的每个处理器添加了一个虚拟CPU接口。每个虚拟CPU接口被划分为以下块:

  • Virtual interface control:

虚拟接口控制块的主要组成部分是GIC虚拟接口控制寄存器,其中包括连接处理器上当前虚拟机的活动和待处理虚拟中断列表。通常,这些寄存器由运行在该处理器上的hypervisor管理。

虚拟接口控制块寄存器由GICH_前缀标识。

  • Virtual CPU interface:

每个虚拟CPU接口块向连接的进程提供虚拟中断的物理信号。ARM处理器虚拟化扩展向该处理器上的当前虚拟机发出这些中断的信号。虚拟机访问的GIC虚拟CPU接口寄存器为虚拟中断提供中断控制和状态信息。这些寄存器的格式类似于物理CPU接口寄存器的格式。

虚拟CPU接口块寄存器由GICV_前缀标识。

一个GIC最多可以实现8个CPU接口,编号从0-7。在实现GIC虚拟化扩展的GIC中,虚拟CPU接口编号对应于CPU接口编号,因此CPU接口0和虚拟CPU接口0连接到同一个处理器。

该模型支持在单处理或多重处理环境中实现GIC,GIC虚拟化扩展将这种支持扩展到支持虚拟化的处理器,其中,在非安全状态下:

  • guest OS在虚拟机上运行

  • hypervisor负责在虚拟机之间切换。这种切换包括切换GIC虚拟接口控制寄存器中保存的状态。

每个块都提供了GIC程序员模型的一部分,并且:

  • 程序员的模型对于每个实现的CPU接口通常是相同的。

  • 虚拟CPU接口的程序员模型通常与物理CPU接口的程序员模型相同。

The Distribuor:

分发器集中所有中断源,确定每个中断的优先级,并为每个CPU接口将优先级最高的中断转发给接口,进行优先级屏蔽和抢占处理。

分发器提供编程接口来实现以下功能:

  • 全局启用向CPU接口转发中断。

  • 启用或禁用每个中断。

  • 设置每个中断的优先级。

  • 设置每个中断的目标处理器列表。

  • 将每个外围设备设置为水平触发或边缘触发。

  • 将每个中断设置为组0或组1。

注:对于GICv1,只有当实现包含GIC安全扩展时,才能将中断设置为组0或组1。

  • 将SGI转发到一个或多个目标处理器。

  • 每个中断状态的可见性

  • 软件设置或清除外设中断的挂起状态的机制。

Interrupt IDs:

来自源的中断使用ID号识别。每个CPU接口最多可以看到1020个中断。SPI和PPI的存储增加了分发器支持的中断总数。

GIC分配中断ID号ID0-ID1019如下:

  • 中断号ID32-ID1019用于SPI。

  • 中断号ID0-ID31用于CPU接口私有的中断。这些中断存储在分发器中。

banked interrupt是分发器可以具有多个具有相同ID的中断的中断。存储中断由其ID号和相关的CPU接口号唯一标识。在banked中断ID中:
1. ID0-ID15用于SGI
2. ID16-ID31用于PPI
在多处理器系统中:
PPI被转发到特定的CPU接口,并且对该接口是私有的。在为CPU接口确定中断优先级时,Distributor不考虑与其他接口相关的PPI。
每个连接的处理器通过写入分发器中的GICD_SGIR来发出SGI。每次写入都可以生成针对多个处理器的具有相同ID的SGI。
在分发器中,SGI由其中断号ID0-ID15、目标处理器ID—CPUID0-CPUID7和发出SGI的处理器的处理器源ID—CPUID0-CPUID7的组合唯一标识。当CPU接口将中断ID通信到目标处理器时,它还提供处理器源ID,以便目标处理器可以唯一标识SGI。
SGI banking意味着GIC可以同时处理多个SGI,而不会发生资源冲突。分发器忽略任何不是来自连接到CPU接口之一的处理器的对GICD_SGIR的写入。分发器如何确定写入GICD_SGIR的处理器的处理器源ID是实现规范。
在单处理器系统中,共享中断和私有中断没有区别,因为使用所有中断对处理器都是可见的。在这种情况下,处理器源ID值为0。

中断号ID1020-ID1023保留用于特殊目的。

系统软件设置每个中断的优先级。这个优先级独立于中断ID号。

在任何实现ARM安全扩展的系统中,为了支持处理器之间消息传递的一致模型,ARM强烈建议所有处理器保留:

  • ID0-ID7用于非安全中断.

  • ID8-ID15用于安全中断。

CPU interfaces:

每个CPU接口块为连接到GIC的处理器提供接口。每个CPU接口都提供一个编程接口,用于:

  • 启用向处理器发送中断请求的信号

  • 确认中断

  • 指示中断处理完成

  • 为处理器设置中断优先级掩码

  • 定义处理器的抢占策略

  • 确定处理器的最高优先级挂起中断。

当启用时,CPU接口为其连接的处理器获取最高优先级挂起中断,并确定该中断是否具有足够的优先级使其向处理器发出中断请求信号。为了确定是否向处理器发出中断请求信号,CPU接口考虑中断优先级掩码和处理器的抢占设置。在任何时候,连接的处理器都可以从其GICC_HPPIR这个CPU接口寄存器中读取其最高优先级活动中断的优先级。
向处理器发出中断信号的机制是实现定义。

注:在ARM处理器实现中,发送中断请求的传统机制是通过断言nIRQ或nFIQ。

处理器通过读取CPU接口中断确认寄存器来确认中断请求。此读取返回以下之一:

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

  • 例外情况下,指示虚假中断的ID号。

当处理器在CPU接口确认中断时,分发器将中断的状态从挂起更改为active,或者active and pending。此时,CPU接口可以向处理器发出另一个中断信号,以抢占处理器上活动的中断。如果没有足够优先级的挂起中断向处理器发出信号,接口将中断请求信号解除断言给处理器。

当处理器上的中断处理程序完成中断的处理后,它会写入CPU接口以指示中断完成。中断完成有两个阶段:

  1. 优先级下降,意味着已处理中断的优先级不能再阻止向处理器发出另一个中断的信号

  1. 中断停用,意味着分发器删除该中断的活动状态

在GICv1实现中,当处理器写入CPU接口中断结束寄存器时,这两个阶段总是一起发生。

在GICv2实现中, GICC_CTLR.EOI模式位确定是否:

  • 当处理器写入CPU接口中断结束寄存器时,这两个阶段一起发生

  • 这两个阶段是分开的,因此:

  • 当处理器写入CPU接口中断结束寄存器时发生优先级下降

  • 中断停用稍后发生,当处理器写入CPU接口停用中断寄存器时。


中断处理和优先级:


通常的中断处理:

分发器在每个CPU接口上为每个支持的中断维护一个状态机。下图的中断处理状态机描述了这个状态机及其状态转换。

中断的可能状态有:

  • inactive

  • pending

  • active

  • active and pending.

【注】1. 本节概述了在不包括GIC安全扩展的GIC实现中对中断的处理。它没有给出处理分组中断的完整描述。中断分组和GIC安全扩展扩展了本节中描述的GIC操作的基本模型。

2. 这种中断处理的基本模型也适用于在包含GIC虚拟化扩展的实现中处理虚拟中断。

当GIC识别出中断请求时,它会将其状态标记为挂起。重新生成挂起的中断不会影响中断的状态。

GIC中断处理顺序是:

  1. GIC确定启用的中断。

  1. 对于每个挂起的中断,GIC确定目标处理器或多个处理器。

  1. 对于每个CPU接口,Distributor转发针对该接口的最高优先级挂起中断。

  1. 每个CPU接口确定是否向其处理器发出中断请求,如果需要,则这样做。

  1. 处理器确认中断,GIC返回中断ID并更新中断状态。

  1. 处理中断后,处理器向GIC发出中断结束(EOI)信号。

更详细地说,这些步骤如下:

  1. GIC确定是否启用每个中断。未启用的中断对GIC没有影响。

  1. 对于每个挂起的启用中断,分发器确定目标处理器或多个处理器。

  1. 对于每个处理器,分发器根据它为每个中断持有的优先级信息确定最高优先级的待处理中断,并将中断转发到目标CPU接口。

  1. 如果分发器正在向CPU接口转发中断请求,则CPU接口确定中断是否具有足够的优先级来向处理器发出信号。如果中断具有足够的优先级,GIC向处理器发出中断请求。

  1. 当处理器接受中断异常时,它会读取其CPU接口的GICC_IAR以确认中断。此读取返回一个中断ID,对于SGI,则返回源处理器ID,处理器使用该ID来选择正确的中断处理程序。当它识别到此读取时,GIC会更改中断状态,如下所示:

  • 如果中断的pending状态在中断变为active时仍然存在,或者如果再次产生中断,则从pending到active and pending。

  • 否则,从pending到active

【注】

1. 当处理器acknowledged水平触发的外设中断时,它会持续存在,因为到GIC的中断信号保持断言状态,直到处理器上运行的中断服务例程(ISR)访问断言信号的外设。
2. 在多处理器实现中,GIC处理:
使用GIC N-N模型的PPI和SGI,其中一个处理器对中断的确认对其他CPU接口上的中断状态没有影响
使用GIC 1-N模型的SPI,其中一个处理器对中断的确认会消除任何其他目标处理器上中断的挂起状态。
3. 在GICv2中,当使用GICC_CTLR. AckCtl位设置为0的软件模型时,使用单独的寄存器来管理第0组和第1组中断,如下所示:
GICC_IAR、GICC_EOIR和GICC_HPPIR用于组0中断
GICC_AIAR、GICC_AEOIR和GICC_AHPPIR用于组1中断。
ARM不推荐使用GICC_CTLR. AckCtl,并强烈建议使用GICC_CTLR.AckCtl设置为0的软件模型。
  1. 当处理器完成处理中断时,它必须向GIC发出完成信号。如优先级下降和中断停用中所述,这:

  • 需要对中断寄存器(EOIR)的结束进行有效写入

  • 可能还需要对停用中断寄存器GICC_DIR进行一次写入。

对于每个CPU接口,GIC体系结构要求对EOIR的有效写入顺序与从GICC_IAR或GICC_AIAR读取的顺序相反,因此每个有效EOIR写入都引用最近的中断确认。

如果在EOIR写入之后,没有足够优先级的待处理中断,CPU接口解除断言给处理器的中断异常请求。

CPU接口从不向连接的处理器发出任何活动和挂起的中断信号。它只向挂起并具有足够优先级的中断发出信号:

  • 对于PPI和SGI,标准中断ID的活动状态在CPU接口之间存储。这意味着,如果特定的中断ID在CPU接口上处于活动状态或处于活动状态并挂起,则该CPU接口上不会发出具有相同ID的中断信号。

  • 对于SPI,中断的活动状态对所有CPU接口都是通用的。这意味着,如果一个中断在一个CPU接口上处于活动状态或活动状态并挂起,那么它不会在任何CPU接口上发出信号。

优先级下降和中断停用:

当处理器完成中断处理时,它必须向GIC发出完成信号。中断完成需要对GIC状态进行以下更改:

  1. Priority drop(优先级下降):优先级下降是对EOIR(GICC_EOIR或GICC_AEOIR)的有效写入时发生的运行优先级下降。有效写入是指可预测、不被忽略且不大于1019的中断ID值的写入。

在优先级下降时,运行优先级从EOIR写入引用的中断的优先级降低到:

  • 没有EOIR写入的最高优先级活动中断的优先级

  • 空闲优先级,如果没有活动中断,也没有EOIR写入。

  1. Interrupt deactivation(中断停用):中断停用是中断状态的变化,或者从活动和待处理到待处理,从活动状态到空闲状态。

在GICv1实现上,以及在GICv2实现上,当 GICC_CTLR.EOI模式设置为0时,有效的EOIR写入也会停用它引用的中断。

在GICv2实现中,将 GICC_CTLR.EOI模式设置为1将优先级降低和中断停用操作分开,并且中断处理软件必须:

  1. 执行有效的EOIR写入,导致GIC CPU接口优先级下降。

  1. 随后,写入GICC_DIR,以停用中断。

GIC架构规范要求对有效的EOIR写入进行排序,以便:

  • 有效的GICC_EOIR写入对应于最近确认的中断

  • 有效的GICC_AEOIR写入对应于最近确认的第1组中断。

  • GICC_EOIR写入是影响组0还是组1中断取决于两者:

  • GICC_CTLR的值。AckCtl位

  • 如果GIC实现了GIC安全扩展,则无论写入是安全的还是不安全的。

在包含安全扩展的GICv2实现中:
GICC_AEOIR是GICC_EOIR的非安全副本的别名
GICC_AIAR是GICC_IAR的非安全副本的别名
GICC_AIAR和GICC_AEOIR是安全寄存器,这意味着它们只能通过安全访问访问。

GICC_DIR写入没有顺序要求。但是,如果软件在以下情况下写入GICC_DIR,效果是不可预测的:

  • GICC_CTLR.EOI模式设置为0

  • GICC_CTLR.EOI模式设置为1,没有相应的写入GICC_EOIR或GICC_AEOIR。

在虚拟化物理中断时,ARM建议,对于与运行虚拟机的处理器对应的每个CPU接口:

  • GICC_CTLR.EOI模式位设置为1

  • 如果GIC实现GIC安全扩展, GICC_CTLR.EOImodeNS位设置为1

GIC中的中断控制
中断启用:

对于外围中断,处理器:

  • 通过写入适当的GICD_ISENABLERn位来启用中断

  • 通过写入适当的GICD_ICENABLERn位来禁用中断。

SGI是永久启用的,还是可以通过写入GICD_ISENABLERn和GICD_ICENABLERn启用和禁用的,由实现定义。

写入GICD_ISENABLERns和GICD_ICENABLERns控制分发器是否将特定中断转发到CPU接口。通过写入适当的GICD_ICENABLERn禁用中断不会阻止该中断改变状态,例如变为挂起。

设置和清除中断的挂起状态:

对于外设中断,处理器可以:

  • 通过写入适当的GICD_ISPENDRn位来设置挂起状态

  • 通过写入适当的GICD_ICPENDRn位来清除挂起状态。

对于水平触发中断:

  • 如果当处理器写入相应的GICD_ICPENDRn位时中断的硬件信号被断言,那么对寄存器的写入对中断的挂起状态没有影响。

  • 如果处理器将1写入GICD_ISPENDRn位,则无论该中断的硬件信号状态如何,相应的中断都将挂起,无论信号的断言或断言如何,相应的中断都将保持挂起。

对于SGI,GIC忽略相应的GICD_ISPENDRn和GICD_ICPENDRn位。处理器不能通过写入这些寄存器来改变软件产生的中断的状态。通常,SGI通过写入GICD_SGIR而挂起。在GICv2中,SGI的挂起状态也可以直接使用GICD_SPENDSGIRn和GICD_CPENDSGIRn位进行修改。

查找中断的活动或挂起状态:

处理器可以找到:

  • 通过读取相应的GICD_ISPENDRn或GICD_ICPENDRn位来确定中断的挂起状态

  • 通过读取相应的GICD_ISACTIVERn或GICD_ICACTIVERn位来获取中断的活动状态。

如果中断处于挂起状态或活动状态,则相应的寄存器位为1。如果中断处于挂起状态并处于活动状态,则两个寄存器中的相应位为1。

在保留或恢复GIC状态时,处理器必须考虑所有中断的挂起和活动状态。

对于SGI,如果存在来自至少一个生成处理器的未决中断,则相应的GICD_ISPENDRn和GICD_ICPENDRn位RAO,该中断以读取GICD_ISPENDRn或GICD_ICPENDRn的处理器为目标。在GICv2中,还可以通过读取相应的GICD_SPENDSGIRn或GICD_CPENDSGIRn位来确定发出SGI的处理器。

产生一个SGI:

处理器通过写入GICD_SGIR来生成SGI。SGI可以针对多个处理器,写入GICD_SGIR指定目标处理器列表。GICD_SGIR包括以下方面的优化:

  • 只中断写入GICD_SGIR的处理器

  • 中断除写入GICD_SGIR的处理器以外的所有处理器。

来自不同处理器的SGI使用相同的中断ID。因此,任何目标处理器都可以从不同的处理器接收具有相同中断ID的SGI。但是,如果以下任何一项不同,任何两个SGI的挂起状态都是独立的:

  • 中断ID

  • 源处理器

  • 目标处理器。

任何时候,只有一个具有特定中断ID的中断可以在CPU接口上激活。这意味着一个CPU接口不能同时激活两个具有相同中断ID的SGI,即使不同的处理器向该处理器发送了具有相同中断ID的SGI。

在目标处理器的CPU接口上,读取SGI的GICC_IAR会返回中断ID和产生中断的处理器的CPU ID,即中断的源处理器。中断ID和源CPU ID的组合唯一地标识目标处理器的中断。

在多处理器实现中,每个SGI中断ID的中断优先级是为每个目标处理器独立定义的。对于每个CPU接口,在接口上挂起的具有特定中断ID的所有SGI具有相同的优先级,必须串行处理。CPU接口序列化这些SGI的顺序是实现规范。

1-N模型的含义:

在多处理器实现中,GIC使用GIC 1-N模型来处理针对多个处理器(即SPI)的外设中断。这意味着当GIC识别到来自其中一个目标处理器的中断时,它会清除所有其他目标处理器上中断的挂起状态。GIC实施必须确保使用1-N模型处理的任何中断仅由一个CPU接口确认,并且所有其他接口都返回一个虚假的中断ID。

当多个目标处理器试图确认中断时,可能会发生以下情况:

  • 处理器读取GICC_IAR并获得要服务的中断的中断ID。

在GICv1中,如果多个目标处理器在非常相似的时间读取其GICC_IAR寄存器,则可能有多个目标处理器获得此中断ID。系统可能需要对目标处理器进行软件重新设置,以确保只有一个处理器运行其中断服务程序。实现这一点的典型机制是在共享内存中实现对中断服务程序(ISR)的锁定。
  • 处理器读取GICC_IAR并获得中断ID 1023,指示虚假中断。处理器可以从其中断服务例程返回而无需写入其GICC_EOIR。

虚假中断ID表示原始中断处没有等待很长时间,通常是因为另一个目标处理器正在处理它。

GICv1实现可以确保只有一个处理器可以激活1-N中断,从而消除了对ISR锁定的要求。架构不需要这样做,通用GIC代码不得依赖于此行为。
对于任何处理器,如果中断处于活动状态且挂起,则GIC不会向任何处理器发出中断异常请求,直到活动状态被清除。
中断处理状态机:

GIC为每个CPU接口上支持的每个中断维护一个状态机。下图显示了此状态机的实例以及可能的状态转换:

SGI只能通过写入GICD_SGIR或GICD_SPENDSGIRn生成。外围中断由向GIC断言硬件中断请求信号或写入GICD_ISPENDRn生成

  • 在GICv1实现中,优先级下降始终与中断停用相关联

  • 在GICv2实现中,优先级下降可以与中断停用分开。

图3-1没有显示优先级下降和中断停用的可能分离。这发生在活动状态中。

当分发器的中断转发和CPU接口的中断信号启用时,导致每个状态转换的条件如下:

Transition A1或A2,添加挂起状态

对于SGI,在以下任一情况下发生:

  • 软件写入指定处理器为目标的GICD_SGIR。

  • 目标处理器上的软件写入对应于所需源处理器和中断ID的GICD_SPENDSGIRn位

如果GIC实现了GIC安全扩展,并且对GICD_SGIR的写入是安全的,则只有当指定的SGI的安全配置(对于适当的CPU接口)对应于 GICD_SGIR.NSATT 位值时,才会发生转换。

对于SPI或PPI,在以下任一情况下发生:

  • 外设断言中断请求信号

  • 软件写入GICD_ISPENDRn。

Transition B1或B2,删除挂起状态

对于SGI,如果目标处理器上的软件写入GICD_CPENDSGIRn的相关位,则会发生这种情况。

对于SPI或PPI,在以下任一情况下发生:

  • 水平触发中断挂起只是因为输入信号的断言,并且该信号被取消断言

  • 中断挂起仅仅是因为边缘触发的中断信号,或者对GICD_ISPENDRn的写入,以及软件对相应GICD_ICPENDRn的写入。

Transition C,等待到激活

如果中断被启用并且具有足够的优先级以向处理器发出信号,则在软件从GICC_IAR读取时发生。

Transition D,待定到活动和待定

对于SGI,这种转换发生在以下任一情况下:

  • 如果将SGI状态设置为挂起的写入与GICC_IAR的读取大约同时发生。

  • 当具有相同中断ID的两个或多个挂起SGI来自同一源处理器并以同一处理器为目标时。如果其中一个SGI遵循Transion C,则其他SGI遵循Transion D。

对于SPI或PPI,如果适用以下所有条件,则会发生此转换:

  • 中断已启用。

  • 软件从GICC_IAR读取。此读取将活动状态添加到中断中。

  • 此外,适用的条件之一是:

  • 对于电平敏感中断,中断信号保持断言状态。通常是这种情况,因为外设在处理器服务中断之前不会取消断言中断。

  • 对于边缘触发的中断,这种转换是否发生取决于读取GICC_IAR的时间相对于检测到中断的重新插入。否则,读取GICC_IAR会导致转换C,随后可能是转换A2。

Transition E1或E2,移除活动状态

当软件通过写入GICC_EOIR或GICC_DIR来停用中断时发生。在包括虚拟化扩展的GIC实现中,如果虚拟CPU接口发出相应物理中断已停用的信号,也会发生。

特殊中断号:

GIC体系结构为特殊目的保留中断ID号1020-1023。在不实现GIC安全扩展的GICv1实现中,唯一使用的是ID 1023。如果没有足够优先级的未决中断向处理器发出信号,则该值将返回给处理器,以响应中断确认。它被描述为对虚假中断的响应。

竞争条件可能导致虚假中断。例如,如果处理器在CPU接口向处理器发出中断信号并且处理器识别出中断之后,但在处理器从GICC_IAR读取之前,将1写入GICD_ICENABLERn中对应于挂起中断的字段,则可能会发生虚假中断。
中断优先级

软件通过为每个中断源分配一个优先级值来配置GIC中的中断优先级。优先级值是8位无符号二进制。GIC支持最小为16,最大256个优先级。如果GIC实现的优先级少于256个,优先级字段的低位是RAZ/WI。这意味着实现的优先级字段位数在4-8范围内是实现定义的,如表3-1所示。

在GIC优先级方案中,较低的数字具有较高的优先级,即分配的优先级值越低,中断的优先级就越高。优先级字段值0总是表示可能的最高中断优先级,最低优先级值取决于实现的优先级级别的数量,如表3-1所示。

GICD_IPRIORITYRn寄存器保存每个支持的中断的优先级值。实现可能会为特定目的保留一个中断,并为该中断分配一个固定的优先级,这意味着该中断的优先级值是只读的。对于其他中断,软件写入GICD_IPRIORITYRn寄存器以设置中断优先级。实现定义是否写入GICD_IPRIORITYRn会改变任何活动中断的优先级。

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

ARM建议,在以这种方式检查优先级范围之前:
• 对于外设中断,软件首先禁用中断。
• 对于SGI,软件首先检查中断是否处于非活动状态。

如果在特定的CPU接口上,多个挂起的中断具有相同的优先级,并且具有足够的优先级以便接口向处理器发出信号,则是实现规范接口决定如何选择要发出信号的中断。

当CPU接口上的中断处于活动状态时,GIC可能会在该CPU接口上发出更高优先级的中断信号。

Preemption(抢占):

CPU接口支持在活动中断完成之前向目标处理器发送更高优先级的挂起中断信号。只有在以下两种情况下才会发出挂起中断信号:

  • 它的优先级高于该CPU接口的优先级掩码。

  • 其组优先级高于CPU接口上的运行优先级,优先级分组和运行优先级寄存器,GICC_RPR。

抢占发生在处理器确认新中断的时候,并开始优先于先前活动的中断或当前运行的进程为其提供服务。当这种情况发生时,初始活动中断被称为已被抢占。在另一个中断仍然活动时开始服务中断有时被描述为中断嵌套。

对于符合ARM架构的处理器:
• CPSR中I或F位的值确定处理器是否通过启动中断确认过程来响应信号中断。
• 处理抢占中断时,处理器必须保存并稍后恢复先前活动的ISR的上下文。
优先级下降意味着中断的优先级不再影响CPU接口上的运行优先级,因此不会阻止中断抢占。在GICv1实现中,优先级下降仅在中断停用时发生,但在GICv2实现中,优先级下降和中断停用可以分开。
Priority masking(优先级屏蔽)

CPU接口的GICC_PMR定义了目标处理器的优先级阈值。GIC仅向目标处理器发送优先级高于该阈值的未决中断信号。值为零,即寄存器复位值,会屏蔽所有中断,使其不被发信号给相关处理器。当比较未决中断的优先级和优先级阈值时,GIC不使用优先级分组。

GIC总是屏蔽具有最大支持优先级字段值的中断。这提供了一种额外的方法来防止向任何处理器发送中断信号。

向GICC_PMR写入255总是将其设置为支持的最大优先级字段值。
Priority grouping(优先级分组)

优先级分组使用二进制点寄存器,GICC_BPR,将优先级值分成两个字段,组优先级和子优先级。在确定抢占时,所有具有相同组优先级的中断都被认为具有相等的优先级,而不管子优先级如何。这意味着在每个组优先级上只能有一个处于活动状态的中断。活动组优先级也称为抢占级别。

GIC使用组优先级字段来确定未决中断是否有足够的优先级来抢占活动中断,如下所示:

  • 挂起中断抢占活动中断,其组优先级必须高于活动中断的组优先级。也就是说,新中断的组优先级字段的值必须小于运行优先级的组优先级字段的值。

  • 如果CPU接口上没有活动中断,则可以向处理器发出最高优先级的挂起中断信号,而不管组优先级如何。

在每种情况下,都会将挂起的中断优先级与优先级掩码进行比较,并且仅当中断未被掩码时才会发出信号。

GICC_BPR中的二进制点字段控制将优先级位分成两部分。这个3位字段指定8位中断优先级字段的最低有效位中有多少位被排除在组优先级字段之外,如表3-2所示。

支持的最小二进制点值为0-3范围内的IMPLEMENTATION DEFINED。

有GIC安全扩展的GICv1实现和GICv2实现有两个二进制点寄存器。用于计算优先级分组的二进制点寄存器的副本取决于中断是由GICD_IGROUPRn寄存器定义的0组中断还是1组中断,以及 GICC_CTLR.CBPR 位的值。

当 GICC_CTLR.CBPR 位设置为1时,软件可以配置CPU接口,使用与第0组中断相同的二进制点寄存器来确定第1组中断的优先级分组。

如果多个挂起的中断具有相同的组优先级,GIC使用子优先级字段来解析组内的优先级。如果组中的两个或多个挂起的入口具有相同的子优先级,GIC如何在中断之间进行选择是实现规范。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值