Arm GIC-v3中断原理及验证(通过kvm-unit-tests)

一、参考连接

gic-v3相关原理可参考https://zhuanlan.zhihu.com/p/520133301

本文主要通过开源测试工具kvm-unit-tests,针对GIC的中断进行一系列验证,这样可以直入中断底层,熟悉整个原理。

kvm-unit-tests官网为kvm-unit-tests / KVM-Unit-Tests · GitLab

armv8寄存器介绍官网为Documentation – Arm Developer

GICv3官方文档为Documentation – Arm Developer

二、中断验证

        GIC的中断主要为四类,即SGI(IPI)、PPI、SPI、LPI,本文主要针对这四类进行验证。具体原理将在验证中随意阐述。总体来看kvm-unit-tests源码的理解难度要低于kernel源码,所以方便引用,其实底层逻辑其实是一样的。

        GIC总计结构:

        GIC中断分布:

中断类型中断号说明
SGI0 - 15
PPI16 – 31
SPI32 - 1019
特殊中断号1020 - 1023
保留中断号1024 - 1055
扩展PPI1056 -1119GICv3.1版本后才支持
保留中断号1120 - 4095
扩展SPI4096 - 5119GICv3.1版本后才支持
保留中断号5120 - 8191
LPI8192 -最大支持的中断号由实现确定

        先来整体看下一个机器中断的整体分布,我是在VM中:

        再来看个kvm-unit-tests的整体测试吧,就当留个印象。

2.1 SGI(software generated interrupt)(IPI)中断验证        [0-15]

       该类型中断并没有实际的物理连线,而是通过由软件写寄存器方式触发,它只支持边沿触发。通常用于处理器之间的通信,如linux内核电源管理模块中调用的ipi中断就是通过SGI实现的。

        IPI即核间中断,arm的叫sgi。

        kvm-unit-tests(本文以后简称k-u-t)中正好有专门的SGI检测项,可以通过总体测试然后log输出,也可以单独加参数测试验证:

2.1.1中断发送

发送中断的本质其实,从软件层面来讲,其实就是写寄存器。发送SGI中断的步骤归纳如下:

  1. 通过GICR_ISENABLER0寄存器设置中断使能
  2. 通过GICR_IPRIORITYR<n>设置优先级
  3. 写寄存器 GICD_SGI1R
  4. 写寄存器 ICC_SGI1R_EL1

kut中关于发送sgi中断的函数是lib/arm/gic-v3.c中的gicv3_ipi_send_mask()函数(可类比kernel-5.10中的gic_ipi_send_mask函数),

再看下写入到寄存器ICC_SGI1R_EL1中的值,以及spec中规定的ICC_SGI1R_EL1各字段含义:

嗯,只能说是一模一样。所以这就是软件层面发送sgi中断的最终操作,剩下的就是硬件层面的事了。

类比kernel-5.10中sgi中断发送代码的调用路径是:

        gic_ipi_send_mask-->gic_send_sgi-->gic_write_sgi1r

其实除了逻辑更复杂了,整体框架都一样。

2.1.2中断接收处理

接收中断的处理函数是arm/gic.c中的irq_handler(),这个函数基本上总结了所有中断handler的模板:

  

所以中断处理的一般步骤就是:

  1. 读取iar寄存器,获取到描述irq的结构体irq_data;
  2. 通过irq_data获取到irq_num;
  3. 具体的中断处理;
  4. 回写eoi寄存器,中断结束。

kut因为只是模拟测试,所以中断handler比较简单,具体的sgi中断处理只是简单的记录信息,如ack[cpuid]++;表示本cpu接收到了中断。

2.1.3kut中sgi测试总体逻辑

由于讲述中断,所以直接开讲的中断发送以及中断处理,其实是倒叙看源码了。正序应该是类似gdb似的从头开始。kut中每个test-case都有一个main函数,当我们独立测试某一项时,如测试gic的sgi中断,当我们命令行输入-append ipi时,就已经进入到sgi测试的主入口了,程序逻辑依次是:

至此,SGI中断的逻辑以及原理差不多可以了,反正就是触发SGI中断就写ICC_SGI1R_EL1寄存器,接收中断handler就是按标准步骤操作寄存器:读取iar,获取irq,逻辑处理,回写eoi。

