Alien

View on GitHub

PLIC

PLIC(platform-level interrupt controller),平台级中断控制器。用来将外部的全局中断请求处理后转至中断目标。PLIC理论上支持1023个外部中断源和15872个上下文

PLIC组成

中断源

中断目标

对于不同的处理器实现,上述描述中存在差异的地方在于中断目标,例如qemu与sifive u74-MC两个相比,qemu的硬件上下文是均匀的,即对与每个处理器核,都存在S/M两个mode,因此在设置相关的寄存器信息时,可以直接按照固定的偏移进行读写,但是对于u74-mc这种设计来说,其第一个核只有M mode,因此PLIC中硬件上下文的排布就不均匀,想比qemu偏移量就会变化。为了可以使得PLIC驱动可以同时兼容上面两种情况,我们在PLIC的初始化函数中要求用户提供当前机器上的硬件上下文信息。

#[derive(Debug)]
pub struct PLIC<const H:usize>{
    base_addr: usize,
    privileges: [u8; H],
}

对于qemu的初始化:

let privileges = [2;CPU_NUM];
let plic = PLIC::new(addr, privileges);

对于u74-mc的初始化:

let mut privileges = [2u8;CPU_NUM];
// core 0 don't have S mode
privileges[0] = 1;
let plic = PLIC::new(addr, privileges);

两者的差别在于第一个核的上下文只有一个,在PLIC内部,在设置外部中断时,会根据这个上下文计算出正确的偏移。

Reference

plic:https://tinylab.org/riscv-irq-analysis-part2-interrupt-handling-plic/

https://blog.csdn.net/moonllz/article/details/52251788