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

@@ -10,6 +10,7 @@ use types::{
use crate::board;
use crate::hw::{plic::Plic, timer};
use crate::mmu;
use crate::smp;
use crate::trap;
pub struct RiscVPlatform {
@@ -20,9 +21,9 @@ pub struct RiscVPlatform {
}
impl RiscVPlatform {
pub fn new(kernel_pt_addr: usize) -> Self {
pub fn new(kernel_pt_addr: usize, num_cores: u8) -> Self {
Self {
num_cores: 1,
num_cores,
kernel_pt: kernel_pt_addr,
page_tables: [0usize; MAX_PROCESSES],
}
@@ -63,8 +64,10 @@ impl Platform for RiscVPlatform {
let Some(root) = self.root(process) else {
return;
};
// The caller may be tearing down the space we are running on; get
// off it before the kernel frees its frames.
// No hart may still translate through it once the kernel frees its
// frames: other harts leave it (and wait for nothing but that), and
// the caller may be tearing down the space we are running on.
smp::shoot_down(root);
if mmu::active_root() == root {
// SAFETY: the kernel page table lives in the boot heap forever.
mmu::activate(unsafe { &*(self.kernel_pt as *const mmu::PageTable) });
@@ -95,6 +98,8 @@ impl Platform for RiscVPlatform {
fn unmap_page(&mut self, process: ProcessId, va: VirtualAddress) {
if let Some(root) = self.root(process) {
mmu::unmap_user_page(root, va.raw());
// Other harts running this process may still cache it.
smp::shoot_down(root);
}
}
@@ -144,10 +149,12 @@ impl Platform for RiscVPlatform {
Plic::enable(irq.raw() as u32);
}
fn send_ipi(&mut self, _target: CoreId) {}
fn send_ipi(&mut self, target: CoreId) {
smp::kick(target.raw() as usize);
}
fn core_id(&self) -> CoreId {
CoreId::from_raw(0)
CoreId::from_raw(smp::hart_id() as u8)
}
fn num_cores(&self) -> u8 {