在Cortex-R52:GIC里我们简述了GIC相关配置寄存器和中断类型,接下来聊一聊SGI、SPI、PPI的配置方法。
根据R52 TRM中的描述,一个中断有INTID表示,且一个中断相关设置如下:
- 使能:只有使能的中断才会送到核里;但是没有使能的中断如果发生了会被pending住;
- 优先级:5bit优先级配置,值越小,优先级越高
- 中断触发行为:电平触发 or 边沿触发
- 设置Group:IRQ or FIQ
- 设置路由目标:目标core或者cores
一、SPI、PPI和SGI中断的配置
1.1 配置项
Setting | SPIs | SGIs & PPIs |
Enable | GICD_ISENABLERn GICD_ICENABLERn | GICR_ISENABLERn GICR_ICENABLERn |
Priority | GICD_IPRIORITYn | GICR_IPRIORITYn |
Configuration (level or edge) | GICD_ICFGRn | GICR_ICFGRn |
Group | GICD_IGROUPn | GICR_IGROUPn |
Routing (target core/cores) | GICD_IROUTERn | N/A |
PPI不需要配置Route,因为本身就是核私有的
1.2 代码示例
if(INT_IS_SPI(intID))
{
REG32_WRITE(gicd_base_addr, gicd_isenabler_offset_x, enable_mask)
REG32_WRITE(gicd_base_addr, gicd_irouter_offset_x, affinity_mask)
REG8_WRITE (gicd_base_addr, gicd_ipriorityr_offset_x, prio_mask)
REG32_WRITE(gicd_base_addr, gicd_icfgr_offset_x, cfg_mask)
}
else
{
REG32_WRITE(gicr_base_addr, gicr_isenabler0/1, enable_mask)
REG8_WRITE (gicr_base_addr, gicr_ipriorityr0/1, prio_mask)
if(INT_IS_PPI(intID))
{
REG32_WRITE(gicr_base_addr, gicr_icfgr1, cfg_mask)
}
}
这里要提出来解释的是router寄存器IROUTER32-991。该寄存器位域结构如下:
对于R52来说,Aff3 只读为0,Aff2/1根据芯片设计时的配置也是固定死了,实际上对于单核簇的R52来说,Aff2、1基本上也就是0;那么唯一可以改变的就只有Aff0,该位域详细解释如下:
那么这个值从哪里来呢?MPIDR(详见Cortex-R52:affinity)
也就是说,现在我想把一个SPI路由到核2,那么肯定要先获取该核的affnity0(通过MPIDR),然后写到该寄存器里。并且,注意,该寄存器是64bit的。
二、注意事项
2.1 GIC模块的初始化
GIC由三个模块构成,因此这三个模块也是要进行初始化的
模块 | 寄存器操作 | 解释 |
Distributor | 1、GICD_CTRL.EnableGrp0/1 设置 1 2、GICD_CTRL.ARE不用设置(默认使能,RAO/WI(Read as one、write ignore)) | 默认值为0,使能IRQ和FIQ的group; 亲和度路由默认开启 |
Redistributor | GICR_WAKER.ProcessorSleep 设置 0 告诉相连的core,我要醒了 | 默认值为1; 软件必须轮询ChildrenAsleep状态为0才能跳转; 配置CPU interface之前必须完成这个操作 |
CPU interface | 1、检查ICC_SRE.SRE是否为1(RAO/WI) 2、ICC_IGRPEN0/1 3、ICC_PMR.Priority 设置优先级mask 4、ICC_BRPn设置抢占策略 | 1、硬件默认为1 2、设置Group0、1使能 3、配置送入到cpu的优先级mask,一般默认FF |
2.2 中断配置总结
中断类型 | 配置项 |
SPI(32-991) | 1、优先级: GICD_IPRIORITYRn 2、中断Group GICD_IGROUPRn 3、触发类型 GICD_ICFGRn 4、路由目的 GICD_IROUTERn 5、中断使能 GICD_ISENABLERn |
PPI(16-31) & SGI(0-15) | 1、优先级 GICR_IRPIORITYRn(n= 0-7) 2、中断Group GICR_IGROUPR0 3、触发类型 GICR_ICFGR0/1 4、中断使能 GICR_ISENABLER0 |