RISC-V SiFive U54内核——PLIC平台级中断控制器

RISC-V SiFive U54内核有两个中断控制器:CLINT和PLIC,今天介绍PLIC。

平台级中断控制器(PLIC)

PLIC:Platform-Level Interrupt Controller. 实际上,除了CLINT管理的软件中断和定时器中断,其他的中断都是由PLIC管理的。

U54内核的平台级中断控制器 (PLIC) 最多可支持 132 个具有 7 个优先级的外部中断源。

Memory Map

U54 内核 PLIC 控制寄存器的内存映射如表 105 所示。PLIC 内存映射仅支持对齐的 32 位内存访问。

img

中断源

U54内核共有 132 个全局中断源,此外还有CLINT管理的 中描述的本地中断。

其中 127 个是外部全局中断,其余由表 106 中列出的各种片上设备驱动。 表 106 描述了 U54 核心复合体上的全局中断源。

img

Note:在 RISC‑V 平台级中断控制器规范中,中断源 0 (ID 0) 未使用,因此第一个可用的 PLIC 中断 ID 的值为 1

中断优先级

每个 PLIC 中断源都可以通过写入其 32 位内存映射优先级寄存器来分配优先级。

U54 内核支持 7 个优先级。 保留优先级值 0 表示“永不中断”并有效地禁用中断。

优先级 1 是最低的活动优先级,优先级 7 是最高的

相同优先级的全局中断之间的关系由中断 ID 打破; ID 最低的中断具有最高的有效优先级。 相关寄存器信息如下:

img

中断挂起位

PLIC 内核中中断源挂起位的当前状态可以从挂起数组中读取,组织为 32 位的 5 个字。 中断 ID 的挂起位存储在字的位中。

因此,U54 内核有 5 个中断挂起寄存器。 表示不存在的中断源 0 的字 0 的位 0 硬接线为零。

PLIC 内核中的挂起位可以通过设置相关的启用位然后执行第 9.8 节中描述的声明来清除

img

img

中断使能

每个全局中断都可以通过设置启用寄存器中的相应位来启用。 使能寄存器作为 5 × 32 位字的连续数组进行访问,其打包方式与未决位相同。 使能字 0 的位 0 表示不存在的中断 ID 0,并硬接线为 0。

SiFive RV64 系统中的使能数组支持 64 位和 32 位字访问。

img

PLIC Clock Gate Disable

PLIC 实现时钟门控功能以在不活动时门控模块时钟节点。PLIC 时钟门控在复位后被禁用,应在启动代码中启用,除非 SiFive 勘误表另有规定。 一旦启用,时钟仅在 PLIC 控制总线上或任何中断线上有活动且相应中断未运行时才可用。

img

优先级阈值

U54 内核 支持通过阈值寄存器设置中断优先级阈值。 阈值是一个WARL字段,其中U54 内核支持的最大阈值为7

U54 核心复合体屏蔽优先级小于或等于阈值的所有 PLIC 中断。 例如,阈值为零允许所有具有非零优先级的中断,而值为 7 则屏蔽所有中断。 如果阈值寄存器的值为 5,则不允许将优先级配置为从 1 到 5 的所有 PLIC 中断传播到 CPU。

img

Interrupt Claim Process

U54 内核 hart 可以通过读取 claim_complete 寄存器(表 115)执行中断请求,该寄存器返回最高优先级挂起中断的 ID,如果没有挂起中断则返回零。 成功的声明还会自动清除中断源上相应的挂起位。

img

U54 内核 hart 可以随时执行声明,即使其 mip寄存器中的 MEIP 位未设置。

声明操作不受优先级阈值寄存器设置的影响。

中断完成

U54 内核 hart 通过将其从声明中收到的中断 ID 写入 claim_complete 寄存器(表 115)来表示它已完成执行中断处理程序。 PLIC 不检查完成 ID 是否与该目标的最后一个声明 ID 相同。 如果完成 ID 与当前为目标启用的中断源不匹配,则完成将被静默忽略。

img

PLIC 无法将新中断转发给已声明中断但尚未完成中断处理程序的完整步骤的 hart。 因此,PLIC 不支持抢占单个 hart 的全局中断

通过 PLIC 路由的全局中断的中断 ID 独立于本地中断的中断 ID。 在退出处理程序之前,一旦初始声明/完成过程完成,PLIC 处理程序可能会检查其他未决的全局中断。 此方法可以为全局中断保存额外的 PLIC 保存/恢复上下文。

PLIC中断处理例子

由于 PLIC 通过外部中断 #11 与 CPU 接口,因此外部处理程序必须包含一个额外的声明/完成步骤,用于与 PLIC 逻辑握手。

void external_handler() {
//get the highest priority pending PLIC interrupt
uint32_t int_num = plic.claim_complete;
//branch to handler
plic_handler[int_num]();
//complete interrupt by writing interrupt number back to PLIC
plic.claim_complete = int_num;
// Add additional checks for PLIC pending here, if desired
}

如果 CPU 读取 claim_complete 并返回 0,则中断不需要处理,因此不需要回写 claim/complete。

上面显示的 plic_handler 例程演示了一种实现软件表的方法,其中驻留在表中的函数的偏移量由 PLIC 中断 ID 确定。 PLIC 中断 ID 对于 PLIC 是唯一的,因为它完全独立于本地中断的中断 ID。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

嵌入式Linux充电站

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

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

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

打赏作者

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

抵扣说明:

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

余额充值