2.2 PPI(private peripheral interrupt)中断验证        [16-31]

       该类型中断是每个处理器私有的,即一个特定的中断只会被路由到特定的处理器上。且其同一个中断号在每个处理器上都可以有不同的中断,如对于一个拥有两个PE的smp系统,中断号16的PPI中断可以分别被注册为PE0和PE1的私有中断,它们可以被独立触发并被特定的PE独立处理.

        kut中没有显式测试ppi的用例,但其中有个timer的测试用例,通过/proc/interrupt可以看出,timer的中断其实就是ppi的中断,毕竟每个cpu都会独立收到timer。所以直接测试kut中的timer一项即可,其中的打印为我自己加的补丁,可以看到timer的irq正好属于[16-31]这个PPI区间。

2.2.1中断发送

发送PPI中断的步骤归纳如下

  1. 通过GICR_ISENABLER0寄存器设置中断使能
  2. 通过GICR_IPRIORITYR<n>设置优先级
  3. 写相应的寄存器(如timer的)

同样的,timer也有一大堆寄存器来控制,包括使能ctl、读写比较值cval、读写时间值tval、读count等。发中断就是设置其中的寄存器,然后等待时间到时(硬件计数)就可以了。

kut中关于timer中断的发送主要为test_timer的子函数 ,分别为 test_timer_cval-->test_cval_10msec(测试compare val寄存器);  test_timer_pending(测试timer中断);  test_timer_tval(测试time val寄存器);

相比而言,timer的寄存器字段较为简单,都不用像sgi寄存器那样显示组装各个field。

2.2.2中断接收处理

timer的接收中断的处理函数是arm/timer.c中的irq_handler(),定睛一看 似曾相识,不用多讲了吧。

唯一的中断处理逻辑就是置位irq_received = true; 这不比看kernel那一坨代码简洁多了。

2.2.3kut中ppi测试总体逻辑

话不多说,直接看图。简洁,太简洁了。

但其实除此之外,还有init的一大段,这个是所有test-case共有的,算作整个kut的初始化吧,ptimer和vtimer的中断号也是在init时从dtb读出来确定的,一开始的入口是arm/cstart.S中:

其中有个setup基本就是在给main铺路了,包括设置内存分布,各类设备初始化,堆栈空间初始化等等,基本看函数名就不用再注释了。

其中timer的irq就在timer_save_state的子函数timer_save_state_fdt中从dtb读出来并设置好,本次实验中的irq打印也是在此插桩。

所以到此,PPI中断也基本讲完了。其实还是老一套,发中断就是写某个寄存器触发某个事件(timer就是写cntp_tval,别的就写对应的reg),中断处理还是四步走。只不过PPI是换成了私有的private的,各个cpu都整了一套。

2.3 SPI(shared peripheral interrupt)中断验证        [32 - 1019]

        SPI中断不与特定的cpu绑定,可以根据affinity配置被路由到任意cpu或一组特定的cpu上。如一般的外设中断都是通过SPI方式连接的。

        kut中并没有看到专门的测试spi中断的test-case,误打误撞却发现kut中有个RTC设备pl031设备用的就是SPI,其中断号34正好属于这个区间,有了前面timer分析的基础,看懂这个rtc设备的发送中断以及中断处理简直是降维打击,读者朋友们自行去看吧,实在不用分析了。

        其实验证SPI中断我本来是想用串口uart-pl011这个设备的,奈何kut中没有对串口进行单独的test-case,而只是把它当作了标准输出stdio,如果重新写一个testcase的话倒也可以(看以后有没有时间即兴趣了),但只是为了测试SPI而加用例,好像不太符合kut的目的。

所以暂时用之前的模拟串口来看吧,反正也能看出uart0中断处理,任意敲击按键,就能发现uart0的中断数++。原理其实是一样的,就是没有显式的代码去一行行验证了。其中

console1:

console2:

2.4 LPI(Locality-specific Peripheral Interrupt)中断验证        [8192 - 具体实现决定max]

        该类型中断是一种基于消息的中断,外设不需要通过硬件中断线连接到GIC上, 而可以向特定地址写入消息来触发中断。典型的应用为PCIe的MSI和MSI-X中断。
  LPI中断有一些其特有的属性,如只支持non secure group1分组、只支持边沿触发、可以选择使用或不使用ITS路由,以及没有active状态,也不需要显式的deactivation操作。

        kvm-unit-tests中正好有专门的LPI检测项,其实就是ITS那一大堆测试,我就拿其中的一个its-trigger来讲解吧。

        处理LPI中断,首先得了解些GIC,GICv3组件如下图所示:

