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


请阅读【ARM GICv3/v4 实战学习 】


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寄存器的访问需要按照你的处理器和系统的特定要求来进行,这可能包拍使用特权指令或通过特定的内存映射地址访问这些寄存器。
  • 操作这些寄存器时,需要确保不会意外地更改或启用/禁用其他中断,尤其是在对寄存器进行位操作时。
  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
armv8armv9是英国ARM公司推出的两个处理器架构,用于移动设备、嵌入式设备和服务器等领域。在这两个架构中,异常中断GIC (Generic Interrupt Controller) 是非常重要的主题。 异常中断是指当系统发生某种事件时,处理器暂停当前任务,转而处理优先级较高的任务。异常中断包括两种类型:同步异常和中断异常。同步异常是由指令执行时产生的,如除零异常、非法指令异常等。中断异常是由外部事件触发的,如定时器中断、外设中断等。 在armv8armv9架构中,异常的处理是通过异常向量表实现的。异常向量表是一个固定大小的表格,其中包含不同类型异常的处理函数的地址。当发生异常时,处理器会根据异常类型在异常向量表中查找相应的处理函数,并跳转到该函数执行异常处理。 GIC是一个用于处理中断的控制器,它负责管理和分发中断信号给相应的处理器核心。在多核处理器中,GIC可以实现中断的负载均衡和处理器间的中断共享。GIC具有多个中断输入通道,每个通道对应一个中断引脚。当外部设备发生中断时,通过相应的中断引脚将中断信号发送给GIC,然后GIC中断信号分发给对应的处理器核心。 armv8armv9架构中的GIC支持多种中断处理模式,包括中断屏蔽、中断优先级配置中断传递方式等。GIC还可以实现中断的共享和抢占,以提高中断的处理效率和可靠性。 总而言之,armv8armv9架构中的异常中断GIC是处理器架构中非常重要的专题。通过学习异常中断的处理和GIC的功能,可以更好地理解和掌握armv8armv9架构的中断处理机制,提高系统的可靠性和性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

主公CodingCos

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值