From 9d5ad06b30c9c02b6da41862d2f051cd8df43095 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 19 Oct 2025 12:58:13 +0200 Subject: [PATCH] Move some code from the trampoline to global_asm!() --- src/acpi/madt/arch/x86.rs | 8 ++---- src/arch/x86_shared/start.rs | 52 ++++++++++++++++++++++++++++------- src/asm/x86/trampoline.asm | 13 ++------- src/asm/x86_64/trampoline.asm | 4 --- 4 files changed, 46 insertions(+), 31 deletions(-) diff --git a/src/acpi/madt/arch/x86.rs b/src/acpi/madt/arch/x86.rs index 813f920b2a..9cdb550521 100644 --- a/src/acpi/madt/arch/x86.rs +++ b/src/acpi/madt/arch/x86.rs @@ -82,8 +82,8 @@ pub(super) fn init(madt: Madt) { let idt_ptr = crate::arch::idt::allocate_and_init_idt(cpu_id); let args = KernelArgsAp { + stack_end: stack_end as *mut u8, cpu_id, - page_table: page_table_physaddr, pcr_ptr, idt_ptr, }; @@ -91,16 +91,13 @@ pub(super) fn init(madt: Madt) { let ap_ready = (TRAMPOLINE + 8) as *mut u64; let ap_args_ptr = unsafe { ap_ready.add(1) }; let ap_page_table = unsafe { ap_ready.add(2) }; - let ap_stack_end = unsafe { ap_ready.add(3) }; - let ap_code = unsafe { ap_ready.add(4) }; + let ap_code = unsafe { ap_ready.add(3) }; // Set the ap_ready to 0, volatile unsafe { ap_ready.write(0); ap_args_ptr.write(&args as *const _ as u64); ap_page_table.write(page_table_physaddr as u64); - ap_stack_end.write(stack_end as u64); - #[expect(clippy::fn_to_numeric_cast)] ap_code.write(kstart_ap as u64); // TODO: Is this necessary (this fence)? @@ -127,7 +124,6 @@ pub(super) fn init(madt: Madt) { // Send START IPI { - //Start at 0x0800:0000 => 0x8000. Hopefully the bootloader code is still there let ap_segment = (TRAMPOLINE >> 12) & 0xFF; let mut icr = 0x4600 | ap_segment as u64; diff --git a/src/arch/x86_shared/start.rs b/src/arch/x86_shared/start.rs index 24315b8845..b7c8628a7a 100644 --- a/src/arch/x86_shared/start.rs +++ b/src/arch/x86_shared/start.rs @@ -6,6 +6,7 @@ use core::{ arch::global_asm, cell::SyncUnsafeCell, hint, + mem::offset_of, sync::atomic::{AtomicBool, Ordering}, }; @@ -13,13 +14,8 @@ use core::{ use crate::acpi; use crate::{ - allocator, - cpu_set::LogicalCpuId, - device, - devices::graphical_debug, - gdt, idt, interrupt, - paging::{self, PhysicalAddress, RmmA, RmmArch, TableKind}, - startup::KernelArgs, + allocator, cpu_set::LogicalCpuId, device, devices::graphical_debug, gdt, idt, interrupt, + paging, startup::KernelArgs, }; /// Test of zero values in BSS. @@ -171,14 +167,51 @@ unsafe extern "C" fn start(args_ptr: *const KernelArgs, stack_end: usize) -> ! { } pub struct KernelArgsAp { + pub stack_end: *mut u8, pub cpu_id: LogicalCpuId, - pub page_table: usize, pub pcr_ptr: *mut gdt::ProcessorControlRegion, pub idt_ptr: *mut idt::Idt, } +// FIXME use extern "custom" +unsafe extern "C" { + pub fn kstart_ap(); +} + +#[cfg(target_arch = "x86")] +global_asm!(" + .globl kstart_ap + kstart_ap: + mov esp, dword ptr [edi + {args_stack}] + mov [esp + 4], edi + mov [esp + 8], esp + + jmp {start_ap} + ", + args_stack = const offset_of!(KernelArgsAp, stack_end), + start_ap = sym start_ap, +); + +#[cfg(target_arch = "x86_64")] +global_asm!(" + .globl kstart_ap + kstart_ap: + // Note: The System V ABI requires the stack to be aligned to 16 bytes + // before the call instruction. As we jump rather than call it has to + // be offset by 8 bytes. Additionally reserve a bit more space at the + // end of the stack to ensure that the start function returns to + // address 0. + mov rax, qword ptr [rdi + {args_stack}] + lea rsp, [rax - 24] + + jmp {start_ap} + ", + args_stack = const offset_of!(KernelArgsAp, stack_end), + start_ap = sym start_ap, +); + /// Entry to rust for an AP -pub unsafe extern "C" fn kstart_ap(args_ptr: *const KernelArgsAp) -> ! { +unsafe extern "C" fn start_ap(args_ptr: *const KernelArgsAp) -> ! { unsafe { let cpu_id = { let args = &*args_ptr; @@ -190,7 +223,6 @@ pub unsafe extern "C" fn kstart_ap(args_ptr: *const KernelArgsAp) -> ! { idt::install_idt(args.idt_ptr); // Initialize paging - RmmA::set_table(TableKind::Kernel, PhysicalAddress::new(args.page_table)); paging::init(); #[cfg(all(target_arch = "x86_64", feature = "profiling"))] diff --git a/src/asm/x86/trampoline.asm b/src/asm/x86/trampoline.asm index 5b520b960e..8002009d2b 100644 --- a/src/asm/x86/trampoline.asm +++ b/src/asm/x86/trampoline.asm @@ -11,7 +11,6 @@ trampoline: .ready: dq 0 .args_ptr: dq 0 .page_table: dq 0 - .stack_end: dq 0 .code: dq 0 startup_ap: @@ -68,19 +67,11 @@ protected_mode_ap: mov gs, eax mov ss, eax - mov eax, [trampoline.stack_end] - lea esp, [eax - 256] - - mov eax, [trampoline.args_ptr] - push eax + mov edi, [trampoline.args_ptr] mov eax, [trampoline.code] mov dword [trampoline.ready], 1 - call eax -.halt: - cli - hlt - jmp .halt + jmp eax struc GDTEntry .limitl resw 1 diff --git a/src/asm/x86_64/trampoline.asm b/src/asm/x86_64/trampoline.asm index 1e9a708d96..bc762e2b84 100644 --- a/src/asm/x86_64/trampoline.asm +++ b/src/asm/x86_64/trampoline.asm @@ -11,7 +11,6 @@ trampoline: .ready: dq 0 .args_ptr: dq 0 .page_table: dq 0 - .stack_end: dq 0 .code: dq 0 startup_ap: @@ -75,9 +74,6 @@ long_mode_ap: mov gs, rax mov ss, rax - mov rcx, [trampoline.stack_end] - lea rsp, [rcx - 256] - mov rdi, [trampoline.args_ptr] mov rax, [trampoline.code]