123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- #![no_std]
- #![no_main]
- // TODO: RustSBI EFI module
- #[no_mangle]
- extern "C" fn rust_main(_hart_id: usize, _opaque: usize) {
- // TODO
- }
- #[no_mangle]
- extern "C" fn rust_sbi_exit() -> ! {
- sbi_rt::system_reset(sbi_rt::Shutdown, sbi_rt::NoReason);
- loop {
- core::hint::spin_loop();
- }
- }
- #[panic_handler]
- fn panic(_info: &core::panic::PanicInfo) -> ! {
- // TODO panic handler
- loop {
- core::hint::spin_loop();
- }
- }
- const LEN_STACK_PER_HART: usize = 16 * 1024;
- pub const NUM_HART_MAX: usize = 8;
- #[link_section = ".bss.uninit"]
- static mut STACK: [u8; NUM_HART_MAX * LEN_STACK_PER_HART] = [0; NUM_HART_MAX * LEN_STACK_PER_HART];
- // If booted with RISC-V SBI, a0 must include hart ID, while a1 must be an opaque register
- #[naked_function::naked]
- #[link_section = ".text.entry"]
- #[export_name = "_start"]
- unsafe extern "C" fn start() -> ! {
- asm!(
- // 1. Turn off interrupt
- " csrw sie, zero",
- // 2. Initialize programming language runtime
- // only initialize if it is boot hart (hart ID 0)
- " bnez a0, 3f",
- // clear bss segment
- " la t0, sbss
- la t1, ebss
- 2: bgeu t0, t1, 2f
- sd zero, 0(t0)
- addi t0, t0, 8
- j 2b",
- // prepare data segment
- " la t3, sidata
- la t4, sdata
- la t5, edata
- 2: bgeu t4, t5, 2f
- ld t6, 0(t3)
- sd t6, 0(t4)
- addi t3, t3, 8
- addi t4, t4, 8
- j 2b",
- "3:",
- // 3. Prepare stack for each hart
- " la sp, {stack}
- li t1, {per_hart_stack_size}
- addi t2, a0, 1
- 2: add sp, sp, t1
- addi t2, t2, -1
- bnez t2, 2b",
- // 4. Start main function
- " call {main}",
- " call {exit}",
- stack = sym STACK,
- per_hart_stack_size = const LEN_STACK_PER_HART,
- main = sym rust_main,
- exit = sym rust_sbi_exit
- )
- }
|