其中 Distributor、Redistributor、ITS和cpu interface是主要组件,可以看首字母区分。有几个虚拟化中断的组件列举几个控制寄存器说明下他们的区别:

ICC_CTLR_EL1

Controls aspects of the behavior of the GIC CPU interface and provides information about the features implemented.

ICH_HCR_EL2

Controls the environment for VMs.

ICV_CTLR_EL1

Controls aspects of the behavior of the GIC virtual CPU interface and provides information about the features implemented.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/422606.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

labview禁用8080端口

需求背景 最近电脑上安装了labview全家桶,发现idea的8080端口项目启动报错,一直提示8080端口被占用。最简单的办法就是找到8080端口的服务,然后关闭这个服务。但是我不想这么做,我想把labview的web服务器的端口给修改了。 操作教程 1、cmd查看8080端口 2、windows进程 同…

022.PL-SQL进阶—分页过程

课 程 推 荐我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448;入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448;虚 拟 环 境 搭 建 &#xff1a;&#x1…

Flask 实现用户登录功能的完整示例:前端与后端整合(附Demo)

目录 前言Demo 前言 对于python用户的登录&#xff0c;以下只是提供一个Demo用于学习 更多的python知识点可从我的专栏中进行学习 python专栏详细分析Flask中的蓝图Blueprint&#xff08;附Demo&#xff09;详细分析Flask部署云服务器&#xff08;图文介绍&#xff09;构建F…

2024 年 GitLab Global DevSecOps 报告解读

近日 GitLab 正式发布了 2024 年 GitLab Global DevSecOps 报告&#xff0c;报告主题为 What’s next in DevSecOps。在全球有超 5000 位 IT 人员参与了该报告的调研&#xff0c;超 70% 为企业管理者&#xff0c;50% 以上的受访者所在企业规模超过 500人。该报告深刻揭示了在 A…

深度学习_GPT2Block详解(casual attention)

