baron · 3月26日 · 四川

[ARM异常]-ARM体系中是否支持中断嵌套

快速连接

👉👉👉【精选】ARMv8/ARMv9架构入门到精通-目录 👈👈👈


 title=

说明:
在默认情况下,本文讲述的都是ARMV8-aarch64架构,gicv3, linux kernel 5.14

请添加图片描述

思考:你是否想过这样的一个场景:当一个中断正在处理事务时,又来了一个高优先级中断把它抢占了? 也就是所谓着中断嵌套。很多人可能都会说“这种场景当然存在了”,但现实中真的存在吗? 不要被网上的博客或书上的一些章节所误导,今天我们抛开事务看本质,从以下方面着手进行讨论:

  • ARM CORE支持中断嵌套吗
  • GIC中断控制器支持中断嵌套吗?
  • Linux Kernel操作系统有没有使用中断嵌套?

在介绍之前,我们先记下几个共识(也就是常识,本文不做重复介绍的):

  • FIQ和IRQ具有同样的优先级,FIQ只是一种中断类型,并非所谓着快速中断。
1、ARM CORE支持中断嵌套吗?

首先来看ARM CORE支持中断嵌套吗?答案 支持! 但是是有一个前提,在进入中断处理时,PSTATE的I、F、A等比特位是MASK的,软件中需要主动unmask后,那么就可以中断嵌套了。如下图所示,正是ARM Core支持中断嵌套的一个示例(或者叫模型):
在这里插入图片描述

2、GIC中断控制器支持中断嵌套吗?

继续看GIC中断控制器支持中断嵌套吗?答案 支持中断抢占,支持中断嵌套!

2.1、先介绍以下优先级和抢占的概念
  • 每个 INTID(中断号) 都有一个优先级(用寄存器GICD_IPRIORITYnGICR_IPRIORITYn 表示),它是一个 8 位无符号值。 0x00 是可能的最高优先级,0xFF 是可能的最低优先级
  • 每个 PE 在其 CPU interface中都有一个优先级掩码寄存器 (ICC_PMR_EL1)。 该寄存器设置将中断转发到该 PE 所需的最低优先级。 只有优先级高于寄存器值的中断才会发送给 PE
  • GICv3 架构具有 运行优先级的概念。 当 PE 响应中断时,它的运行优先级变为该中断的优先级。 当 PE 写入 EOI 寄存器之一时,运行优先级将返回其先前值。 如果 PE 尚未处理中断,则运行优先级为空闲优先级 (0xFF)。 只有优先级高于运行优先级的中断才能抢占当前中断
2.2、Without preemption : 即关闭抢占,disable running priority

在Without preemption的情况下,高优先级的中断无法抢占正在active的中断,只能等active的中断执行完了、返回了,高优先级的中断才能发生"抢占"(这里还说抢占,合适吗? 此种情况应属于抢占pendding中断)。 如下图所示,便是一个示例:

  • 高优先级的中断 无法抢占active的中断
  • 等待active的中断执行完毕返回了,高优先级的中断才能发生抢占(也就是抢占pendding中断)
    在这里插入图片描述
    虽然你关闭了抢占,但优先级仍然存在,仍然会发生作用

    抢占正在pendding中断的示例, 这种情况下,一个高优先级的中断可以抢占一个低优先级的pendding中断,并非抢占正在执行的中断,抢占后高优先级的中断变成pendding。而我们大多数人所说的中断嵌套是指,一个中断正在执行时,被另外一个中断给抢占了。
    当 CPU interface上的一个低优先级中断处于pendding状态时,更高优先级的中断也可能会变为pendding状态。 Redistributor 可以为新的更高优先级中断发送 Set 命令。 此 Set 命令将取代之前的 Set 命令,导致 CPU interface为较低优先级的中断发出 Release。 下图显示了此类场景的示例。 该示例假设 INTID Y 的优先级高于 INTID X。
    在这里插入图片描述

    2.3、With preemption

    接下来就看 抢占正在active中断的示例,描述的其实就是:一个中断正在执行,然后另一个更高优先级的中断打断了它, 这也就是正是我们所说的中断嵌套。

在考虑抢占时,运行优先级的概念很重要。 当一个高优先级中断被发送给一个已经在处理一个低优先级中断的 PE 时,就会发生抢占。 抢占为软件带来了一些额外的复杂性,但它可以防止低优先级中断阻塞更高优先级中断的处理。
在这里插入图片描述

2.4、那么对于一个gicv3的IP,优先级肯定是有的,它到底是Without preemption 还是With preemption呢? 如何配置的呢?

请查略ICC_BPRn_EL1寄存器,该寄存器定义优先级值字段分成两部分的点,即组优先级字段和子优先级字段。 组优先级字段确定组 1 中断抢占。<font color=blue size=4> 换句白话来解释就是,中断优先级被分成了两部分,如下图所示,ICC_BPRn_EL1寄存器的BIT[2:0]定义了下图中的N的值</font>
在这里插入图片描述
对于抢占,仅考虑Group优先级位。 Subpriority优先级位被忽略. 然后举一个例子:

  • INTID A has priority 0x10
  • INTID B has priority 0x20
  • INTID C has priority 0x21

如上有三个中断,A可以抢占B,但B不可以抢占C,因为B和C的Group priority是一样的
在这里插入图片描述

3、 Linux Kernel操作系统有没有使用中断嵌套?

继续看Linux Kernel操作系统有没有使用中断嵌套?答案<font color=red size=4> 没有使用!</font>

首先查看ICC_BPRn_EL1寄存器的配置:
在这里插入图片描述
写入的是0,也就是意味着,N=0, 即下图的第一行,也就是说抢占是开启的。
在这里插入图片描述
继续看,针对每一个 INTID(中断号) 的priority的配置,如下所示,在gic初始化阶段,给每一个 INTID(中断号) 都配置成了一样的优先级,值位0XA5。 也就是所有中断的优先级都是一样的。
在这里插入图片描述
事实上,在gicv3代码中,提供了一个接口,可以单独针对某一中断设置优先级。
查略该函数用途,仅仅是为NMI中断设置的(注:Linux Kernel中armv8体系目前还没有该中断,ARMV9新增了一类NMI中断),其值为0Xa5 & 0x7f = 0x25,该值小于0XA0,所有该优先级大于其它中断的优先级。
在这里插入图片描述


关注"Arm精选"公众号,备注进ARM交流讨论区。
图片1.png

推荐阅读
关注数
9462
内容数
207
以易懂、渐进、有序的方式,深入探讨ARMv8/ARMv9架构的核心概念。我们将从基础知识开始,逐步深入,覆盖最新的架构,不再纠缠于过时技术。本系列内容包含但不限于ARM基础、SOC芯片基础、Trustzone、gic、异常和中断、AMBA、Cache、MMU等内容,并将持续更新。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息