riscv_vplic
路径:
virtualization/riscv_vplic类型:库 crate 分层:组件层 / RISC-V 虚拟中断控制器 版本:0.2.1文档依据:当前仓库源码、Cargo.toml、README.md、vplic.rs、devops_impl.rs与其在axdevice中的接入路径
riscv_vplic 实现的是面向 hypervisor 的 RISC-V 虚拟 PLIC。它并不是完全软件仿真的独立 PLIC,也不是简单的原样透传,而是采用一种“部分透传、部分软件建模”的折中策略:priority/enable/threshold 等寄存器多半透传到宿主 PLIC,pending 与 claim/complete 的关键语义由软件维护,并通过 hvip::set_vseip() / clear_vseip() 驱动 guest 感知 VS 级外部中断。
架构设计
设计定位
该 crate 的设计目标是让 RISC-V guest 在 hypervisor 下看到一套近似 PLIC 1.0.0 的 MMIO 设备,同时又尽量复用宿主已有 PLIC 硬件能力。因此它的实现不是完全虚构一个独立中断控制器,而是采用 PPPT(PLIC Partial Passthrough)思路:
- 真实硬件寄存器尽可能透传访问。
- 与虚拟化直接相关的 pending、claim/complete、注入语义由软件接管。
- 最终通过
hvip中的VSEIP位把“有外部中断待处理”的事实告诉 guest。
在当前仓库中,它是 axdevice 自动实例化的 RISC-V 中断设备后端,对应 EmulatedDeviceType::PPPTGlobal。
模块结构
| 模块 | 作用 | 关键内容 |
|---|---|---|
consts.rs | PLIC 内存布局常量 | PLIC_NUM_SOURCES、priority/pending/enable/context offsets 与 stride |
vplic.rs | 核心状态对象 | VPlicGlobal、上下文数量、位图状态、构造期边界检查 |
devops_impl.rs | 设备语义实现 | BaseDeviceOps<GuestPhysAddrRange> 的 MMIO 读写逻辑 |
utils.rs | 宿主 MMIO 辅助 | perform_mmio_read/write(),通过 axvisor_api::memory::phys_to_virt() 做 volatile 访问 |
lib.rs | 对外导出 | 导出常量和 VPlicGlobal |
1.3 关键数据结构
VPlicGlobal 是唯一核心对象,字段含义如下:
addr:guest 物理地址空间中的 vPLIC 基址。size:映射区域大小。contexts_num:context 数量,通常与可见 hart 数密切相关。assigned_irqs:分配给该 vPLIC 的 IRQ 位图,当前源码尚未真正使用。pending_irqs:软件维护的 pending 位图。active_irqs:软件维护的 in-service 位图。host_plic_addr:宿主 PLIC 的物理基址。
这里最值得注意的是 host_plic_addr 的假设:当前实现直接把它设为与 guest vPLIC 地址数值相同,并在注释中明确写出“当前假定 host_plic_addr = guest_vplic_addr”。这意味着当前实现依赖宿主和 guest 在 PLIC 映射上的强假设,而不是做通用 地址转换表。
1.4 构造期校验
VPlicGlobal::new() 会在初始化时进行两个关键检查:
size必须显式传入,不能省略。- 区间长度必须足以覆盖最后一个 context 的 claim/complete 寄存器,否则直接
assert!失败。
这保证了最基本的 PLIC MMIO 布局完整性,不会在运行期才暴露明显越界。
1.5 PLIC 内存模型
consts.rs 基本按 PLIC 1.0.0 组织了地址布局:
PLIC_PRIORITY_OFFSET = 0x000000PLIC_PENDING_OFFSET = 0x001000PLIC_ENABLE_OFFSET = 0x002000PLIC_CONTEXT_CTRL_OFFSET = 0x200000PLIC_CONTEXT_STRIDE = 0x1000PLIC_CONTEXT_CLAIM_COMPLETE_OFFSET = 0x04
源码还明确记录:
PLIC_NUM_SOURCES = 1024- source 0 保留不用
因此这个 crate 至少在“地址模型”和“寄存器区段划分”上是强对齐 PLIC 规范的。