wake application processors to long mode

INIT-SIPI-SIPI plus a self-relocating real-mode trampoline.
This commit is contained in:
Daniel Samson
2026-07-08 12:35:30 +01:00
parent 36c29d2d6d
commit ed7f542006
12 changed files with 482 additions and 8 deletions
+22
View File
@@ -13,6 +13,7 @@ const serial = @import("serial.zig");
const apic = @import("apic.zig");
const ioapic = @import("ioapic.zig");
const io = @import("io.zig");
const smp = @import("smp.zig");
/// The saved register/trap frame passed to a fault handler.
pub const CpuState = idt.CpuState;
@@ -99,6 +100,27 @@ pub fn cpuLocal() usize {
return io.rdmsr(ia32_gs_base);
}
// --- SMP: application-processor bring-up ----------------------------------
/// Make a low RAM page executable (clear its NX bit) — the AP trampoline is fetched
/// from it under paging. Delegates to the VMM; see paging.setExecutable.
pub fn setPageExecutable(phys: u64) void {
paging.setExecutable(phys);
}
/// Copy the AP trampoline into its low page (allocated + made executable by the
/// caller). Run once before waking any application processor.
pub fn prepareSecondaries(tramp_phys: u64) void {
smp.prepare(tramp_phys);
}
/// Wake the core with Local APIC id `apic_id`, giving it `stack_top` and its per-CPU
/// pointer `percpu`; it adopts the current (kernel) page tables. Returns false if it
/// doesn't come online within the timeout. Blocks until the core reports in.
pub fn startSecondary(apic_id: u32, stack_top: usize, percpu: usize) bool {
return smp.startAp(apic_id, stack_top, percpu, readCr3());
}
/// Kernel tick rate: 1000 Hz (1 ms), the scheduler's time quantum.
pub const timer_hz = 1000;