为了理解贺贺老师的大系统中断的9种示例文档,理解整个ARM在安全和非安全模式中对各种中断的响应流程,我今天看了周贺贺老师在阅码场和csdn写的文章。点击链接可以直达。看的是下面图中关于中断的文章:


看了之后对大系统的中断路由有了很大的收获,在此记录一下,以免忘记。
这里先说说一些前置的知识。
1.CPU 有三种执行环境(Runtime):
• cpu执行在ATF:此时cpu处于EL3,此时的cpu一般的工作是切换REE和TEE,主要是保存和回复现场。
• cpu执行在REE:非安全侧的cpu执行环境,一般是我们的linux,此时cpu一般处于EL1。
• cpu执行在TEE:安全侧的cpu执行环境,一般是optee或者是商用的TEE,此时cpu一般处于EL1。
2.中断有三 种分类:
• NS-Group 1 : 想给REE处理的中断,也就是给non-secure EL1处理
• S-Group 1 : 想给TEE处理的中断,也就是给secure EL1处理
• Group 0: 想给ATF处理的中断,也就是给EL3处理
2.SCR_EL3(Secure Configuration Register)寄存器:
这里我只需要看FIQ,IRQ,NS这3个位就可以了,看数据手册:

NS:非安全位,NS=0表示cpu处于Secure,也就是上面说的TEE环境,NS=0表示cpu处于SNon-secure,也就是上面说的REE;
IRQ:中断位,IRQ=1表示cpu在EL3的时候来了一个EL3以下(EL1或者EL2)的中断,中断控制器(更准确的说是cpu中的中断接口)会把EL3以下(EL1或者EL2)的中断路由到EL3,让cpu直接跳转到ATF的异常向量表;IRQ=0表示cpu在EL3的时候中断控制器不会做以上操作,cpu不会去响应中断,而是等到cpu回到EL1,再去处理中断。
FIQ:转发中断位,FIQ=1表示cpu在EL3的时候来了一个EL3以下(EL1或者EL2)的中断,中断控制器(更准确的说是cpu中的中断接口)会把EL3以下(EL1或者EL2)的中断路由到EL3,让cpu直接跳转到ATF的异常向量表;FIQ=0表示cpu在EL3的时候中断控制器不会做以上操作,cpu不会去响应中断,而是等到cpu回到EL1,再去处理中断。
4.CPU 有三种执行环境下SRC的状态,大家都是这么设定的,没有为什么:
• cpu执行在ATF: cpu处于EL3,SRC.NS=0,SRC.IRQ=0,SRC.FIQ=0/1
• cpu执行在REE:cpu处于EL1,SRC.NS=1,SRC.IRQ=0,SRC.FIQ=1
• cpu执行在TEE:cpu处于EL1,SRC.NS=0,SRC.IRQ=0,SRC.FIQ=0
5.IRQ和FIQ怎么来的
这个我觉得很重要,就把贺贺老师的描述截取过来,把下面的话翻译一遍就是,只有cpu处于TEE,来的中断是NS-Group 1或者cpu处于REE,来的中断是S-Group 1,cpu才会收到IRQ,其他时候收到的都是FIQ,所以FIQ也叫转发中断,意思是当前cpu环境不应该处理当前中断,需要转一下,让合适的cpu环境过来执行。

6.cpu接受到一个中断,只要这个中断的处理函数还没有处理完毕,这个中断的中断标志位就不会清理,而且,cpu在处理这个中断的时候,会切换异常等级,每一次切换异常等级后cpu interface都会根据NS和Group发送IRQ或者GIQ。
7.中断路由表,这里cpu根据当前异常等级、NS位、IRQ位、FIQ位判断把中断路由到哪里:

前置知识说完了,开始正题,cpu在不同执行环境(3种)来了不同中断(3种),cpu处理中断的流程分别是怎么样的,一共有9种情况。
一、 cpu执行在REE时,来了一个想给REE处理的中断

解析:
1.由于cpu在REE,此时SRC.NS=1,并且中断为NS-Group 1,所以cpu interface 判断为IRQ ,根据SRC.IRQ=0,所以中断路由到了EL1,所以cpu跳转到VBAR_EL1 + offset(IRQ)处理了,处理完成后清理中断标志位返回REE继续执行。
二、cpu执行在TEE时,来了一个想给TEE处理的中断

