登录后台

页面导航

本文编写于 509 天前,最后修改于 450 天前,其中某些信息可能已经过时。

2023-05-15T13:11:45.png
# 中断类型

  1. locality- specific peripheral interrupt(LPI):LPI是一个有针对性的外设中断,通过affinity路由到特定的PE。
    • 为非安全group1中断
    • 边沿触发
    • 可以通过its进行路由
    • 没有active状态,所以不需要明确的停用操作
    • LPI总是message-based interrupt
  2. private peripheral interrupt(PPI):PPI是针对单个特定PE的外设中断,不同的PE可以使用同一个中断号来表示不同的事件
    • 可以是任意group中断
    • 支持电平触发或边沿触发
    • 不使用ITS进行路由
    • 有active状态,所以需要明确的停用操作
    • 通常情况下,PPI被每个PE上的同一个中断源的不同实例所使用,从而允许一个共同的中断号被用于特定的事件,例如来自私有定时器的中断。
  3. shared peripheral interrupt(SPI):SPI时一种物理中断,它可以通过distributor路由到特定的PE进行除了,或路由到PE集群中某一个配置为可以接收这种中断类型的PE上。
    • 可以是任意group中断
    • 支持电平触发或边沿触发
    • 从不使用ITS进行路由
    • 有active状态,所以需要明确的停用操作
    • 可以是message- based的中断
  4. software generated interrupt(SGI):SGI通常用于处理器间通信。通过向gic中的一个寄存器写入产生
    • 可以是任意group中断
    • 边沿触发
    • 从不使用ITS进行路由
    • 有active状态,所以需要明确的停用操作

边沿触发:在检测到一个中断信号的上升沿时被断言,然后无论该信号的状态如何都会保持断言,直到该中断被软件确认。

电平触发:只要中断信号的电平处于活动状态,它就会被断言。只要电平不活动,就会解除断言。

中断的路由与分发

INTIDs

中断会通过中断ID进行区分,中断ID需要遵循以下规则:

  1. 对于gicd与gicr中支持的中断ID位数有着如下限制:
    • 如果不支持LPI,gicd中的INTID位数被限制在10位(2^10=1024),与早期的gic版本相同
    • 如果支持LPI,INTID位数范围为14-24(8192~),具体在GICD_TYPER寄存器中定义
  2. 对于ITS中支持的INTID位数:
    • 如果支持LPI,INTID位数范围为14-24,具体在GICS_TYPER寄存器中定义。
    • ITS必须设置INTID位数,以便被转发到gicr中的中断是在它所支持的中断范围内,否则该行为是不可预测的。
  3. 对于CPU interface中支持的INTID位数:
    • 在GIC V3中CPU interface支持16bits和24bits两种INTID字段。支持的中断ID位数由ICC_CTLR_EL1的ID位以及ICC_CTLR_EL3的ID位表示

有效的INTID位数由gicd和CPU interface中定义的大小来共同决定。将大于支持的位数大小的INTID转发给CPU interface是一个编程错误。未使用的INTID位数是RAZ(read as zero)。

Affinity Routing

亲和路由是一种基于分层地址的方式,用于识别特定的PE节点进行中断路由。

对于一个PE,亲和路由在aarch64状态下由MPIDR_EL1寄存器中定义,在aarch32状态下由MPIDR寄存器定义。亲和路由是一个32位的值,是由4个8位的亲和路由字段组成。

  • 亲和路由级数:gic v3在aarch64状态下,支持4级或3级亲和路由。而在aarch32下只支持3级亲和路由。ICC_CTLR_EL3.A3V,ICC_CTLR_EL1.A3V,和GICD_TYPER.AV3表示是实现4级还是3级亲和路由。
  • 亲和路由的使能:安全状态的亲和路由是在gicd中通过配置affinity routing enable位(ARE)来启用的。对于安全中断,GICD_CTLR.ARE_S 位被设置为1。对于非安全中断GICD_CTLR.ARE_NS位被设置为1。

