【GIC】配置GIC

本章介绍如何在裸机环境中启用和配置兼容GICv3的中断控制器。


目录

一、全局设置

二、单独PE设置

2.1 Redistributor配置

2.2 CPU接口配置

2.3 PE配置

三、SPI, PPI, SGI配置

3.1设置SPI的目标PE

附:寄存器介绍

附1:GICD_CTLR

附2:GICR_WAKER

附3:ICC_SRE_ELn

附4:ICC_PMR_EL1

附5:ICC_BPRn_EL1

 附6:ICC_CTLR_EL1

附7:GICR_CTLR


一、全局设置

必须将 Distributor控制寄存器(GICD_CTLR)配置为启用中断组并设置路由模式。

  • 使能亲和性路由 (ARE bits)

GICD_CTLR中的ARE位控制是否启用亲和路由。如果未启用亲和路由,则可用传统操作配置GICv3。对于安全状态和非安全状态,可以分别控制是否启用关联路由。

  • 中断使能·

对于Group 0, Secure Group 1 and Non-secure Group 1,GICD_CTLR有单独的使能位bit:

GICD_CTLR.EnableGrp1S   允许分发Secure Group 1中断。

GICD_CTLR.EnableGrp1NS 允许分发Non-secure Group 1中断。

GICD_CTLR.EnableGrp0   允许分发Group 0中断。

二、单独PE设置

2.1 Redistributor配置

        复位时,Redistributor将其连接的PE视为睡眠状态。唤醒过程可以通过GICR_WAKER进行控制。要将已连接的PE标记为awake状态,软件必须:

  1. 清除GICR_WAKER .ProcessorSleep为0。·
  2. 轮询GICR_WAKER .ChildrenAsleep,直到读取到0。

        写入CPU接口寄存器,除了ICC_SRE_ELn,当任何一个GICR_WAKER.ProcessorSleep==1 或者 GICR_WAKR.ChildrenAsleep==1都会导致不可预测的行为。

2.2 CPU接口配置

CPU接口负责将中断传递到它所连接到的PE。要启用CPU接口,软件必须配置以下内容:

  • 启用系统寄存器访问权限。

软件必须通过在ICC_SRE_ELn寄存器中设置SRE位来启用对CPU接口寄存器的访问。·

  • 设置优先级掩码和二进制点寄存器。

CPU接口包含优先级掩码寄存器(ICC_PMR_EL1)和二进制点寄存器(ICC_BPRn_EL1)。优先级掩码设置中断必须被转发到PE的最小优先级。二进制点寄存器用于优先级分组和抢占。·

  • 设置EOI模式。

CPU接口中的ICC_CTLR_EL1和ICC_CTLR_EL3中的EOImode位控制着如何处理中断的完成。

  • 启用每个中断组的信号。

      必须在中断由CPU接口转发到PE之前使能每个中断组的信号。要启用信号软件必须写入ICC_IGRPEN1_EL1用于Group 1中断,写入ICC_IGRPEN0_EL1用于Group0中断。

ICC_IGRPEN1_EL1由安全状态备份。这意味着ICC_GRPEN1_EL1控制当前安全状态的Group 1。在EL3,软件可以使用ICC_IGRPEN1_EL3访问安全Group1中断和非安全Group 1中断。

2.3 PE配置

        还需要对PE进行一些配置来允许它接收和处理中断。在这里,只描述在AArch64状态下执行ARMv8-A兼容PE所需的基本步骤就足够了。

  • 路由控制

        中断的路由控制位于PE的SCR_EL3和HCR_EL2中。路由控制位决定了进行中断的异常级别。这些寄存器中的路由位在复位时是一个未知值,因此它们必须由软件进行初始化。·

  • 中断掩码

        PE在PSTATE中也有异常掩码位。当设置了这些位时,中断将做掩码处理。这些位在复位时被设置。·

  • 向量表

        PE的向量表的位置由VBAR_ELn寄存器设置。与SCR_EL3和HCR_EL2一样,VBAR_ELn寄存器在复位时是一个未知值。软件必须将VBAR_ELn寄存器设置为指向内存中适当的向量表。

更多信息,请查阅 ARM® Architecture Reference Manual, ARMv8, for ARMv8-A architecture profile。

