ATF:givc3的中断初始化配置流程

前言

前段时间不是在整gicv2吗?这个确实太老了。资料很少,但是gicv3的蛮多的,这里找到了一篇关于gicv3的中断的blog,我们一起来学习一下,相信通过前辈的文章一定有所收获,核心内存的内容链接我放在了文末。

ATF在bl31中提供了GICv3驱动加载bl31的中断处理异常等级切换时中断路由信息配置以及GICv3相关的电源管理功能,由于电源管理功能与中断处理流程关联不大,在本文中不做详细分析。下图为bl31中gic驱动和中断处理流程架构,其中平台相关部分代码都以arm common plat为例,如bl31 platform setup和gicv3 init是与平台相关的

  • GICv3驱动加载流程主要实现了distributor、redistributor和cpu interface 三大组件相关资源的初始化,所有SPI、PPI和SGI中断属性的默认参数设置,以及需要在bl31中注册的中断属性设置等功能

  • Bl31的中断处理实现了对路由到EL3的中断相关异常处理流程

  • 异常等级切换时bl31 负责设置cpu系统寄存器以配合GICv3实现将不同group的中断路由到正确的异常等级。(那么在gicv3he gicv2的切换适配的时候,其实我只需要修改这个部分,其他的应该都是common的。)

下面来分开讲讲ATF中bl31这三件事

二、GICv3驱动加载流程

GICv3驱动加载流程由bl31启动流程调用,主要包含两部分,GIC驱动初始化GIC初始化

1-GIC驱动初始化(关于硬件的初始化)

与上节相同,在代码分析中涉及到平台相关的代码时,统一都以arm common plat为例,如下面的arm_bl31_setup.c和arm_gicv3.c。其中GIC驱动初始化流程如下:
在这里插入图片描述

其主要功能为解析GIC版本支持的特性,以及初始化redistributor的寄存器基地址。以下为其详细流程:

  • (1)输入参数校验

    扫描二维码关注公众号,回复: 14707401 查看本文章
  • (2)从distributor的pidr2寄存器读取GIC版本信息,若其为GICv4,则从typer寄存器中读取其是否支持直接注入LPI能力

  • (3)读取distributor的控制寄存器,并解析相关字段判断其是否兼容GICv2 版本

  • (4)初始化并填充CPU的redistributor寄存器基地址

2-GIC初始化(关于中断的初始化)

GIC初始化包含了distributor、redistributor以及cpu interface的初始化。

包括初始化系统中所有中断的默认配置,在GICv3中设置BL31中已注册中断的中断属性等。其中distributor和其所管理的SPI中断配置流程如下:

1-distributor和所管理的SPI中断配置流程

在这里插入图片描述

  • (1)gicd_clr_ctlr:清除所有的中断group的使能位
      gicd_set_ctlr:设置secure和non secure空间的ARE位,以使能中断的affinity路由功能

  • (2)gicv3_spis_config_defaults:将所有的spi中断属性配置为默认值。它包括:
      gicv3_get_spi_limit:获取系统支持的最大spi中断数量
      gicd_write_igroupr:将中断初始化为non secure group 1类型
      gicd_write_ipriorityr:将中断优先级初始化为默认值
      gicd_write_icfgr:将中断触发方式初始化为电平触发

  • (3)gicv3_secure_spis_config_props:设置bl31中已配置中断的实际属性。其中已配置中断从gicv3_driver_data->interrupt_props中获取,它是由每个plat定义并在初始化时通过arm_bl31_platform_setup以结构体指针方式传给gic驱动的。因此,平台需要将bl31中的所有中断都写入interrupt_props结构中。以下为其属性设置流程:
      gicd_clr_igroupr:将该中断设置为secure中断
      gicd_set_igrpmodr/gicd_clr_igrpmodr:将该中断设置为group 0或secure group 1
      gicd_set_icfgr:设置该中断实际的触发方式
      gicd_set_ipriorityr:设置该中断的优先级
      gicd_write_irouter:将该中断设置为路由到primary cpu
      gicd_set_isenabler:使能该中断

  • (4)gicd_set_ctlr:使能该中断对应的group

2-Redistributor主要用于初始化sgi和ppi中断的配置

Redistributor主要用于初始化sgi和ppi中断的配置。其初始化流程与distributor类似,也是先将所有中断配置初始化为默认值,然后读取平台已设置的bl31中的sgi和ppi中断信息,并将其配置到gicv3中。其主要流程如下,具体流程细节不再赘述:
  在这里插入图片描述

3-CPU interface的初始化流程

CPU interface的初始化流程如下:

在这里插入图片描述

  • (1)gicv3_rdistif_mark_core_awake:设置redistributor的电源管理接口,将其设置为wake状态。其包括以下流程:
      gicr_read_waker:读取并校验gicr_waker的children asleep位
      gicr_write_waker:清除gicr_waker的processorsleep位,以将接口设置为唤醒状态。
      gicr_read_waker:轮询读取gicr_waker的children asleep位,以确保设置结果已生效。

  • (2)write_icc_sre_el3:关闭irq、fiq bypass特性,以及寄存器映射和访问权限的设置
    read_scr_el3和write_scr_el3:通过SCR寄存器的secure控制bit,将当前系统状态切换为non secure状态,以设置下面的non secure寄存器
      write_icc_sre_el2和write_icc_sre_el1:设置non secure状态下el2和el1的sre寄存器,其寄存器定义与icc_sre_el3相同
      write_scr_el3:将当前系统状态切换回secure状态
      write_icc_sre_el1:设置secure状态下el1的sre寄存器
      write_icc_pmr_el1:初始化优先级mask值,该值用于mask掉一些低优先级的中断,只有当优先级高于该设定值的中断会被发送给PE。因此此处将其设置为最低中断优先级,即所有的中断都不会被mask
      write_icc_igrpen0_el1:使能group 0中断
      write_icc_igrpen1_el3:使能secure group 1中断

至此,bl31中的GIC初始化和中断配置已完成,此后若已配置完成的group 0和secure group 1中断发生后,GICv3将会处理并向合适的CPU发送中断信号。

(感叹一句前辈写的真的很详细)

https://zhuanlan.zhihu.com/p/520161285

猜你喜欢

转载自blog.csdn.net/weixin_45264425/article/details/129477105