解析:
1.由于cpu在TEE,此时SRC.NS=0,并且中断为S-Group 1,所以cpu interface 判断为IRQ ,根据SRC.IRQ=0,所以中断路由到了EL1,所以cpu跳转到VBAR_EL1 + offset(IRQ)处理了,处理完成后清理中断标志位返回TEE继续执行。
三、cpu执行在REE时,来了一个想给TEE处理的中断

解析:
1.由于cpu在REE,此时SRC.NS=1,并且中断为S-Group 1,所以cpu interface 判断为FIQ ,根据SRC.FRQ=1,所以中断路由到了EL3,所以cpu跳转到VBAR_EL3 + offset(FIQ)处理了,
2.此时cpu处于ATF的FIQ中断里面,ATF判断到是-Group 1的中断,执行关闭中断然后进行cpu context,切换cpu到TEE中,并且把PC指向VBAR_EL1 + offset(FIQ),TEE时的cpu没有触发中断,但是也是从VBAR_EL1 + offset(FIQ)处开始运行并且处理中断,。
3.TEE的cpu处理完后清理中断标志位,中断返回到ATF,
4.ATF的打开中断,cpu恢复现场然后进行进行中断的返回,回到REE断点处继续执行。
四、 cpu执行在TEE时,来了一个想给REE处理的中断

解析:
1.由于cpu在TEE,此时SRC.NS=0,并且中断为NS-Group 1,所以cpu interface 判断为FIQ ,根据SRC.FRQ=0,所以中断路由到了EL1,所以cpu跳转到VBAR_EL1 + offset(FIQ)处理,
2.此时cpu处于TEE的FIQ中断里面,cpu通过smc指令陷入到ATF中,
3.ATF中的cpu会进行cpu context,保存现场和切换cpu到REE,
4.此时cpu在TEE,由于异常等级发生了变化,根据SRC.NS=1和中断为NS-Group 1,所以cpu interface 判断为IRQ,根据SRC.IRQ=0,所以中断路由到了EL1,所以cpu跳转到VBAR_EL1 + offset(IRQ)处理了,
5.REE的cpu完成中断处理后清理中断标志位,返回ATF,
6.ATF的cpu会返回到TEE,TEE的cpu会恢复现场然后进行中断的返回,回到TEE断点处继续执行。
五、cpu执行在REE时,来了一个想给ATF处理的中断

解析:
1.由于cpu在REE,此时中断为Group 0,所以cpu interface 判断为FIQ ,根据SRC.FIQ=1,所以中断路由到了EL3,所以cpu跳转到VBAR_EL3 + offset(FIQ)处理了,处理完成后清理中断标志位,返回REE继续执行。
六、cpu执行在TEE时,来了一个想给ATF处理的中断

解析:
1.由于cpu在TEE,此时中断为Group 0,所以cpu interface 判断为FIQ ,根据SRC.FIQ=0,所以中断路由到了EL1,所以cpu跳转到VBAR_EL1 + offset(FIQ)处理了,
2.此时cpu在TEE的中断中,再中断会执行smc指令陷入ATF,陷入到ATF的cpu会由于异常等级发生了变化,根据中断为Group 0,所以cpu interface 判断为FIQ,但是因为SRC.FIQ=0,根据路由表,EL3不会进入中断处理函数,但是会判断中断是Group 0,知道这个给自己处理的中断,所以自己处理了。
3.ATF的cpu处理完中断,清理中断标志位则返回TEE,TEE的cpu会继续完成FIQ中断,恢复现场,返回TEE断点执行。
上面的说法是错误的,修改一下:
解析:
1.由于cpu在TEE,此时中断为Group 0,所以cpu interface 判断为FIQ ,根据SRC.FIQ=0,所以中断路由到了EL1,所以cpu跳转到VBAR_EL1 + offset(FIQ)处理了,
2.此时cpu在TEE的中断中,再中断会执行smc指令陷入ATF,陷入到ATF的cpu会由于异常等级发生了变化,根据中断为Group 0,所以cpu interface 判断为FIQ,但是因为SRC.FIQ=0,根据路由表,EL3不会进入中断处理函数,而会返回REE,
3此时cpu在REE,中断为Group 0,所以cpu interface 判断为FIQ ,根据SRC.FIQ=1,所以中断路由到了EL3,所以cpu跳转到VBAR_EL3 + offset(FIQ)处理了,处理完成后清理中断标志位返回REE,又从REE返回到ATF,再从ATF返回到TEE的中断向量表中,cpu最后返回TEE断点处。
七、cpu执行在ATF时,来了一个想给REE处理的中断

