/* * kernel_entry.S — kernel stack setup and entry trampoline (riscv64) * * UEFI hands control to kernel_main() running on EDK2's own boot-time stack. * Unlike amd64 (see arch/amd64/kernel_entry.S, which has carried this same * trampoline since early on), riscv64 previously called straight into * kernel_main_impl with no stack switch at all. The VM bootstrap's call * depth (27 chained word-registration modules, physics/SSM init, capsule * birth, Tripod fleet spawn) overflowed EDK2's riscv64 boot stack partway * through vm_init_with_host()'s return, corrupting the return address and * producing a wild jump shortly after — observed as a load/instruction * page fault (scause 0xd or 0xc) whose exact address drifted between * builds while the crash always landed in this same call region. amd64 * never had this problem because kernel_entry.S already switches to a * dedicated 2 MiB BSS stack before anything deep runs; aarch64 apparently * gets away with EDK2's default boot stack being large enough, but that's * incidental, not a guarantee. * * kernel_main is the symbol the UEFI loader calls (extern in uefi_loader.c). * kernel_main_impl is defined in kernel_main.c and contains all the C code. * * Calling convention: RISC-V LP64D — boot_info pointer arrives in a0 and is * passed unchanged to kernel_main_impl via the tail-call. */ #include "starkernel/boot_info_offsets.h" /* 2 MiB kernel stack in BSS — fallback when no dynamic stack requested */ .section .bss .align 4 .global g_kernel_stack g_kernel_stack: .space 0x200000 g_kernel_stack_top: .global g_kernel_stack_top .section .text .extern kernel_main_impl /* * kernel_main — stack-switch trampoline, then tail-call kernel_main_impl. * * a0 = BootInfo* (RISC-V LP64D ABI — first argument register) * * Stack selection (checked in order): * 1. boot_info->kernel_stack_base != 0 → use loader-allocated stack * (top = base + size, aligned down to 16) * 2. Otherwise → fall back to g_kernel_stack (2 MiB BSS) * * Never returns; kernel_main_impl runs the REPL forever or panics. */ .global kernel_main kernel_main: ld t0, BOOT_INFO_KERNEL_STACK_BASE_OFFSET(a0) bnez t0, .Ldynamic_stack /* BSS fallback */ la t0, g_kernel_stack_top j .Lstack_ready .Ldynamic_stack: ld t1, BOOT_INFO_KERNEL_STACK_SIZE_OFFSET(a0) add t0, t0, t1 /* top = base + size (stack grows down) */ .Lstack_ready: andi t0, t0, -16 /* 16-byte alignment (RISC-V psABI requirement) */ mv sp, t0 mv s0, zero /* terminate frame-pointer chain */ tail kernel_main_impl /* a0 (boot_info) already in place */