ARM中断处理之GIC

收藏一篇gic的文章 gic中断.
本章的主要内容如下:
Ø 中断处理(interrupthandling)主要描述
n GIC如何识别中断
n 软件如何通过编程GIC来配置和控制中断
n GIC处理任意CPU interface中断的状态机
n CPU的异常模式下如何与GIC交互
Ø 优先化(prioritization)
n 配置和控制每个中断的优先级
n 挂起中断的执行顺序
n 中断是否对目标CPU可见的决定因素:
u 中断优先级屏蔽
u 优先级分组
u 抢占当前activeinterrupt
3.1.1 多处理器(MP)系统中处理不同类型的中断
GIC支持外设中断(硬件中断)PI和SGI中断。在MP系统中的处理方式不同:SGI使用N-N模型,PI使用1-N模型。
3.1.2 识别GIC支持的中断
软件获取支持的中断信息:
Ø 读GICD_TYPERn。GICD_TYPER中的ITLinesNumber决定GICD_ISENABLERn的数目,因此决定了GIC支持的最大SPI的数目。所以,GIC支持的中断总数(ITLinesNumber+1)。
Ø 写0到GICD_CTLR禁止GICDistributor将中断传递给CPU interface。
Ø 对于GICD_ISENABLERn,从GICD_ISENABLE0开始。
n 写0xffffffff到GICD_ISENABLERn
n 然后读GICD_ISENABLERn,相应位为1代表支持该中断ID。

类似的软件也可以通过读取GICD_ICENABLEn来获取相应中断信息。
Ø 对于GICD_ICENABLERn,从GICD_ISENABLE0开始。
n 写0xffffffff到GICD_ICENABLERn,禁用所有中断。
n 然后读GICD_ISENABLERn,相应位为1表示中断被永久使能了。
n 写1到GICD_ISENABLERn,则相应位重新被使能。
3.2 通用中断处理
当GIC接收一个中断,将其状态置为pending。重新产生挂起中断不影响该中断状态。中断处理的顺序:

  1.  GIC决定该中断是否被使能,若没有被使能对GIC没有影响。 
    
  2.  对于每个pending中断,GIC决定目标处理器。 
    
  3.  对于每个处理器,Distributor根据他拥有的每个中断优先级信息决定最高优先级的挂起中断,将该中断传递给目标CPU interface。 
    
  4.  GIC Distributor将一个中断传递给CPUinterface后,该CPU interface决定该中断是否有足够的优先级将中断请求发送给CPU。
    
  5.  当CPU开始处理该异常中断,它读取GICC_IAR应答该中断。读取的GICC_IAR获取到中断ID,对于SGI,还有源处理器ID。中断ID被用来查找正确的中断处理函数。GIC识别读过程后,将改变该中断的状态: 
    

a) 如果该中断在pending状态时,产生了另一次中断,中断状态将从pending转化为pending &active。
b) 否则,中断状态将从pending变为active。
6. 当处理器完成中断处理后,它需要通知GIC处理已经完成。这个过程称为priority drop and interrupt deactivation:
a) 需要写EOIR(End of interrupt register)
b) 接着需要写GICC_DIR(deactivate interrupt register)
3.2.1 Priority drop and interruptdeactivation
Priority drop是降低当前中断优先级(runningpriority),这个动作发生在写EOIR后,即写GICC_EOIR或GICC_AEOIR。
Interruptdeactivation是改变中断状态:

  1.  从active & pending变为pending; 
    
  2.  从active变为idle。 
    

在GIC v2.0实现中,GICC_CTLR.EOImode为1表示这两个操作被分开执行。

3.2.2 GIC的中断控制
3.2.2.1 中断使能
对于一个外设中断(PI),一个处理器可以通过如下两种方法:
Ø 写1到GICD_ISENABLERn的相应位使能一个中断
Ø 写1到GICD_ICENABLERn的相应位禁用一个中断
对于一个SGI中断,是否永久使能或可以被上述的两个寄存器控制,这是有芯片实现决定的。
3.2.2.2 设置和清除中断挂起状态
对于外设中断,处理器可以通过如下方式控制:
Ø 写GICD_ISPENDRn设置中断pending状态;
Ø 写GICD_ICPENDRn清除中断pending状态。

对于一个电平触发的中断:
Ø 当硬件中断发出中断信号,且处理器已经GICD_ICPENDRn相应位,这个时候写GICD_ICPENDRn对该中断的挂起状态不会产生任何影响。
Ø 如果处理器对GICD_ISPENDRn的相应位写1,不管当前硬件的中断信号是否已经发出,都不会影响该中断的变化pending状态。
3.2.2.3 找到激活或挂起状态的中断
处理可以通过如下方法:
Ø 读GICD_ISPENDRn或GICD_ICPENDRn的相应位找到挂起状态的中断;
Ø 读GICD_ISACTIVERn或GICD_ICACTIVERn的相应位找到激活状态的中断。
当中断为挂起或者激活时,GICD_ISPENDRn或GICD_ISACTIVERn相应位为1;如果中断处于active& pending状态,那么这两个寄存器的相应位都为1.
3.2.2.4 产生SGI
处理器可以通过写GICD_SGIR来产生一个SGI。一个SGI可以传递给多个CPU,在GICD_SGIR寄存器中的CPUTargetList就可以指定目标处理器。
SGI可以是来自不同的处理器但使用了同一中断ID,因此,任意目标CPU可以接收来自不同CPU的使用同一个中断号的SGI。因此两个SGI只要有如下一项不同就是不同的:中断ID、源处理器和目标处理器。
当产生SGI,目标处理器读GIC的GICC_IAR返回中断号ID和源处理器。中断号ID和源处理器ID才能唯一的标识目标处理器。

3.2.5 特殊中断号
GIC保留中断号1020~1023,其中1023是伪中断号(SpuriousInterrupt)。
3.3 中断优先化
3.3.1 Preemption
在一个active中断被处理完之前,CPUinterface 支持通知更高优先级的中断到目标处理器。这种情况必要条件如下:
Ø 该中断的优先级高于当前CPUinterface被屏蔽优先级;
Ø 该中断的组优先级高于正在当前CPU interface处理的中断优先级
Preemption(抢占)发生在处理器应答这个新的中断时,开始为执行新中断的相应服务程序。原来的中断就被抢占,这种情况也称为中断嵌套。
3.3.2 Priority Masking(优先级屏蔽)
GICC_PMR定义了目标处理器的优先级阈值。GIC仅上报那些优先级高于这个阈值的pending中断。初始值为0,屏蔽所有的中断。
3.3.2 优先级分组(Priority grouping)
优先级分组是将GICC_BPR(Binary PointRegister)分为两个域,组优先级(group priority)和组内优先级(subpriority)。当决定抢占(Preemption)的时候,组优先级相同的中断被视为一样的,不考虑组内优先级。那就意味着在每个优先级组内只能有一个中断被激活。组优先级又被称为抢占级别(preemption level)。
GIC使用组优先级决定挂起中断是否有足够的优先级抢占当前active中断,原则如下:
Ø 如果发生抢占,该挂起中断的组优先级一定比当前active中断的组优先级高,也就是说,挂起中断的组优先级域的值小于active中断的组优先级域的值。
Ø 如果当前CPUinterface上没有active中断,最高优先级的挂起中断将被传递给处理器,而不考虑组优先级。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值