解析:
1.由于cpu在ATF,此时SRC.NS=0,并且中断为NS-Group 1,所以cpu interface 判断为IRQ,根据SRC.IRQ=0,查看中断路由表,ATF不会响应中断,而会继续处理自己的事情,直到ATF处理完毕,主动回到REE或者TEE。
2.这里就有两种情况了,一种是回到REE,另一种回到TEE:
八、cpu执行在ATF时,来了一个想给TEE处理的中断

解析:
1.由于cpu在ATF,此时SRC.NS=0,并且中断为S-Group 1,所以cpu interface 判断为FIQ,这里要分三种情况分析:
ATF的SRC.FIQ=1 :根据SRC.FIQ=1,所以中断路由到了EL3,所以cpu跳转到VBAR_EL3 + offset(FIQ)了,在ATF的中断向量里面判断到中断为S-Group 1,执行关闭中断然后进行cpu context,切换cpu到TEE中,并且把PC指向VBAR_EL1 + offset(FIQ),TEE时的cpu没有触发中断,但是也是从VBAR_EL1 + offset(IRQ)处开始运行并且处理中断,处理完中断后清除中断标志位并且返回ATF,ATF继续完成FIQ,然后恢复现场,回到ATF断点执行。这里说明一下,由于中断已经处理完成,中断标志位清除了,不需要考虑ATF返回的事情,下面的情况是因为中断还没有处理,需要ATF返回处理,所以需要分情况。
ATF的SRC.FIQ=0,等下返回TEE:由于异常等级发生变化,cpu interface会重新发送中断,接下来相当于前面说的第二种情况。自己回头看,这里不再次展开分析了。
ATF的SRC.FIQ=0,等下返回REE:这里需要说明一下,目前ATF的SRC.FIQ=0,由于需要返回REE,所以中间会有一个中间的阶段,就是ATF的SRC.FIQ=1,但是由于异常等级没有发生变化,cpu interface不会重新发送中断,直到返回到REE,CPU返回到REE后,接下来相当于前面说的第三种情况,这里不再次展开分析了。
九、cpu执行在ATF时,来了一个想给ATF处理的中断

解析:
1.由于cpu在ATF,此时中断为Group 0,所以cpu interface 判断为FIQ,这里要分三种情况分析:
ATF的SRC.FIQ=1 :根据SRC.FIQ=1,所以中断路由到了EL3,所以cpu跳转到VBAR_EL3 + offset(FIQ)了,在ATF的中断向量里面判断到中断为Group 0,判断到是给自己的中断,自己就处理了,处理完后清除中断标志位恢复现场,返回断点继续执行。
ATF的SRC.FIQ=0,等下返回TEE:由于异常等级发生变化,cpu interface会重新发送中断,接下来相当于前面说的第六种情况。自己回头看,这里不再次展开分析了。
ATF的SRC.FIQ=0,等下返回REE:这里需要说明一下,目前ATF的SRC.FIQ=0,由于需要返回REE,所以中间会有一个中间的阶段,就是ATF的SRC.FIQ=1,但是由于异常等级没有发生变化,cpu interface不会重新发送中断,直到返回到REE,CPU返回到REE后,接下来相当于前面说的第五种情况,这里不再次展开分析了。
到这里,九种情况都梳理了一遍,接下来就是自己去追代码,加深印象,了解实际代码中每一个详细的操作了。再见!!!
参考的文章链接如下:
周贺贺:armv8-armv9中断系列详解-硬件基础篇(new)
周贺贺:armv8/armv9中断系列详解-中断示例展示(new)
周贺贺:armv8/armv9不同特权程序之间的跳转模型(new)
00-armv8/armv9中断系列详解-序言⚡
10-ARM gicv3/gicv4的总结-基础篇 ⚡
20-armv8/armv9中断系列详解-硬件基础篇⚡
21-Linux Kernel/optee/ATF/hafnium等操作系统的异常向量表的速查
22-armv8/armv9中断系列详解-软件篇-Linux kernel中断相关软件导读⚡
40-armv8/armv9中断系列详解-中断示例展示(不含虚拟化部分)⚡
42-armv8/armv9中断系列详解-optee运行时来了一个REE(linux)中断–代码导读⚡
[答疑]-中断流程举例:在TEE侧时产生了FIQ,回到REE后为啥又产生了IRQ
[答疑]-中断流程举例:在REE(SCR.FIQ=1)侧时产生了FIQ,跳转到EL3后做了哪些事情?
Linux和optee双系统中1020-1023号的中断号的使用
EL3中设置的中断的routing模型
50-armv8/armv9中断系列详解-中断示例展示(虚拟化部分)⚡