一、GTP2Block 整体结构 1.1 block准备 import torch from torch import nn from transformers import GPT2Model, GPT2Config from transformers.models.gpt2.modeling_gpt2 import GPT2Blockcfg GPT2Config() print(cfg.add_cross_attention) blk GPT2Block(cfg, layer_…

《ECMAScript 与 JavaScript:差异与共通》

一、概念辨析 《ECMAScript 与 JavaScript&#xff1a;差异与共通》 ECMAScript&#xff08;简称 ES&#xff09;是一种由 Ecma International 标准化的脚本语言规范。它定义了脚本语言的核心特性&#xff0c;包括语法、类型、语句、关键字等。例如&#xff0c;ECMAScript 规定…

被要求撤回Blackwell?一家初创企业称英伟达侵权自家技术,忍无可忍!英伟达和伙伴微软被齐齐告上法庭,赔偿或高达数十亿!

刚刚&#xff0c;一家初创公司居然把巨头英伟达和微软一起告了&#xff01; 名为Xockets的初创公司在诉讼中称&#xff0c;英伟达和微软公司窃取了其DPU技术&#xff0c;用以开发AI产品&#xff0c;并相互串通以压低其技术的价格&#xff0c;是名副其实的垄断行为&#xff01;…

智汇创想pytest接口自动化测试框架

本测试框架是基于pytest搭建的接口自动化框架&#xff0c;对象为深圳智汇创想官方网站。深圳智汇创想科技有限责任公司&#xff08;深圳智汇创想科技有限责任公司&#xff09;&#xff0c;是一家专注于跨境电子商务的集团公司&#xff0c;全球电商平台多品类多品牌的零售商&…

MATLAB | R2024b更新了哪些好玩的东西?

Hey, 又到了一年两度的MATLAB更新时刻&#xff0c;MATLAB R2024b正式版发布啦&#xff01;&#xff0c;直接来看看有哪些我认为比较有意思的更新吧! 1 小提琴图 天塌了&#xff0c;我这两天才写了个半小提琴图咋画&#xff0c;MATLAB 官方就出了小提琴图绘制方法。 小提琴图…

客户端负载均衡Ribbon实例

文章目录 一&#xff0c;概述二&#xff0c;实现过程三&#xff0c;项目源码1. 源码放送&#xff1a;2. 部署方式 四&#xff0c;功能演示五&#xff0c;其他 一&#xff0c;概述 一般来说&#xff0c;提到负载均衡&#xff0c;大家一般很容易想到浏览器 -> NGINX -> 反…

加密与安全_ sm-crypto 国密算法sm2、sm3和sm4的Java库

文章目录 Presm-crypto如何使用如何引入依赖 sm2获取密钥对加密解密签名验签获取椭圆曲线点 sm3sm4加密解密 Pre 加密与安全_三种方式实现基于国密非对称加密算法的加解密和签名验签 sm-crypto https://github.com/antherd/sm-crypto 国密算法sm2、sm3和sm4的java版。基于js…

PMP--一模--解题--21-30

文章目录 9.资源管理21、 [单选] 项目经理发现一个不可预料的高影响风险已经成为项目的一个因素&#xff0c;团队成员之间的自身利益导致问题得不到解决&#xff0c;项目经理必须快速行动&#xff0c;让团队重新集中精力&#xff0c;以便项目恢复进度&#xff0c;项目经理应该使…

vue3项目实现全局国际化

本文主要梳理vue3项目实现全项目格式化&#xff0c;例如在我前面文章使用若依创建vue3的项目中&#xff0c;地址&#xff1a;若依搭建vue3项目在导航栏中切换&#xff0c;页面中所有的组件的默认语言随之切换&#xff0c;使用的组件库依旧是element-plus&#xff0c;搭配vue-i1…

09-排序1 排序(C)

这一节&#xff0c;测试各类排序算法的运行速度&#xff08;没有基数排序&#xff08;桶&#xff09; 其实在实际学习中&#xff0c;还是有意义的 给定 n 个&#xff08;长整型范围内的&#xff09;整数&#xff0c;要求输出从小到大排序后的结果。 本题旨在测试各种不同的排序…

Windows与Linux下 SDL2的第一个窗口程序

Windows效果和Linux效果如下&#xff1a; 下面是代码&#xff1a; #include <stdio.h> #include "SDL.h"int main(int argc, char* argv[]) { // 初始化SDL视频子系统if (SDL_Init(SDL_INIT_VIDEO) ! 0){// 如果初始化失败&#xff0c;打印错误信息printf(&…

proteus+51单片机+实验(LCD1620、定时器)

目录 1.LCD1602液晶显示屏 1.1基本概念 1.1.1LCD的简介 1.1.2LCD的显示原理 ​​​1.1.3LCD的硬件电路 1.1.4LCD的常见指令 1.1.5LCD的时序 ​​​​​​​1.2代码 1.2.1写命令和写数据操作 1.2.2初始化和测试代码 1. 3.3功能函数 1.3proteus代码 1.3.1器件代码 1.…

探索Python世界的隐藏宝石:Pika库的神秘力量

文章目录 探索Python世界的隐藏宝石&#xff1a;Pika库的神秘力量背景&#xff1a;为何选择Pika&#xff1f;Pik库简介如何安装Pika&#xff1f;简单库函数使用方法场景应用常见Bug及解决方案总结 探索Python世界的隐藏宝石&#xff1a;Pika库的神秘力量 背景&#xff1a;为何…

ELK预警方案:API+XXLJob

目录 步骤一&#xff1a;出一个接口&#xff0c;接口内查询出10分钟内是否有异常信息 步骤二&#xff1a;XXLJob中设置预警的频率 步骤三&#xff1a;在重要的业务处输出指定格式日志即可 步骤一&#xff1a;出一个接口&#xff0c;接口内查询出10分钟内是否有异常信息 {&qu…

Java | Leetcode Java题解之第402题移掉K位数字

题目&#xff1a; 题解&#xff1a; class Solution {public String removeKdigits(String num, int k) {Deque<Character> deque new LinkedList<Character>();int length num.length();for (int i 0; i < length; i) {char digit num.charAt(i);while (!…

C语言字符函数和字符串函数(20)

文章目录 前言一、字符分类函数小练习 二、字符转换函数三、strlen的使用和模拟实现四、strcpy的使用和模拟实现五、strcat的使用和模拟实现六、strcmp的使用和模拟实现七、strncpy函数的使用八、strncat函数的使用九、strncmp函数的使用十、strstr函数的使用和模拟实现十一、s…