分类: Android平台
2015-03-23 16:21:52
中断控制器
目录:
一、综述:
二、中断的分类:
三、GIC的主要构造:
四、中断编程:
五、编程要点:
一、综述:
中断是一种系统资源,中断控制器就是用来集中管理这种资源的。
中断控制器提供管理中断资源,中断行为,中断路由的接口——寄存器。
二、中断的分类:
4412的中断控制器支持:
1)ARM 架构的安全扩展
2)3种中断类型:SPI 、SGI 、PPI。
对于1) 中,支持安全扩展的机器,发送给处理器的中断又被分为两种类型,安全中断是FIQ或者IRQ(可通过ICCICR 寄存器的The FIQEn bit 来配置),非安全中断则只能是IRQ。
对2)中SPI 和PPI 属于外部中断,其中,PPI为每个core的私有外设中断,SPI为各个core公用的中断,第一S 是share的意思,第一P是private的意思。SGI为软件可以触发的中断,经常用于各个core之间的通信。触发SGI的寄存器是ICDSGIR。
三、GIC的主要构造:
如下图:
包含了如下几个主要部分:
1)AMBA Slave Interfaces
AMBA是系统总线,有了AMBA接口你才能访问distributor的寄存器。
2)Distributor
顾名思义仲裁器咯,由Distributor截获的中断,经过仲裁之后,满足要求(比如优先级,传递权限等)才会发送到CPU接口,这里要注意一个概念是:Distributor Interface 和 CPU interface ,他们是GIC 里面最主要的两部分。
3)CPU Interface
CPU interface 包含一个可配置(编程)的中断屏蔽码(参考寄存器ICCPMR)。
CPU interface 接受Distributor Interface 传递过来的处于 pending 状态的中断的条件是,当前中断的优先级:
(1)大于该CPU 的中断屏蔽码。
(2)大于该CPU 正在处理的中断。
很显然,第二点涉及到中断嵌套。
4)Clock and Reset
Gic的时钟和复位pin 。
四、中断编程:
1,主要寄存器介绍:
4412中断控制器可以编程控制一个中断如下五个属性:
1)一个中断的安全状态,寄存器是ICDISR
2)一个中断的优先级,寄存器是ICDIPR
3)使能或者禁止一个中断,寄存器是ICDISER
4)一个中断发给哪个或者哪几个CPU,寄存器是ICDIPTR
5)一个中断的触发方式(边沿触发或者电平触发),寄存器是ICDICFR
当然,上面几点都对于单个中断而言的,对于整个中断系统而言,还有很多总控制的寄存器,比如ICDDCR是控制中断是否传递给CPU 接口的,还有只读寄存器ICDICTR,它包含了该GIC 的一些属性。
还有一些属于CPU interface 的寄存器,比如ICCICR 是控制CPU 接口是否使能的,ICCPMR是设置某一个CPU的中断屏蔽码的值的。
具体参考datasheet 的Register Description 。
2,带安全扩展的初始化流程:
参考中断控制器文档DDI0416B_gic_pl390_r0p0_trm P70
这里一定要注意的一点是,在最后enable的时候,在secure world enable了还不算,还要切换到normal world 来enable ,这样normal world才能接收到normal 中断。具体编程代码可以参考我提供的一份源码,这里面有实现一个SGI中断的完整配置。
五、编程要点:
1,首先是异常向量表的设置:
\trustzone\tzone_sdk\otzone\src\arch\arm\armv7\cpu_entry.S
代码如下:
__start_secure_core:
@ Set VBAR
ldr r1, =secure_exception_vectors @ Load base address into r0
mcr p15, 0, r1, c12, c0, 0 @ Write Current world VBA
@ Install monitor
LDR r1, =monitor @ Get address of Monitor s vector table
MCR p15, 0, r1, c12, c0, 1 @ Write Monitor Vector Base Address Register
上面代码实现了monitor 和 secure 模式的异常向量表的装载。
ARM 最新架构实际上支持4个运行模式,除了上述两个外还有,Hyp 和 non_secure 模式如下图:
参见ARM 架构文档:DDI0406C_C_arm_architecture_reference_manual.pdf P1167
关于一场向量表的地址可以参考同上文档的P1165
B1.8.1 Exception vectors and the exception base address
实际上关于异常向量表的地址支持两种情况:
1)支持安全扩展(要用到三个异常向量表)
2)支持虚拟化扩展(要用到四个异常向量表)
2,异常路由路径:
参考同上文档,P1181 ,以FIQ为例子,如下图所示:
这张图很好的展现了在ARM架构下支持各种扩展,异常路由的路径。其中各种系统控制寄存器的相应位起到了指路的作用,比如SCTLR 和SCR等。
3,在UBOOT 启动地址:
一台使用ARM 处理器的机器,在关闭状态下,当我们按下power键的时候,首先会给PMU按照一定的时序上电,上电的时序是芯片厂商事先掩膜好的,当必要的各个电路上电完毕,PMU 会reset 我们的CPU,然后CPU 开始执行代码。如果你机器是多核的,那么除了CPU0 外,其他CPU 会处于WFI(Wait for interrupt)或WFE(Wait for event)状态。CPU0 执行的第一条指令从0地址还是FFFF0000地址开始,取决于SCTLR(System Control Register)寄存器的V 位,默认状况下从0地址启动。
参考uboot代码:arch/arm/cpu/armv7/start.S 可以知道0地址放了异常向量表的第一个指令:
b reset
然后就开始从reset 执行。
要注意的是,在这里有个从CPSR关闭FIQ和IRQ的动作,所以,如果你要在UBOOT 实现中断调试的话,请记得把他们重新打开。
4, 如何在uboot 把一个GPIO配置成中断:
1)首先在底板原理图上选定一个pin 脚:
这里我们选中XEINT12。
2)在核心板原理图上找出XEINT12是从哪里接出来的:
可以看到其对应GPX1_4,这个GPIO 。
3)在datasheet 上找到这个gpio ,并把它配置成中断模式:
当然,GPIO 还可以配置其他信息,不细讲了。
4)配置EXT_INT41[4]的中断触发模式:
5)最后,你得打开EXT_INT41[4]的中断屏蔽位:
OK,如果你的中断控制器已经初始化好了,那么这个GPIO 中断也就可以使用了。