Cortex-A510——GIC
小狼@http://blog.youkuaiyun.com/xiaolangyangyang
1、中断类型
- SGIs:Software Generated Interrupt(0~15)
- PPI:Per-Processor Interrupt(16~31,1056~1119)
- SPI:Shared Phripheral Interrupt(32~1019,4096~5119)
- LPI:Locality-Specific Peripheral Interrupt(GIC-V3之后增加的Feature,8192~)
2、中断分组
中断分组的目的就是使不同Group的中断,在CPU不同状态下可分别被路由到IRQ或FIQ上,在AARCH32/AARCH64状态下,中断的路由方式如下:
有了IRQ和FIQ,其具体在CPU哪级异常执行,由SCR_EL3寄存器决定,如下所示:
3、FIQ与IRQ区别
1、对FIQ你必须进快处理中断请求,并离开这个模式;
2、IRQ可以被FIQ所中断,但FIQ不能被IRQ所中断,在处理FIQ时必须要关闭中断;
3、FIQ的优先级比IRQ高;
ARMv8里已经没有区别
4、FIQ模式下,比IRQ模式多了几个独立的寄存器;
ARMv8里IRQ/FIQ不会进行硬件压栈,所以在ARMv8里没区别。
5、FIQ的中断向量地址不同;
6、IRQ和FIQ的响应延迟有区别
IRQ会等待预取指令执行完毕
IRQ与FIQ的区别IRQ与FIQ的区别IRQ与FIQ的区别IRQ与FIQ的区别IRQ与FIQ的区别IRQ与FIQ的区别IRQ与FIQ的区别
【005 中断】IRQ和FIQ有什么区别,在CPU里面是是怎么做的?
4、中断亲和性
GICv3使用hierarchy来标识一个具体的core, 如下图是一个四层的结构(AArch64):
用<affinity level 3>.<affinity level 2>.<affinity level 1>.<affinity level 0>的形式组成一个PE的路由。每一个core的affnity值可以通过MPDIR_EL1寄存器获取,每一个affinity占用8bit。配置对应 core的MPIDR值,可以将中断路由到该core上。每个core,连接一个cpu interface,而cpu interface会连接gic中的一个redistributor。redistributor的标识和core的标识一样。
各个affinity的定义是根据SOC自己的定义,比如:
- <group of groups>. <group of processors>.<processor>.<core>
- <group of processors>.<processor>.<core>.<thread>
5、中断处理流程
物理中断生命周期
- generate:外设或软件发起一个中断;
- distribute:中断经过分组,优先级仲裁等,发送给对应的CPU Interface;
- deliver:CPU Interface将中断发送给core;
- activate:当CPU core开始响应中断,GIC将最高激活优先级的中断设置为激活;
- priority drop:core发信号给GIC,通知最高优先级中断,GIC可以重置优先级;
- deactivation:清除中断。
SPI中断检测流程
- 外设发起SPI中断,GIC检测到这个中断,并标记为Pending状态;
- Distributor对所有处于Pending状态的中断确定目标CPU;
- 对每个CPU,Distributor会从众多Pending状态的中断中,选择优先级高的发送到对应的Redistributor;
- Redistributor将中断发送到目标CPU的CPU Interface上;
- CPU Interface将满足要求的中断发送给CPU;
- CPU进入中断异常后,内核中断处理程序读取GICC_IAR寄存器来响应该中断,寄存器返回硬件中断号;
- CPU处理完中断服务后,通过写GICC_EOIR寄存器,来给GIC发送一个EOI完成信号。
PPI和SGI中断检测程序
- GIC检测到PPI或者SGI中断,并标记为Pending状态;
- Redistributor选择优先级高的中断发送到对应的CPU Interface上;
- CPU Interface将满足要求的中断发送给CPU;
- CPU进入中断异常后,内核中断处理程序读取GICC_IAR寄存器来响应该中断,寄存器返回硬件中断号;
- CPU处理完中断服务后,通过写GICC_EOIR寄存器,来给GIC发送一个EOI完成信号。
LPI中断检测流程
forwarding方式,由以下寄存器实现
- GICR_SERLPIR:将制定的LPI中断,设置为Pending状态;
- GICR_INVLPIR:将指定的LPI中断,清除Pending状态,寄存器内容和GICR_SERLPIR一致;
- GICR_INVLPIR:将缓存中,指定LPI的缓存给无效掉,使GIC重新从memory中载入LPI的配置;
- GICR_INVALLR:将缓存中,所有LPI的缓存给无效掉,是GIC重新从memory中载入LPI的配置;
- GICR_SYNCR:对Redistributor的操作是否完成。
6、主要寄存器配置
7、寄存器列表
A) 通过系统寄存器访问:
系统寄存器-ICC(物理CPU Interface系统寄存器)
ICC_AP0R<n>、ICC_AP1R<n>、ICC_ASGI1R、ICC_BPR0、ICC_BPR1、ICC_CTLR、ICC_DIR、ICC_EOIR0、ICC_EOIR1、ICC_HPPIR0、ICC_HPPIR1、ICC_HSRE、ICC_IAR0、ICC_IAR1、ICC_IGRPEN0、ICC_IGRPEN1、ICC_MCTLR、ICC_MGRPEN1、ICC_MSRE、ICC_PMR、ICC_RPR、ICC_SGI0R、ICC_SGI1R、ICC_SRE、ICC_AP0R<n>_EL1、ICC_AP1R<n>_EL1、ICC_ASGI1R_EL1、ICC_BPR0_EL1、ICC_BPR1_EL1、ICC_CTLR_EL1、ICC_CTLR_EL3、ICC_DIR_EL1、ICC_EOIR0_EL1、ICC_EOIR1_EL1、ICC_HPPIR0_EL1、ICC_HPPIR1_EL1、ICC_IAR0_EL1、ICC_IAR1_EL1、ICC_IGRPEN0_EL1、ICC_IGRPEN1_EL1、ICC_IGRPEN1_EL3、ICC_NMIAR1_EL1、ICC_PMR_EL1、ICC_RPR_EL1、ICC_SGI0R_EL1、ICC_SGI1R_EL1、ICC_SRE_EL1、ICC_SRE_EL2、ICC_SRE_EL3
系统寄存器-ICH(虚拟CPU Interface控制系统寄存器)
ICH_AP0R<n>、ICH_AP1R<n>、ICH_EISR、ICH_ELRSR、ICH_HCR、ICH_LR<n>、ICH_LRC<n>、ICH_MISR、ICH_VMCR、ICH_VTR、ICH_AP0R<n>_EL2、ICH_AP1R<n>_EL2、ICH_EISR_EL2、ICH_ELRSR_EL2、ICH_HCR_EL2、ICH_LR<n>_EL2、ICH_MISR_EL2、ICH_VMCR_EL2、ICH_VTR_EL2
系统寄存器-ICV(虚拟CPU Interface系统寄存器)
ICV_AP0R<n>、ICV_AP1R<n>、ICV_BPR0、ICV_BPR1、ICV_CTLR、ICV_DIR、ICV_EOIR0、ICV_EOIR1、ICV_HPPIR0、ICV_HPPIR1、ICV_IAR0、ICV_IAR1、ICV_IGRPEN0、ICV_IGRPEN1、ICV_PMR、ICV_RPR、ICV_AP0R<n>_EL1、ICV_AP1R<n>_EL1、ICV_BPR0_EL1、ICV_BPR1_EL1、ICV_CTLR_EL1、ICV_DIR_EL1、ICV_EOIR0_EL1、ICV_EOIR1_EL1、ICV_HPPIR0_EL1、ICV_HPPIR1_EL1、ICV_IAR0_EL1、ICV_IAR1_EL1、ICV_IGRPEN0_EL1、ICV_IGRPEN1_EL1、ICV_NMIAR1_EL1、ICV_PMR_EL1、ICV_RPR_EL1
B) Memory-Map寄存器:
GICD(Distributor寄存器)
GICD_CTLR、GICD_TYPER、GICD_IIDR、GICD_TYPER2、GICD_STATUSR、GICD_STATUSR、GICD_SETSPI_NSR、GICD_CLRSPI_NSR、GICD_SETSPI_SR、GICD_CLRSPI_SR、GICD_IGROUPR<0~31>、GICD_ISENABLER<0~31>、GICD_ICENABLER<0~31>、GICD_ISPENDR<0~31>、GICD_ICPENDR<0~31>、GICD_ISACTIVER<0~31>、GICD_ICACTIVER<0~31>、GICD_IPRIORITYR<0~255>、GICD_ICFGR<0~63>、GICD_IGRPMODR<0~31>、GICD_NSACR<0~63>、GICD_SGIR、GICD_CPENDSGIR<n>、GICD_SPENDSGIR<n>、GICD_INMIR<n>、GICD_IGROUPR<0~31>E、GICD_ISENABLER<0~31>E、GICD_ICENABLER<0~31>E、GICD_ISPENDR<0~31>E、GICD_ICPENDR<0~31>E、GICD_ISACTIVER<0~31>E、GICD_ICACTIVER<0~31>E、GICD_IPRIORITYR<0~255>E、GICD_ICFGR<0~63>E、GICD_IGRPMODR<0~31>E、GICD_NSACR<0~63>E、GICD_IROUTER<0~991>、GICD_IROUTER<0~1023>E、GICM_TYPER、GICM_SETSPI_NSR、GICM_CLRSPI_NSR、GICM_SETSPI_SR5、GICM_CLRSPI_SR、GICM_IIDR
GICR(Re-Distributor寄存器)
GICR_CTLR、GICR_IIDR、GICR_TYPER、GICR_STATUSR、GICR_STATUSR、GICR_WAKER、GICR_MPAMIDR、GICR_PARTIDR、GICR_SETLPIR、GICR_CLRLPIR、GICR_PROPBASER、GICR_PENDBASER、GICR_INVLPIR、GICR_INVALLR、GICR_SYNCR、GICR_IGROUPR0、GICR_IGROUPR<n>E、GICR_ISENABLER0、GICR_ISENABLER<n>E、GICR_ICENABLER0、GICR_ICENABLER<n>E、GICR_ISPENDR0、GICR_ISPENDR<n>E、GICR_ICPENDR0、GICR_ICPENDR<n>E、GICR_ISACTIVER0、GICR_ISACTIVER<n>E、GICR_ICACTIVER0、GICR_ICACTIVER<n>E、GICR_IPRIORITYR<n>E、GICR_IPRIORITYR<n>、GICR_ICFGR0、GICR_ICFGR<n>E、GICR_ICFGR1、GICR_IGRPMODR0、GICR_IGRPMODR<n>E、GICR_NSACR、GICR_INMIR0、GICR_INMIR<n>E、GICR_VPROPBASER、GICR_VPENDBASER、GICR_VSGIR、GICR_VSGIPENDR
GICC(CPU Interface寄存器)
GICC_CTLR、GICC_PMR、GICC_BPR、GICC_IAR、GICC_EOIR、GICC_RPR、GICC_HPPIR、GICC_ABPR、GICC_AIAR、GICC_AEOIR、GICC_AHPPIR、GICC_STATUSR、GICC_STATUSR、GICC_APR<n>、GICC_NSAPR<n>、GICC_IIDR、GICC_DIR
GICV(Virtual CPU Interface寄存器)
GICV_CTLR、GICV_PMR、GICV_BPR、GICV_IAR、GICV_EOIR、GICV_RPR、GICV_HPPIR、GICV_ABPR、GICV_AIAR、GICV_AEOIR、GICV_AHPPIR、GICV_STATUSR、GICV_APR<n>、GICV_IIDR、GICV_DIR
GICH(Virtual Interface控制寄存器,在Hypervisor模式访问)
GICH_HCR、GICH_VTR、GICH_VMCR、GICH_MISR、GICH_EISR、GICH_ELRSR、GICH_APR<n>、GICH_LR<n>
GITS(ITS寄存器)
GITS_CTLR、GITS_IIDR、GITS_TYPER、GITS_MPAMIDR、GITS_PARTIDR、GITS_MPIDR、GITS_STATUSR、GITS_UMSIR、GITS_CBASER、GITS_CWRITER、GITS_CREADR、GITS_BASER<n>、GITS_SGIR
GIC寄存器详解
一文搞懂GICv3中断控制器的工作原理
【ARMv8/v9 GIC 系列 1.4 -- GIC 中断分类 SGI | PPI | SPI 及中断检测流程】
【转】ARM GIC中断系列(三):gicv3架构基础