中断处理与优先级

中断生命周期

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

2023-05-15T12:25:01.png

  1. generate interrupt:中断是由外设或者软件产生的。
  2. distribute:IRI执行中断分组、中断优先级并且控制终端向CPU interface的转发。
  3. deliver:CPU接口将中断传送到相应的PE。
  4. activate:当PE中的软件确认了一个信号,gic将最高的活动优先级设置给被激活的中断。对于SPI、SGI和PPI中断状态变为activate。
  5. priority drop:软件向gic发出信号,表示最高优先级的中断已经被处理到了可以放弃运行优先级的程度。然后运行优先级的值恢复到中断被确认前的值。这就是中断处理程序所指示的中断结束点。中断结束点也可以被配置成为中断的deactivation。
  6. deactivation:清除中断的活动状态,从而允许中断在pending状态下可以再次被使用。deactivation对于LPI来说是不需要的。deactivation可以被配置为在priority drop时同时发生,也可以在它之后发生。

CPU interface

CPU接口接收由gic IRI确认优先级的待处理中断,并且确认该中断是否为CPU接口中启用的中断分组,并且有足够的优先级向PE发出信号。接口连接的PE可以在任何时刻通过读取ICC_HPPIR0_EL1 or ICC_HPPIR1_EL1寄存器的值来确定pending状态下优先级最高的中断的INTID,以及通过读取ICC_RPR_EL1寄存器的值来确定CPU接口的运行优先级(running priority:对于没有发生过优先级下降的active中断的优先级称为运行优先级)。

当LPI被确认时,在gicr中,中断的pending状态变为not pending。gicr不会为LPI维持active

中断处理状态机

2023-05-15T12:25:52.png

  • A1、A2 : add pending state。这可能是外设产生中断的结果,也可能是软件产生中断的结果
  • B1、B2 : remove pending state。如果中断是一个电平触发的中断,那么当中断被外设转置时或软件改变了等待状态时,就会发生这种转换。对于LPI,这种转换发生在对中断的确认时
  • C :pending to active。如果中断是边沿触发的SPI、SGI和PPI,当PE确认了这个中断时,会发生这种转换。
  • D:pending to active and pending。如果中断是电平触发的SPI、SGI和PPI,当PE确认了这个中断时,会发生这种转换。
  • E1、E2:remove active state。当软件deactivate一个SPI、SGI或PPI中断时发生。

中断分组

ARM架构提供了两种安全状态(安全、非安全),每一个状态都关联独立的物理地址空间。GIC V3架构支持路由和处理两种安全状态相关的中断。GIC V3使用中断分组作为一种机制,使中断处理与ARM V8的异常模型和安全模型相匹配。

  • group 0 的中断:ARM会在EL3处理这个中断
  • 安全group 1的中断:ARM会在安全状态EL1处理这个中断
  • 非安全的group 1的中断:在使用虚拟化的系统中,ARM会在非安全的EL2处理这个中断;在不使用虚拟化的系统中,ARM会在非安全的EL1处理这个中断。

在多处理器系统中,某个PE可能只支持安全状态下可用资源的访问或非安全状态下访问资源。如果:

  • group 0 或者安全的group 1中断被转发到只支持非安全的PE上
  • 非安全的group 1中断被转发到只支持安全的PE上

会被视为一个编程错误。

当一个group 0 的物理中断在所有的pending中断中有着最高的优先级,并且自身优先级足够时,通常被表示为FIQ。

当一个group 1 的物理中断在所有的pending中断中有着最高的优先级、自身优先级足够且满足以下条件中的某一个时,表示为FIQ,否则为IRQ

  • 这个中断时其他安全状态的中断,即与当前PE执行的安全状态不同
  • 该PE在EL3执行

2023-05-15T12:26:21.png

中断优先级

