36 lines
1.0 KiB
Rust

//! The RISC-V Platform Level Interrupt Controller (PLIC)
use crate::{
arch::riscv::{plic_sclaim, plic_senable, plic_spriority, PLIC, UART0_IRQ, VIRTIO0_IRQ},
proc::cpu::cpuid,
};
pub unsafe fn plicinit() {
// Set desired IRQ priorities non-zero (otherwise disabled).
*((PLIC + UART0_IRQ as u64 * 4) as *mut u32) = 1;
*((PLIC + VIRTIO0_IRQ as u64 * 4) as *mut u32) = 1;
}
pub unsafe fn plicinithart() {
let hart = cpuid() as u64;
// Set enable bits for this hart's S-mode
// for the UART and VIRTIO disk.
*(plic_senable(hart) as *mut u32) = (1 << UART0_IRQ) | (1 << VIRTIO0_IRQ);
// Set this hart's S-mode priority threshold to 0.
*(plic_spriority(hart) as *mut u32) = 0;
}
/// Ask the PLIC what interrupt we should serve.
pub unsafe fn plic_claim() -> i32 {
let hart = cpuid() as u64;
*(plic_sclaim(hart) as *const i32)
}
/// Tell the PLIC we've served this IRQ.
pub unsafe fn plic_complete(irq: i32) {
let hart = cpuid() as u64;
*(plic_sclaim(hart) as *mut i32) = irq;
}