• GIC/ITS代码分析(9)中断应用实例之IPI中断


            PPI中断为外设私有中断,在ARM64上arch_timer为PPI中断。这里以arch_timer为例(代码位置drivers/clocksource/arm_arch_timer.c),作应用实例讲解。

            先对ARM64通用定时器作简要介绍。通用定时器为Arm core提供标准定时器。通用定时器包括一个系统counter和一组每core定时器。

            其中system counter处于always on的电源域,它提供固定频率的系统计数。它对系统上所有core都是广播的。每个core都有一组timer,它们与system counter进行比较,软件可配置每个timer在将来某个点产生中断或event。如上图,当中断产生时会通过GIC中GICR传递给GICC,最终由本core来完成中断的处理。

            在ARM64中如下中断ID(INTID)用于由SBSA定义的每个定时器,如下:

    Timer

    SBSA推荐的INTID

    EL1 physical timer

    30

    EL1 virtual timer

    27

    Non-secure EL2 physical timer

    26

    Non-secure EL2 virtual timer

    28

    EL3 physical timer

    29

    Secure EL2 physical timer

    20

    Secure EL2 virtual timer

    19

            当支持Timer虚拟化时,Non-secure EL2 physical timer用于hypervisor上arch_timer,EL1 virtual timer用于guest上arch_timer。

    这里以这种情况进行介绍。

            在ACPI情况下,TIMER是在GTDT表中定义的。

    [GTDT表介绍可自行查看协议]

       ARM系统的timer定义为TIMER_ACPI_DECLARE(arch_timer, ACPI_SIG_GTDT, arch_timer_acpi_init)。这里分析在hypervisor上的情况。

    1. 通过函数acpi_gtdt_init()获取GTDT表中定义的定时器数目;
    2. 从GTDT表中获取HYP中断号,并通过函数acpi_register_gsi()注册中断;
    3. 从GTDT表中获取非安全EL1 physical中断号,并通过函数acpi_register_gsi()注册中断;
    4. 从GTDT表中获取EL1 virtual中断号,并通过函数acpi_register_gsi()注册中断;
    5. 将EL1 physical中断号和EL1 virtual中断号传递给KVM用;
    6. 读取系统计数器频率;
    7. 在Host上选择HYP中断为arch_timer,注意在guest上会选择EL1 virtual中断为arch_timer;
    8. 检查定时器是否处于always on电源域;
    9. 在host上注册HYP中断对应的中断处理函数arch_timer_handler_phys,在guest上注册virtual中断对应的中断处理函数arch_timer_handler_virt;
    10. 调用arch_timer_common_init()将arch_timer注册到clocksource和sched_clock中。

            无论是arch_timer_handler_phys()还是arch_timer_handler_virt(),最终会调用用户注册的定时器中断处理函数。

            对于arch_timer_common_init(),调用如下:

    1. 若在guest上为VIRT timer情况,获取计数接口为arch_counter_get_cntvct(),通过vtimer对应的寄存器获取计数;
    2. 若在host上为ptimer情况,获取计数接口为arch_counter_get_cntpct(),通过ptimer对应的寄存器获取计数;
    3. 以当前时钟频率注册clocksource;
    4. 采用上述步骤(1)中的计数接口来注册sched clock。

  • 相关阅读:
    【RuoYi-Vue-Plus】扩展笔记 03 - 实现简单的 EasyExcel 自定义导入监听器
    6.30年终小结,学生时代结束
    工作中怎么去进行测试用例的编写
    JUC线程池——newSingleThreadExecutor源码解析&&JDK提供线程池ThreadPoolExecutor执行任务流程解析
    基于 R 语言的判别分析介绍与实践 LDA和QDA
    C++ - 智能指针 - auto_ptr - unique_ptr - std::shared_ptr - weak_ptr
    【spring】SpringBoot与SpringCloud的版本对应
    【数据分析】2020年北京交通大学计算机学院学术型博士录取数据分析
    【分立元件】贴片电阻过电压故障机理
    Hadoop如何启动HttpFS服务?
  • 原文地址:https://blog.csdn.net/flyingnosky/article/details/127680341