36 lines
1.0 KiB
Rust
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;
|
|
}
|