GIC通用中断寄存器
GIC(Generic Interrupt Controller,通用中断控制器) 是 ARM 处理器中用于管理中断的硬件模块,负责接收、优先级排序和分发中断信号到 CPU 核心。


MRC MCR
MRC 和 MCR 是 ARM 指令集中用于访问协处理器的指令,是 ARM 系统编程中最核心的指令之一。
MRC = 读协处理器(协处理器 → ARM 寄存器)
MCR = 写协处理器(ARM 寄存器 → 协处理器)
基本语法
MRC{条件} p<编号>, <op1>, <Rd>, <CRn>, <CRm>, <op2>
MCR{条件} p<编号>, <op1>, <Rd>, <CRn>, <CRm>, <op2>
参数解释
MRC/MCR p<编号>, <op1>, <Rd>, <CRn>, <CRm>, <op2>
│ │ │ │ │ │
│ │ │ │ │ └── 操作码2 (0-7)
│ │ │ │ └── 协处理器寄存器 (0-15)
│ │ │ └── 主寄存器 (0-15)
│ │ └── ARM 寄存器 (R0-R15)
│ └── 操作码1 (0-7)
└── 协处理器编号 (0-15)
SCTLR寄存器
SCTLR(System Control Register,系统控制寄存器) 是 ARM CP15 协处理器中最重要的寄存器之一,它控制着处理器的核心系统功能,包括 MMU、Cache、内存对齐、指令集等。
使能指令缓存
_enable_icache
mrc p15,0,r0,c1,c0,0
bic r0,r0,#(1<<13)
orr r0,r0,#(1<<12)
mcr p15,0,r0,c1,c0,0
bx lr
首先读取sctlr数据到r0,清除13位用于禁用高向量表,大部分嵌入式系统向量表放在低地址,12位置1用于打开指令缓存,最后将修改的值写回sctlr
VBAR寄存器
VBAR(Vector Base Address Register,向量表基址寄存器) 是 ARMv7-A 架构引入的寄存器,用于指定异常向量表在内存中的位置。
设置异常向量表基址
_set_vbar
ldr r0,=0x87000000
mcr p15,0,r0,c12,c0,0
bx lr
先加载向量表地址,然后设置VBAR,告诉 CPU 向量表在0x87000000

CBAR配置基址寄存器
CBAR 是 Configuration Base Address Register(配置基址寄存器)的缩写。它的作用是为软件提供GIC(通用中断控制器)寄存器区域的物理基地址
irq中断处理
_irq_handler:
subs lr,lr,#4
//GIC基地址
mrc p15,4,r1,c15,c0,0
add r1,r1,#0x2000
ldr r0,[r1,#0x0C]
stmfd sp!,{r0-r12,lr}
stmfd sp!,{r0,r1}
cps #0x1F //切换到system模式
stmfd sp!,{lr}
bl system_interrupt_handler
ldmfd sp!,{lr}
cps #0x12 //切换到irq模式
ldmfd sp!,{r0,r1}
str r0,[r1,#0x10] //清中断标志
ldmfd sp!,{r0-r12,pc}^
首先修正返回地址,通过协处理器cp15,读取 CBAR 寄存器,获取 GIC 的基地址到r1,给r1一个CPU接口基地址,偏移0x0C到GICC_IAR(中断确认寄存器),获取当前挂起的最高优先级中断编号,读到r0.
先保存所有寄存器,此时仍为irq模式,然后单独保存一下r0和r1的状态,切换到system模式,保存system的lr,然后调用c函数,此时可以进行中断嵌套,后面进行一系列恢复操作,最后要把中断号写回EOIR寄存器,告诉GIC本次中断已经执行完毕,可以执行下一个中断
注意在外设部分,需要给中断状态寄存器ISR的18位写1清0
arm启动代码整体流程
上电复位,触发_reset_handler,进入irq模式,设置irq的栈,切换system模式,设置system的栈,使能所有外设时钟,点灯。
中断流程
以key按键为例
首先配置外设,配置引脚的复用功能,电气属性,输入方向,配置中断触发方式,中断优先级,使能GPIO1_18引脚中断
配置GIC,第一步初始化GIC,使能GPIO1_18引脚中断,设置优先级,GIC通过IRQ将中断送往内核
配置内核,使能irq中断,切换工作模式irq,通过pc跳转到irq处理函数进行处理
qs
1.什么是GIC
GIC是通用中断控制器,位于外设和CPU之间,用于接收外设的中断信号,按优先级排序仲裁,分配中断给CPU。IMX6ULL使用的是GIC-400,属于GIC V2版本,面向Cortex-A7这类32位处理器。
2.什么是协处理器?ARM Cortex-A7配备了几个协处理器?
协处理器是挂在内核旁边的辅助单元,用于拓展一些功能。ARM架构最大支持16个协处理器,cp0-cp15.Cortex-A7实际配备的协处理器有:cp10(VFP浮点运算控制)、cp11(VFP浮点运算数据,与cp10配对)、cp14(Debug调试控制)、cp15(系统控制,管理cache、MMU、中断等,是必须有的)。其余cp0-cp9视具体实现可选配。访问不存在的协处理器会触发未定义指令异常。
3:为什么要将异常向量表重映射?如何重映射?
ARM默认异常向量表在0x0000000,通电后这个地址容易被别的外设所占用,比如Boot ram,而且只读无法修改。重映射,通过cp15的VBAR寄存器,用指令将VBAR设为代码实际地址,之后异常发生时CPU跳转地址 = VBAR基址 + 异常类型偏移量,比如IRQ跳到VBAR+0x18。
4:GIC支持多少个中断,分为哪几类?
GIC-400理论最大支持1020个中断(编号0-1019),分三大类:SGI软件生成中断(编号0-15,共16个),由软件写寄存器触发,用于核间通信和多核调度;PPI私有外设中断(编号16-31,共16个),每个核有独立的一份,如核私有定时器;SPI共享外设中断(编号32-1019,共988个),来自片上外设(GPIO、UART、I2C等),所有核共用,可路由到任意核。
5:IMX6ULL支持多少个中断?
IMX6ULL实际实现了160个中断(编号0-159),虽然GIC-400理论上能管1020个,但NXP只用了前160个。其中SGI占16个(0-15)、PPI占16个(16-31)、SPI占128个(32-159)。