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:
@@ -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) };
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user