feat: SMP stage 1 (4 harts, per-hart guarded stacks, home-core affinity, IPIs, TLB shootdown, one temporary kernel lock), 4-core storm

This commit is contained in:
2026-10-27 00:56:15 +01:00
parent b87a62475f
commit 2e665fd66e
22 changed files with 995 additions and 230 deletions

View File

@@ -2,21 +2,36 @@ use crate::board;
const PLIC: usize = crate::mmu::phys_to_virt(board::PLIC_BASE);
const PLIC_PRIORITY: usize = PLIC;
const PLIC_S_ENABLE: usize = PLIC + 0x2080;
const PLIC_S_THRESHOLD: usize = PLIC + 0x201000;
const PLIC_S_CLAIM: usize = PLIC + 0x201004;
// External interrupts go to the boot hart only: its supervisor context is
// 2 * hart + 1 on QEMU virt (even contexts are machine mode).
fn context() -> usize {
2 * crate::smp::boot_hart() + 1
}
fn enable_base() -> usize {
PLIC + 0x2000 + context() * 0x80
}
fn threshold() -> usize {
PLIC + 0x20_0000 + context() * 0x1000
}
fn claim_reg() -> usize {
threshold() + 4
}
pub struct Plic;
impl Plic {
pub fn init() {
unsafe { core::ptr::write_volatile(PLIC_S_THRESHOLD as *mut u32, 0) };
unsafe { core::ptr::write_volatile(threshold() as *mut u32, 0) };
}
pub fn enable(irq: u32) {
let word = (irq / 32) as usize;
let bit = irq % 32;
let addr = PLIC_S_ENABLE + word * 4;
let addr = enable_base() + word * 4;
unsafe {
let current = core::ptr::read_volatile(addr as *const u32);
core::ptr::write_volatile(addr as *mut u32, current | (1 << bit));
@@ -28,7 +43,7 @@ impl Plic {
pub fn disable(irq: u32) {
let word = (irq / 32) as usize;
let bit = irq % 32;
let addr = PLIC_S_ENABLE + word * 4;
let addr = enable_base() + word * 4;
unsafe {
let current = core::ptr::read_volatile(addr as *const u32);
core::ptr::write_volatile(addr as *mut u32, current & !(1 << bit));
@@ -36,10 +51,10 @@ impl Plic {
}
pub fn claim() -> u32 {
unsafe { core::ptr::read_volatile(PLIC_S_CLAIM as *const u32) }
unsafe { core::ptr::read_volatile(claim_reg() as *const u32) }
}
pub fn complete(irq: u32) {
unsafe { core::ptr::write_volatile(PLIC_S_CLAIM as *mut u32, irq) };
unsafe { core::ptr::write_volatile(claim_reg() as *mut u32, irq) };
}
}