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:
@@ -8,12 +8,21 @@ unsafe extern "C" {
|
||||
static _heap_start: u8;
|
||||
}
|
||||
|
||||
pub fn init(uart: &Uart) -> &'static mut mmu::PageTable {
|
||||
pub fn init(uart: &Uart, boot_hart: usize) -> &'static mut mmu::PageTable {
|
||||
zero_bss();
|
||||
|
||||
let heap_start = unsafe { &_heap_start as *const u8 as usize };
|
||||
mmu::init_allocator(heap_start);
|
||||
let kernel_pt = mmu::init_kernel_page_table();
|
||||
let harts = crate::smp::probe_harts();
|
||||
if boot_hart >= harts {
|
||||
crate::halt(uart, "boot hart outside the hart range");
|
||||
}
|
||||
crate::smp::init(
|
||||
boot_hart,
|
||||
harts,
|
||||
mmu::virt_to_phys(kernel_pt as *const mmu::PageTable as usize),
|
||||
);
|
||||
mmu::activate(kernel_pt);
|
||||
uart.write_str("k-os: MMU enabled (Sv39)\n");
|
||||
match mmu::check_wx(kernel_pt) {
|
||||
@@ -46,7 +55,8 @@ pub fn init(uart: &Uart) -> &'static mut mmu::PageTable {
|
||||
if board::USER_POOL_PAGES > domain::memory::frame::MAX_FRAMES {
|
||||
crate::halt(uart, "user pool larger than the frame table");
|
||||
}
|
||||
let riscv_platform = platform::RiscVPlatform::new(kernel_pt as *const mmu::PageTable as usize);
|
||||
let riscv_platform =
|
||||
platform::RiscVPlatform::new(kernel_pt as *const mmu::PageTable as usize, harts as u8);
|
||||
// SAFETY: `init_in_place` writes every field of the kernel.
|
||||
unsafe {
|
||||
KERNEL.init_with(|slot| {
|
||||
|
||||
@@ -13,7 +13,6 @@ const MAX_FILE_SIZE: usize = 64 * 1024;
|
||||
|
||||
pub struct LoadedProcess {
|
||||
pub pid: ProcessId,
|
||||
pub entry: usize,
|
||||
}
|
||||
|
||||
fn kern() -> &'static mut kernel::Kernel<crate::platform::RiscVPlatform> {
|
||||
@@ -48,7 +47,7 @@ pub fn load_init(uart: &Uart, blk: &mut VirtioBlk) -> (LoadedProcess, ThreadId)
|
||||
setup_thread(tid, entry);
|
||||
uart.write_str("k-os: init loaded\n");
|
||||
|
||||
(LoadedProcess { pid, entry }, tid)
|
||||
(LoadedProcess { pid }, tid)
|
||||
}
|
||||
|
||||
pub fn load_server(
|
||||
@@ -69,35 +68,7 @@ pub fn load_server(
|
||||
uart.write_str(label);
|
||||
uart.write_str(" loaded\n");
|
||||
|
||||
LoadedProcess { pid, entry }
|
||||
}
|
||||
|
||||
pub fn enter_userspace(pid: ProcessId, entry: usize, shared_buf_va: usize) -> ! {
|
||||
let pt_addr = kern().platform_mut().page_table_for(pid);
|
||||
if pt_addr != 0 {
|
||||
mmu::activate(mmu::page_table::table_at(pt_addr));
|
||||
}
|
||||
|
||||
let kernel_sp: usize;
|
||||
unsafe { core::arch::asm!("mv {0}, sp", out(reg) kernel_sp) };
|
||||
crate::trap::set_kernel_stack(kernel_sp);
|
||||
|
||||
unsafe {
|
||||
core::arch::asm!(
|
||||
"csrc sstatus, {spp}",
|
||||
"csrs sstatus, {spie}",
|
||||
"csrw sepc, {entry}",
|
||||
"mv sp, {stack}",
|
||||
"mv a0, {arg}",
|
||||
"sret",
|
||||
spp = in(reg) 1usize << 8,
|
||||
spie = in(reg) 1usize << 5,
|
||||
entry = in(reg) entry,
|
||||
stack = in(reg) USER_VA_BASE,
|
||||
arg = in(reg) shared_buf_va,
|
||||
options(noreturn),
|
||||
);
|
||||
}
|
||||
LoadedProcess { pid }
|
||||
}
|
||||
|
||||
fn setup_thread(tid: ThreadId, entry: usize) {
|
||||
|
||||
Reference in New Issue
Block a user