中断优先级描述了:

  • 中断优先权的配置和控制
  • 待定中断的执行顺序
  • 确定中断对目标PE的可见时间,包括中断优先级屏蔽、优先级分组、活动中断抢占。

在GIC优先级方案中,优先级数值越小,优先级越高。

GIC对中断优先级进行了分组。讲优先级值分成两个字段,即group priority组优先级 和 subpriority子优先级。抢占时,具有相同组优先级的中断被认为具有相同的优先级,不关注子优先级值为多少。当多个待处理中断具有相同的组优先级时,GIC会使用子优先级来决定优先处理哪一个pending状态的中断。当子优先级也相同时,GIC对于pending中断的选择是由具体实现来决定的。

GIC使用组优先级来决定一个pending状态的中断是否拥有足够的优先级(sufficient priority)来抢占正在PE执行的中断。

  • pending中断的组优先级数值必须低于PE的运行优先级
  • 中断的优先级值必须低于其优先级掩码的值

ICC_BPR0_EL1:表明了group 0中断组优先级和子优先级的位数

ICC_BPR1_EL1:表明了group 1中断组优先级和子优先级的位数

2023-05-15T12:26:47.png

中断的抢占

定义:CPU interface支持在active中断完成前向目标PE发出优先级更高的待处理中断信号。

一个待处理中断只有在以下两种情况都满足时才会被CPU interface发给PE:

  • 其优先级高于该CPU interface的屏蔽优先级(由ICC_PMR_EL1寄存器定义。该寄存器的复位值为0,会屏蔽所有的中断,GIC不向相关的PE发出信号。GIC在比较pending中断的优先级和优先级阈值时不使用组优先级)
  • 它的组优先级高于该CPU interface上的运行优先级

抢占发生在PE接收新的中断时,并开始处理新的中断,而不是处理先前的active中断或者当前运行的程序。当这种情况发生时,最初的active中断被称为已经被抢占了。进程状态PSTATE中的DAIF位决定了PE是否通过采取中断来响应中断信号。

GIC多芯片操作

在多芯片系统中,主要影响的是SPI的行为。在多芯片系统中,每个chip上都要集成一个GIC。GIC对于多芯片系统最多支持16个chip。对于多芯片系统,PPI不需要任何特定的考虑。因为它们是被限制在单个chip上,并且通过对应chip上的相关GICR寄存器进行编程的。SGI在多芯片和单芯片配置中的表现也是一样的,它的路由寻址都是通过MPIDR进行的。

为了控制所有芯片配置的一致性,GIC使用了一组寄存器,它们定义了chip之间的连接。这些寄存器被称为路由表,由三种类型的寄存器组成:

  • 芯片寄存器GICD_CHIPR
  • 默认芯片寄存器GICD_DCHIPR
  • 芯片状态寄存器GICD_CHIPSR

GICD_CHIPR定义了路由表。它规定了芯片所拥有的spi,以及芯片的访问方式。这个寄存器存在于多芯片配置中的每一个芯片上,因此每个芯片都有一个路由表的副本。

GICD_DCHIPR定义了当前负责路由表一致性的芯片。并且表明在什么时候进行路由表的更新。在多芯片配置中的每个芯片上都有该寄存器的一个副本

GICD_CHIPSR定义了当前芯片的状态细节。在多芯片配置中的每个芯片上都有该寄存器的一个副本。

复位时,在多芯片配置中的每个芯片实际上是一个独立的全功能GIC。为了使多芯片配置连贯,所有配置中的芯片都必须互相连接。并且一个芯片必须得拥有路由表。当配置中的多芯片连接起来之后,每32个spi被分为一个集合,每个芯片可以拥有若干个spi的集合,也就是芯片之间的SPI空间是分段的。按照路由表,不属于任何芯片的spi不能被使用。芯片上的SPI线只能用于属于自己的SPI。但是message-base SPI支持对任何芯片拥有的spi的访问。