diff --git a/src/arch/aarch64/start.rs b/src/arch/aarch64/start.rs index eec13f801a..cd0b6828b6 100644 --- a/src/arch/aarch64/start.rs +++ b/src/arch/aarch64/start.rs @@ -3,6 +3,7 @@ //! It must create the IDT with the correct entries, those entries are //! defined in other files inside of the `arch` module use core::{ + arch::global_asm, slice, sync::atomic::{AtomicBool, Ordering}, }; @@ -21,19 +22,35 @@ static mut DATA_TEST_NONZERO: usize = 0xFFFF_FFFF_FFFF_FFFF; pub static AP_READY: AtomicBool = AtomicBool::new(false); static BSP_READY: AtomicBool = AtomicBool::new(false); +global_asm!(" + .globl kstart + kstart: + // BSS should already be zero + adrp x9, {bss_test_zero} + ldr x9, [x9, :lo12:{bss_test_zero}] + cbnz x9, .Lkstart_crash + adrp x9, {data_test_nonzero} + ldr x9, [x9, :lo12:{data_test_nonzero}] + cbz x9, .Lkstart_crash + + mov lr, 0 + b {start} + + .Lkstart_crash: + mov x9, 0 + br x9 + ", + bss_test_zero = sym BSS_TEST_ZERO, + data_test_nonzero = sym DATA_TEST_NONZERO, + start = sym start, +); + /// The entry to Rust, all things must be initialized -#[unsafe(no_mangle)] -pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! { +unsafe extern "C" fn start(args_ptr: *const KernelArgs) -> ! { unsafe { let bootstrap = { let args = args_ptr.read(); - // BSS should already be zero - { - assert_eq!(BSS_TEST_ZERO, 0); - assert_eq!(DATA_TEST_NONZERO, 0xFFFF_FFFF_FFFF_FFFF); - } - // Set up graphical debug graphical_debug::init(args.env()); diff --git a/src/arch/riscv64/start.rs b/src/arch/riscv64/start.rs index 2ef6e2b035..3af8e917cc 100644 --- a/src/arch/riscv64/start.rs +++ b/src/arch/riscv64/start.rs @@ -1,9 +1,7 @@ use core::{ - arch::asm, - slice, + arch::{asm, global_asm}, sync::atomic::{AtomicUsize, Ordering}, }; -use fdt::Fdt; use crate::{ allocator, @@ -38,13 +36,34 @@ fn get_boot_hart_id(env: &[u8]) -> Option { None } +global_asm!(" + .globl kstart + kstart: + mv gp, x0 // ensure gp relative accesses crash + mv tp, x0 // reset percpu until it is initialized + csrw sscratch, tp + + // BSS should already be zero + ld t0, {bss_test_zero} + bnez t0, .Lkstart_crash + ld t0, {data_test_nonzero} + beqz t0, .Lkstart_crash + + li ra, 0 + j {start} + + .Lkstart_crash: + jr x0 + ", + bss_test_zero = sym BSS_TEST_ZERO, + data_test_nonzero = sym DATA_TEST_NONZERO, + start = sym start, +); + /// The entry to Rust, all things must be initialized -#[unsafe(no_mangle)] -pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! { +unsafe extern "C" fn start(args_ptr: *const KernelArgs) -> ! { unsafe { asm!( - "mv tp, x0", // reset percpu until it is initialized - "csrw sscratch, tp", "sd x0, -16(fp)", // and stop frame walker here "sd x0, -8(fp)", ); @@ -52,12 +71,6 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! { let bootstrap = { let args = args_ptr.read(); - // BSS should already be zero - { - assert_eq!(BSS_TEST_ZERO, 0); - assert_eq!(DATA_TEST_NONZERO, 0xFFFF_FFFF_FFFF_FFFF); - } - let dtb_data = if args.hwdesc_base != 0 { Some(( crate::PHYS_OFFSET + args.hwdesc_base as usize, diff --git a/src/arch/x86_shared/start.rs b/src/arch/x86_shared/start.rs index 8317c7361b..3c858b043e 100644 --- a/src/arch/x86_shared/start.rs +++ b/src/arch/x86_shared/start.rs @@ -3,6 +3,7 @@ //! It must create the IDT with the correct entries, those entries are //! defined in other files inside of the `arch` module use core::{ + arch::global_asm, cell::SyncUnsafeCell, hint, sync::atomic::{AtomicBool, Ordering}, @@ -29,19 +30,54 @@ static DATA_TEST_NONZERO: SyncUnsafeCell = SyncUnsafeCell::new(usize::max pub static AP_READY: AtomicBool = AtomicBool::new(false); static BSP_READY: AtomicBool = AtomicBool::new(false); +#[cfg(target_arch = "x86")] +global_asm!(" + .globl kstart + kstart: + // BSS should already be zero + cmp dword ptr [{bss_test_zero}], 0 + jne .Lkstart_crash + cmp dword ptr [{data_test_nonzero}], 0 + je .Lkstart_crash + + jmp {start} + + .Lkstart_crash: + mov eax, 0 + jmp eax + ", + bss_test_zero = sym BSS_TEST_ZERO, + data_test_nonzero = sym DATA_TEST_NONZERO, + start = sym start, +); + +#[cfg(target_arch = "x86_64")] +global_asm!(" + .globl kstart + kstart: + // BSS should already be zero + cmp qword ptr [rip + {bss_test_zero}], 0 + jne .Lkstart_crash + cmp qword ptr [rip + {data_test_nonzero}], 0 + je .Lkstart_crash + + jmp {start} + + .Lkstart_crash: + mov rax, 0 + jmp rax + ", + bss_test_zero = sym BSS_TEST_ZERO, + data_test_nonzero = sym DATA_TEST_NONZERO, + start = sym start, +); + /// The entry to Rust, all things must be initialized -#[unsafe(no_mangle)] -pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! { +unsafe extern "C" fn start(args_ptr: *const KernelArgs) -> ! { unsafe { let bootstrap = { let args = args_ptr.read(); - // BSS should already be zero - { - assert_eq!(BSS_TEST_ZERO.get().read(), 0); - assert_eq!(DATA_TEST_NONZERO.get().read(), usize::max_value()); - } - // Set up serial debug device::serial::init(); @@ -123,8 +159,6 @@ pub unsafe extern "C" fn kstart_ap(args_ptr: *const KernelArgsAp) -> ! { unsafe { let cpu_id = { let args = &*args_ptr; - assert_eq!(BSS_TEST_ZERO.get().read(), 0); - assert_eq!(DATA_TEST_NONZERO.get().read(), usize::max_value()); // Set up GDT gdt::install_pcr(args.pcr_ptr);