三、SPI, PPI, SGI配置

        SPI通过Distributor使用GICD_*寄存器进行配置。PPIs和SGIs是通过各个Redistributor,使用GICR_*寄存器进行配置的。对于每个INTID,软件必须配置以下内容:

  • 优先级Priority (GICD_IPRIORITYn, GICR_IPRIORITYn)

        每个INTID都有一个关联的优先级,用一个8位的无符号值表示。0x00优先级最高,0xFF优先级最低。第五章描述了GICD_IPRIORITYn和GICR_IPRIORITYn中的优先级值如何屏蔽低优先级中断,以及它如何控制抢占。中断控制器不需要实现所有的8bit优先级。如果GIC支持两个安全状态,则必须至少实现5位。如果GIC只支持一个安全状态,则必须至少实现4位。

  • 中断分组Group (GICD_IGROUPn,GICD_IGRPMODn, GICR_IGROUP0, GICR_IGRPMOD0)

        一个中断可以被配置为属于三个不同的中断组中的一个。

        这些中断组分别是 Group 0,Secure Group 1,Non-secure Group 1。

  • 触发方式Edge-triggered/level-sensitive (GICD_ICFGRn, GICR_ICFGRn)

        如果中断作为物理信号发送,则必须将其配置为边缘触发或电平敏感。SGIs总是被视为边缘触发的,因此GICR_ICFGR0对于这些中断表现为RAO/WI。

  • 中断使能Enable (GICD_ISENABLERn, GICD_ICENABLER, GICR_ISENABLER0, GICR_ICENABLER0)

        每个INTID都有一个使能位。设置启用寄存器和清除启用寄存器删除了执行 read-modify-write例程的要求。

        ARM建议,在启用INTID之前,先配置上述的设置。

        对于裸机环境,在初始配置后通常无需更改设置。但是,如果必须重新配置一个中断,例如要更改组设置,则建议首先禁用该特定的INTID。大多数配置寄存器的复位值都由具体实现者定义。这意味着中断控制器的设计者决定值是什么,并且值可能在系统之间有所不同。

3.1设置SPI的目标PE

        对于SPI,必须额外配置中断的目标。这是由GICD_IROUTERn控制的。每个SPI都有一个GICD_IROUTERn寄存器,中断路由模式位控制路由策略。选项包括:

  • GICD_IROUTERn.Interrupt_Routing_Mode == 0

SPI将被交付给PE  A.B.C.D,即在寄存器中指定的亲和坐标。

  • GICD_IROUTERn.Interrupt_Routing_Mode == 1

SPI可以传递给参与中断组分配的任何已连接的PE。Distributor选择目标PE,

而不是软件;这可以在每次中断信号时发生变化。这种类型的路由称为1-of-N。

PE可以选择不接收1-of-N中断。这是由GICR_CTLR中的DPG1S、DPG1NS和DPG0位控制的。

附:寄存器介绍

附1:GICD_CTLR

启用中断和亲和关系路由。

【GIC】配置GIC_第1张图片

附2:GICR_WAKER

        允许软件控制与 Redistributor对应的WakeRequest电源管理信号的行为。

        如果PE进入了/正在进入低功耗状态时,所有中断进到Redistributor后,都会①产生一个WakeRequest信号②在Redistributor处于待定状态,未与CPU接口通信。

【GIC】配置GIC_第2张图片

附3:ICC_SRE_ELn

        控制ELn是否使用系统寄存器接口或到GIC CPU接口的内存映射接口。

【GIC】配置GIC_第3张图片

附4:ICC_PMR_EL1

        提供一个中断优先级过滤器。只有优先级高于此寄存器中的值的中断才会向PE发出信号。写入此寄存器必须是高性能的,并且必须确保在写入之后不会发生优先级低于写入值的中断,而不需要ISB或异常边界。

【GIC】配置GIC_第4张图片

附5:ICC_BPRn_EL1

ICC_BPRn_EL1其实就是将优先级分为了两级,前面作为group,用于抢占。

【GIC】配置GIC_第5张图片

 附6:ICC_CTLR_EL1

【GIC】配置GIC_第6张图片

EOImode:针对当前安全状态的EOI模式。控制是否对结束中断寄存器的写入,也会停用该中断;

【GIC】配置GIC_第7张图片

附7:GICR_CTLR

【GIC】配置GIC_第8张图片

你可能感兴趣的:(ARM,嵌入式硬件,GIC,ARM)