当前位置: 首页 > news >正文

【ARMv8/v9 GIC 系列 2 -- GIC SPI 中断的 enable和 disable 配置】

文章目录

    • GIC 中断 Enable 和 Disable
      • GICD_ISENABLER<n>
      • GICD_ICENABLER<n>
      • 参数 n
      • 使用举例
      • 代码实现
      • 注意事项

GIC 中断 Enable 和 Disable

在ARMv8架构中,通用中断控制器(GIC)负责管理处理器的中断。为了控制和管理这些中断,GIC提供了一系列寄存器。其中,GICD_ISENABLER<n>GICD_ICENABLER<n> 是两组关键的寄存器,用于启用和禁用中断。

OffsetNameDescription
0x0100-0x017CGICD_ISENABLER<n>Interrupt Set-Enable Registers
0x0180-0x01FCGICD_ICENABLER<n>Interrupt Clear-Enable Registers

GICD_ISENABLER

在这里插入图片描述

  • 寄存器名称:Interrupt Set-Enable Registers
  • 目的:用于启用中断。
  • 描述:这些寄存器允许软件启用特定的中断。每个寄存器对应32个中断,每个位代表一个中断。写入1到某位会启用对应的中断,写入0对该位没有影响(即,不能通过写入0来禁用中断)。

GICD_ICENABLER

在这里插入图片描述

  • 寄存器名称:Interrupt Clear-Enable Registers
  • 目的:用于禁用中断。
  • 描述:这些寄存器允许软件禁用特定的中断。与GICD_ISENABLER<n>类似,每个寄存器对应32个中断,但写入1到某位会禁用对应的中断,写入0对该位没有影响。

参数 n

参数<n>代表寄存器的索引,根据系统支持的中断数量而变化。例如,如果GIC支持最多1020个中断,那么GICD_ISENABLERGICD_ICENABLER寄存器会有32个(从GICD_ISENABLER0GICD_ISENABLER31和从GICD_ICENABLER0GICD_ICENABLER31),因为每个寄存器可以控制32个中断。

可以通过下面函数判断一个中断是否为SPI中断:

static uint32_t is_spi_irq(int irq)
{return irq >= 32 && irq < 1020;
}

使用举例

假设我们要启用中断ID 68和禁用中断ID 95。

  • 启用中断ID 68
    • 中断ID 68在GICD_ISENABLER2寄存器中,因为68/32 = 2(整除)。
    • GICD_ISENABLER2中,68对应的位是68 % 32 = 4
    • 因此,通过向GICD_ISENABLER2写入1 << 4(即,0x10),可以启用中断ID 68。
GICD_ISENABLER2 |= (1 << 4);
  • 禁用中断ID 95
    • 中断ID 95在GICD_ICENABLER2寄存器中,因为95/32 = 2(整除)。
    • GICD_ICENABLER2中,95对应的位是95 % 32 = 31
    • 因此,通过向GICD_ICENABLER2写入1 << 31(即,0x80000000),可以禁用中断ID 95。
GICD_ICENABLER2 |= (1 << 31);

代码实现

下面代码展示了如何使用C代码实现 irq_enableirq_disable

void irq_enable(int irq)
{uint32_t addr;if (!is_spi_irq(irq)) {log_err("irq%d is not a spi irq\n", irq);return;}/* Calculate enable register offset and bit position */uint32_t reg_offset = irq / 32;uint32_t reg_shift  = irq % 32;addr = GIC_ISENABLER_ADDRESS(GIC_DISTRIBUTOR_BASE, reg_offset);write32(addr, (1 << reg_shift));
}void irq_disable(int irq)
{uint32_t addr;if (!is_spi_irq(irq)) {log_err("irq%d is not a spi irq\n", irq);return;}uint32_t reg_offset = irq / 32;uint32_t reg_shift  = irq % 32;addr = GIC_ICENABLER_ADDRESS(GIC_DISTRIBUTOR_BASE, reg_offset);write32(addr, (1 << reg_shift));
}

注意事项

  • 在实际编程中,对GIC寄存器的访问需要按照你的处理器和系统的特定要求来进行,这可能包拍使用特权指令或通过特定的内存映射地址访问这些寄存器。
  • 操作这些寄存器时,需要确保不会意外地更改或启用/禁用其他中断,尤其是在对寄存器进行位操作时。

相关文章:

  • SpringSecurity实战入门——认证
  • React+TS前台项目实战(九)-- 全局常用组件弹窗Dialog封装
  • Mybatis Plus 详解 IService、BaseMapper、自动填充、分页查询功能
  • Python基础教程(二十四):日期和时间
  • 第六章 图论与网络分析 (重点,熟练掌握三算法) 树图和图的最小部分树 最短路问题 网络的最大流
  • 24年计算机等级考试22个常见问题解答❗
  • 23种设计模式之桥接模式
  • 【Unity设计模式】状态编程模式
  • Git与SSH
  • 深入了解软件设计模式:创新应用与优化代码结构
  • 【信息学奥赛】CSP-J/S初赛04 进制转换相关问题(二、八、十六进制与十进制互相转换)
  • leetcode67 二进制求和
  • Android低代码开发 - InputMenuPanelItem详解
  • 2.spring cloud gateway 源码编译
  • (创新)基于VMD-CNN-BiLSTM的电力负荷预测—代码+数据
  • 【MySQL经典案例分析】 Waiting for table metadata lock
  • C学习-枚举(九)
  • KMP算法及优化
  • leetcode388. Longest Absolute File Path
  • STAR法则
  • Vue组件定义
  • 程序员该如何有效的找工作?
  • 仿天猫超市收藏抛物线动画工具库
  • 基于Vue2全家桶的移动端AppDEMO实现
  • 聊一聊前端的监控
  • 软件开发学习的5大技巧,你知道吗?
  • 使用Envoy 作Sidecar Proxy的微服务模式-4.Prometheus的指标收集
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 微服务入门【系列视频课程】
  • 一些css基础学习笔记
  • const的用法,特别是用在函数前面与后面的区别
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • ​Java并发新构件之Exchanger
  • #07【面试问题整理】嵌入式软件工程师
  • (04)odoo视图操作
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (动手学习深度学习)第13章 计算机视觉---图像增广与微调
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (四)Linux Shell编程——输入输出重定向
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • (转)Linux下编译安装log4cxx
  • (转载)Linux网络编程入门
  • (轉)JSON.stringify 语法实例讲解
  • (总结)(2)编译ORB_SLAM2遇到的错误
  • .NET CORE使用Redis分布式锁续命(续期)问题
  • .net Stream篇(六)
  • .NET/C# 判断某个类是否是泛型类型或泛型接口的子类型
  • .NET/C# 使窗口永不激活(No Activate 永不获得焦点)
  • .net开发时的诡异问题,button的onclick事件无效
  • .net之微信企业号开发(一) 所使用的环境与工具以及准备工作
  • [ 云计算 | AWS ] 对比分析:Amazon SNS 与 SQS 消息服务的异同与选择
  • [APIO2015]巴厘岛的雕塑
  • [BUUCTF 2018]Online Tool(特详解)