本文是对【操作系统】xv6操作系统中按下键盘回车后发生的事情一文的补充阅读。如果你对PLIC(Platform-Level Interrupt Controller,平台级中断控制器)感到困惑,不妨先阅读这篇文章,了解PLIC的基本概念和工作原理。

什么是PLIC?

在现代计算机系统中,CPU需要与各种外部设备(如键盘、鼠标、硬盘、网络卡等)进行通信。这些设备往往需要主动向CPU报告某些事件,比如键盘被按下、数据传输完成等。为了实现这种主动通知,设备会发出中断信号

然而,在一个复杂的系统中,可能有数十甚至数百个设备同时发出中断请求。如果所有中断信号都直接涌向CPU,会导致混乱。因此,需要一个专门的硬件来管理和协调这些中断请求。这个硬件就是PLIC(Platform-Level Interrupt Controller,平台级中断控制器)

通俗地理解,PLIC就像公司的秘书,中断目标就像公司的老板,而外部中断请求就像要拜访老板的访客。由于访客众多,如果没有处理就让他们全挤在老板办公室,会非常嘈杂。于是,老板聘请了一个秘书,规定所有访客都要在秘书那里登记。秘书会根据访客的重要性排序,每次只通知优先级最高的访客去见老板,从而提高办公效率。

PLIC在RISC-V架构中的作用

RISC-V是一个开源的指令集架构,在嵌入式系统和操作系统教学中应用广泛,目前也在往AI和服务器领域进军(但效果不佳)。在一个典型的RISC-V系统中,主要由以下几个核心部件组成:

  • Core:负责执行指令流水线
  • PLIC:负责管理外部中断
  • DM(Debug Module):负责调试功能

PLIC作为平台级中断控制器,理论上可以支持多达1023个外部中断源和15872个上下文(context)。当然,在实际的硬件实现中,通常不会用到这么多。

PLIC的工作原理

PLIC的核心功能是将外部设备的中断请求进行汇总、仲裁和分发。具体来说,它根据以下几项用户配置的信息来处理中断:

  • 中断优先级:每个中断源的重要程度
  • 中断使能:哪些中断被允许
  • 中断阈值:只有优先级高于阈值的中断才会被处理

通过这些配置,PLIC可以选择出”胜利者”(最高优先级且超过阈值的中断),将其转发给相应的CPU核心进行处理。由于这些参数都可以由软件配置,所以PLIC也被称为可编程中断控制器

中断处理流程

让我们通过一个完整的中断处理流程来理解PLIC的工作机制:

  1. 中断请求到达:外部设备发出中断请求,中断网关(Interrupt Gateway)接收并处理这个请求。

  2. 标记等待状态:网关将处理后的中断请求转发给PLIC内核,同时设置相应中断源的pending位(表示该中断正在等待处理)。

  3. 仲裁与通知:PLIC根据配置信息对所有等待中的中断请求进行仲裁,选择出优先级最高的一个。然后,它向相应的CPU核心发送中断通知(notification),告知有中断需要处理。

  4. 获取中断信息:CPU核心收到通知后,通过读取PLIC的claim寄存器来获取当前需要处理的中断源ID。此时,PLIC会清除该中断源的pending位,表示该中断已开始被服务。

  5. 执行中断服务:CPU执行相应的中断服务程序,处理设备请求。

  6. 完成处理:中断服务完成后,CPU向PLIC的complete寄存器写入中断ID,通知PLIC该中断已处理完毕。

  7. 重启网关:网关收到完成通知后,会重新打开”门”,允许该中断源的下一次中断请求进入。

这个流程确保了中断处理的有序性和可靠性,避免了中断丢失或重复处理的问题。

关键概念详解

Hart Context(硬件线程上下文)

在RISC-V中,hart指硬件线程,即CPU核心。中断目标通常是运行在特定特权模式下的特定hart。PLIC支持多hart系统,可以将不同的中断路由到不同的CPU核心。

Interrupt Gateway(中断网关)

中断网关是每个中断源的入口。它负责:

  • 将不同形式的中断信号(电平触发或边沿触发)转换为统一的格式
  • 控制中断请求的进入,确保同一时刻每个中断源最多只有一个请求在PLIC中等待

网关就像一道门,只有在上一个中断处理完成后才会打开,允许新的中断请求进入。

Interrupt Notification(中断通知)

当PLIC仲裁出需要处理的中断后,会通过设置EIP(External Interrupt Pending)位来通知CPU。需要注意的是:

  • PLIC采用广播方式,所有hart都会收到通知
  • 实际由软件决定哪个hart负责处理
  • EIP不同于具体的IP位,后者表示某个中断源的状态

Interrupt Identifier(中断标识符)

每个全局中断源都有一个唯一的ID(从1开始,0表示无中断)。ID不仅用于标识中断源,还在优先级相同时作为仲裁的次要标准(ID小的优先)。

PLIC寄存器详解

PLIC通过内存映射的寄存器进行配置和控制。不同处理器的PLIC可能位于不同的基地址,但访问方式都是base + offset。

中断优先级寄存器

每个中断源都有一个优先级设置:

  • 0:禁用该中断
  • 1-7(或更高):优先级数值越大,越重要
  • 在仲裁时,优先级相同则ID小的胜出

中断pending指示寄存器(只读)

每个中断源用1位表示是否处于等待状态。读取claim寄存器会自动清除对应位。

中断使能寄存器

控制每个上下文(hart)可以接收哪些中断。每个中断源用1位表示。

中断阈值寄存器

设置每个上下文的最低中断处理优先级。低于此阈值的中断会被屏蔽。

中断claim寄存器

CPU读取此寄存器获取下一个待处理中断的ID。如果没有中断,返回0。

中断完成寄存器

与claim寄存器共享地址。写入中断ID表示处理完成,允许新中断进入。

总结

PLIC是RISC-V系统中不可或缺的中断管理组件,它通过仲裁和分发机制,确保CPU能够高效、有序地处理来自外部设备的各种请求。在xv6这样的教学操作系统中,理解PLIC的工作原理有助于我们深入掌握中断处理的全貌。

如果你已经阅读完这篇文章,建议回到《【操作系统】xv6操作系统中按下键盘回车后发生的事情》,重新审视PLIC在实际系统中的应用。这样,你将对计算机中断机制有更加全面和深刻的理解。