ARMv8 中断管理(1): 架构与GICv3

ARMv8 中断系统的架构

GIC 的输入为许多的中断线,但输出到 CPU 的只有 IRQ 和 FIQ 两种, 所以就要由 GIC 做中断的分发和过滤工作。

总体来说,整个中断系统架构从底向上可分为三部分:

  1. 硬件接口;外设的引脚
  2. 中断控制器;桥梁,向下提供引脚连接外设,向上连接 CPU 在合适的时间 触发中断信号,充当中断系统的主管
  3. 中断处理函数;GIC 将中断信号传递到 CPU 后,CPU 执行中断处理函数
+-----------+     +-----------+
|  Process  |     |  Process  |
+---------+-+     ++----------+
          |        |
        +-+--------+----+
        |               |
        |      GIC      |
        |               |
        +-------+-------+
                |
  +-------------+----------+
  |   Peripheral Device    |
  +------------------------+

中断控制器 GICv3

GIC 的有许多版本,本文皆以 GIC version3 为例介绍, 简称为 GICv3

如上所述,GIC 在中断系统中充当“管家”的作用。如果将 CPU 比作老板, 到来的中断比作约见老板的员工,那么 GIC 就是秘书,统筹安排何人何时 与老板谈话。

GICv3 的组成大概可分为 3 部分:

  • Distributor
  • Redistributor
  • CPU Interface

如果将上面架构图中的 GIC 拆开,大概的结构如下图所示。能够注意到除了 GIC 被细分外,外设中断源也划分为两部分,在下面中断分类中会详细 介绍。

+----------------+    +----------------+
|    Process     |    |    Process     |
+--+----------+--+    +--+----------+--+
   |   CPU    |          |   CPU    |
   | Interface|          | Interface|
   +----+-----+          +----+-----+
        |                     |
 +------+-------+      +------+-------+
 | Reditributor |      | Reditributor +-----+
 +----------+---+      +--+-----------+     |
            |             |                 |
        +---+-------------+-----+           |
        |                       |           |
        |     Distributor       |           |
        |                       |           |
        +-----------+-----------+           |
                    |                       |
          +---------+--------+      +-------+---------+
          |Peripheral Device |      |Peripheral Device|
          |      (SPI)       |      |      (PPI)      |
          +------------------+      +-----------------+

Distributor

负责全局中断的分发

Redistributor

Redistributor 是 GICv3 相较于 v2 新引入的部件,在我看来,引入 Redistributor 的 主要原因是: 提高中断相应的效率。 在以前,无论是全局中断还是私有中断都是通过一个 Distributor 分发,如果中断到来的比较频繁,则可能产生延迟。

Redistributor 就主要负责私有中断的分发,减轻了 Distributor 的负担。

CPU Interface

物理结构上依附与 CPU,而不是 GIC。主要负责控制中断被 CPU 接收的过程, 即中断状态 pengding , active, inactive 的切换。

同时, CPU Interface 还负责优先级的过滤,只有符合优先级条件的中断才会被 CPU 响应。 相关的寄存器有ICC_PMR_EL1ICC_RPR_EL1

中断抢占的配置也是由其完成,详见ICC_BPRx_EL1寄存器。

GICv3 Affinity Rounting

GICv3 以前都是用 target-list, 来设置中断到达的目的 CPU,这种方式类似于位图, 以前只有 8bit 来做这个,所以采用 GICv2 的系统最多支持 8 个 CPU。

而 GICv3 引入了 Affinity value 来支持更多的 CPU,类似于 IP 地址的方法,用 4 个 8bit 来标识。可以写作a.b.c.d

  • c: 一般是指某个 cluster
  • d: 转发时会填入 target-list,指定多个 CPU,最多 8 个(下图的形式还没有将d转为targetlist)

所以用 Affinity value 虽然能指定大于 8 个 CPU,但是一次只能发往一个 cluster 内的最多 8CPU。

GICv3 中断的分类与标识

在使用 GICv3 的系统上,中断被划分为 4 种类型:

  • spi: 全局的中断,可以被路由到任意的一个或多个 CPU。一般对应所有 CPU 共用 的外设,例如串口中断。
  • ppi: 每个 CPU 私有的中断,只能被路由到该 CPU。对应与 CPU 私有的外设中断, 例如 CPU 内部定时器中断。
  • sgi: CPU 触发的中断,可以被路由到任意 CPU。一般用于核间通信使用。
  • lpi: message-based interrupts 这里不做介绍.

中断标识: INTID

CPU 如何区分当前来的中断是来自哪个外设的中断信号? 答案是通过 INTID,它是 GIC 定义的中断标识符,CPU 通过读取寄存器ICC_IAR1_EL1就能得知当前处理中断的 INTID。

INTID 按照中断类型分类的, 对照表如下:

INTID中断类型Note
0-15SGI本地的, 不同 CPU 可使用同一中断号代表不同中断
16-31PPI本地的
32-1019SPI全局的
1020-1023特殊中断
1056-1119扩展的 PPI本地的
4096 – 5119扩展的 SPI全局的

扩展中断号的最大值是实现定义的, 可以在GICD_TYPER.IDbits中读取。

特殊中断号

特殊中断不需要 end of interrupt or deactivation 过程.

  • 1020:

  • 1021:

  • 1022:

  • 1023: 读ICC_IAR1_EL1 返回该值表明当前的 CPU 上没有待处理的中断, 编程时可当做while退出的标志

小结

这节主要总结 ARMv8 中断系统的总体架构和 GICv3 的组成结构,下一节将介绍 一个中断的生命周期,即中断的状态转换,以及在此过程中各个组件的作用。


创建于: 2023-04-12T21:51:49, Lastmod: 2024-05-12T21:54:13