From 0257911a410fb842902b61c4bb041d9707c5fbff Mon Sep 17 00:00:00 2001 From: CharlyCst Date: Mon, 29 Jan 2024 14:40:30 +0100 Subject: [PATCH] Move entry point (_start) to platform module Move the entry point (the _start function) to the platform specific subfolder, instead of main.rs. This enables platform specific entry points, for instance QEMU will load the hard ID in a0 and the device tree in a1. --- config/linker-script.x | 8 +++----- src/arch/metal.rs | 20 ++++++++++++++++++++ src/main.rs | 26 +++++--------------------- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/config/linker-script.x b/config/linker-script.x index 7f9a8fa5..bf896a07 100644 --- a/config/linker-script.x +++ b/config/linker-script.x @@ -6,16 +6,14 @@ SECTIONS . = 0x80000000; /* Output a text section, starting with the entry point */ - .entry_point : ALIGN(0x1000) { - *(.entry_point) - } .text : ALIGN(0x4) { + _start *(.text) *(.text.*) } /* Output the rodata */ - .rodata : ALIGN(0x1000) { + .rodata : ALIGN(0x8) { KEEP(*(__*)) *(.rodata) *(.rodata.*) @@ -23,7 +21,7 @@ SECTIONS /* Finally, all data */ /* NOTE: no need to page-align bss, both bss and data are RW */ - .data : ALIGN(0x1000) { + .data : ALIGN(0x8) { KEEP(*(__*)) *(.data) *(.data.*) diff --git a/src/arch/metal.rs b/src/arch/metal.rs index c0a1aebe..cdc611e1 100644 --- a/src/arch/metal.rs +++ b/src/arch/metal.rs @@ -5,6 +5,7 @@ use core::ptr; use super::{Architecture, MCause, Mode}; use crate::virt::VirtContext; +use crate::{_stack_end, main}; /// Bare metal RISC-V runtime. pub struct Metal {} @@ -197,6 +198,25 @@ fn read_mtvec() -> usize { return mtvec; } +// —————————————————————————————— Entry Point ——————————————————————————————— // + +global_asm!( +r#" +.text +.global _start +_start: + ld sp, __stack_addr + j {main} + +// Store the address of the stack in memory +// That way it can be loaded as an absolute value +__stack_addr: + .dword {stack} +"#, + main = sym main, + stack = sym _stack_end, +); + // ————————————————————————————— Context Switch ————————————————————————————— // global_asm!( diff --git a/src/main.rs b/src/main.rs index 4a9505f5..0b6c4a16 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,6 @@ mod logger; mod platform; mod virt; -use core::arch::asm; use core::panic::PanicInfo; use arch::{pmpcfg, Arch, Architecture}; @@ -19,31 +18,16 @@ use crate::virt::VirtContext; // Defined in the linker script extern "C" { - static _stack_start: usize; - static _stack_end: usize; + pub(crate) static _stack_start: usize; + pub(crate) static _stack_end: usize; } -#[no_mangle] -#[link_section = ".entry_point"] -pub unsafe extern "C" fn _start() -> ! { - /// Address of the top of the stack (stack grow towerd lower addresses) - static STACK: &'static usize = unsafe { &_stack_end }; - - // Initialize stack pointer and jump into main - // TODO: zero-out the BSS (QEMU might do it for us, but real hardware will not) - asm!( - "mv sp, {stack}", - "j {main}", - main = sym main, - stack = in(reg) STACK, - options(noreturn) - ); -} - -extern "C" fn main() -> ! { +pub(crate) extern "C" fn main(hart_id: usize, device_tree_blob_addr: usize) -> ! { init(); log::info!("Hello, world!"); + log::info!("Hart ID: {}", hart_id); log::info!("mstatus: 0x{:x}", Arch::read_mstatus()); + log::info!("DTS address: 0x{:x}", device_tree_blob_addr); log::info!("Preparing jump into payload"); let payload_addr = Plat::load_payload();