今天来看一下中断及ARM体系中对中断的处理,直接进入正题。
中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。
中断的几个主要目的。第一,通过中断可以提高CPU效率。假设一种场景,CPU通知其它设备完成某项工作,当设备完成任务后,CPU如何知道呢?一种方式是设备标记状态寄存器,等待CPU来查询,这种做法弊端是程序员在编写程序时不能确切知道设备完成任务所需的时间,也就是说需要定时去查询设备的状态。我们知道,现代CPU一般频率很高,如果去频繁查询外部设备,尤其是低速设备,必将浪费很多的CPU资源;如果查询的时间间隔长,那么外设的利用率就不高。有一种解决办法,那就是外设处理完任务,主动告诉CPU,从而省去了CPU的查询开销。
中断的第二个用途是,可以维护系统正常运行。现代的操作系统都是多任务系统,表面看起来多个程序在并行,实际上真正的CPU是分时复用的(假设最简单的单核单线程),并不是真的并行。如果这时有一个恶意程序,一直霸占CPU资源不释放,是不是整个系统就会挂死呢?答案是并不会,因为CPU的分配是由操作系统负责完成的,原理就是通过中断把控制权从程序手中交还给操作系统。另外,CPU访问内存或其它设备时,也可能发生一些错误。对于不同错误有不同的处理方式,也可以通过中断来完成。
对于一些特定的应用场景,设备系统需要满足实时性。所谓实时性,就是要求系统在规定的或者可预期的时间内作出反应。此类需求也可以通过中断来满足。
还记得前面讲ARM异常时的概念吗?中断算一种异步异常,《ARM系列 – 异常和特权》。A系列处理器提供四个管脚来实现中断,分别是:
nIRQ:物理普通中断
nFIQ:物理快速中断
nVIRQ:虚拟普通中断
nVFIQ:虚拟快速中断
如下图所示:
其中虚拟中断是为了实现虚拟化而准备的,这部分留待以后讲虚拟化时再说。我们只看物理中断。
在开始介绍中断概念时,我们说中断可能会有很多种,每个设备都可能要发中断,而ARM处理器只有两个管脚,那怎么办?这时,就需要有一个模块来收集所有的中断,然后转发给处理器。 在ARM的体系中,这个模块就是通用中断处理器(generic interrupt controller,以下简称GIC)。
类似ARM的处理器,GIC有架构和实现之分。GIC的架构经历了GICv1,GICv2,GICv3和GICv4。每个架构下有有对应的设计实现,比如GIC-600就是支持GICv3架构的最新IP。
在介绍GIC-600之前,有必要先讲一下中断的一些基本概念。 首先,中断是分优先级的。很多个设备同时发送中断,处理器必须遵守一定的规则来给所有中断排序,从而决定先响应哪个。这个规则就是中断优先级,操作系统需要维护中断处理器中的优先级寄存器。既然有了优先级,就有了中断嵌套。当处理器处理某个低优先级的中断时,来了一个高优先级的中断,CPU可以保留低优先级的中断处理现场,转而处理高优先级中断,待高优先级处理完再继续处理低优先级中断。如果CPU在某段时间内,选择不响应某设备,其中断也可以被屏蔽。
在ARM体系中,对于每个中断,有四个状态:
inactive:中断处于无效状态
pending:中断处于有效状态,但是CPU没有响应该中断
active:中断处于有效状态,CPU在响应该中断
active and pending:CPU在响应该中断,但是该中断源又发送中断过来
在ARM体系中,中断分为以下几个类型(不讨论虚拟中断):
PPI:(Private Peripheral Interrupt,私有外设中断),该中断来源于core,但是该中断只对指定的core有效,所谓的私有即指对core私有;
SPI:(Shared Peripheral Interrupt,共享外设中断),该中断来源于外部设备,该中断可以对所有的core有效;
SGI:(Software Generated Interrupt,软件中断),用于给其它的core发送中断信号;
LPI:(Locality-specific Peripheral Interrupt,特定局部外设中断),是一种基于消息的边沿中断。
ARM又为每种中断分配了中断号,用以区分,其中1020-1023是特殊的中断号。
图1 GICv3中断号分配
对于每个中断,从产生到处理再到结束,是有一个完整的生命周期的。
图2 物理中断生命周期
generate:外设或软件发起一个中断
distribute:中断经过分组,优先级仲裁等,发送给对应的CPU interface
deliver:CPU interface将中断发送给core
activate:当CPU core开始响应中断,GIC将最高激活优先级的中断设置为激活
priority drop: core发信号给GIC,通知最高优先级中断,GIC可以重置优先级
deactivation:清除中断
这里要解释一下CPU interface。前面也提到了,core提供给中断的物理管脚只有两个,中断会有成百上千个,GIC怎么把这些中断发送给core是一个问题。这时就需要CPU interface了。CPU interface将GIC发送的中断信息,通过IRQ,FIQ管脚,发送给连接到core。CPU interface提供了以下的功能:
将中断请求发送给core
中断进行认可
中断完成识别
设置中断优先级屏蔽
定义中断抢占策略
决定当前处于pending状态最高优先级中断
在GICv3架构中,CPU interface被抽离出来,实现在core内部的。也就是说,在GIC-600中,是不包含CPU interface的。这样做的好处是,可以减少中断响应的时间,并且减少系统总线的占用。对于众核SoC设计来说,其物理设计非常大,CPU interface实现在core内部,也就意味着某些中断寄存器可以放在其内部,这样core就可以很快的访问到这些寄存器了。对于那些常用的寄存器,core不用跋山涉水的通过系统总线或片上网络去频繁访问GIC了。CPU interface与GIC之间,是通过专用的AXI-stream总线来传输信息的。
今天就到这里吧,下周开始详细GIC-600的内部结构。
原文地址:https://mp.weixin.qq.com/s/V-feDdiHG8GV2KTMKeEPPA