4
0

entry.rs 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. const LEN_STACK_PER_HART: usize = 16 * 1024;
  2. pub const NUM_HART_MAX: usize = 8;
  3. #[link_section = ".bss.uninit"]
  4. static mut STACK: [u8; NUM_HART_MAX * LEN_STACK_PER_HART] = [0; NUM_HART_MAX * LEN_STACK_PER_HART];
  5. // If booted with RISC-V SBI, a0 must include hart ID, while a1 must be an opaque register
  6. #[naked_function::naked]
  7. #[link_section = ".text.entry"]
  8. #[export_name = "_start"]
  9. unsafe extern "C" fn start() -> ! {
  10. asm!(
  11. // 1. Turn off interrupt
  12. " csrw sie, zero",
  13. // 2. Initialize programming language runtime
  14. // only initialize if it is boot hart (hart ID 0)
  15. " bnez a0, 4f",
  16. // clear bss segment
  17. " la t0, sbss
  18. la t1, ebss
  19. 1: bgeu t0, t1, 2f
  20. sd zero, 0(t0)
  21. addi t0, t0, 8
  22. j 1b",
  23. "2:",
  24. // prepare data segment
  25. " la t3, sidata
  26. la t4, sdata
  27. la t5, edata
  28. 3: bgeu t4, t5, 4f
  29. ld t6, 0(t3)
  30. sd t6, 0(t4)
  31. addi t3, t3, 8
  32. addi t4, t4, 8
  33. j 3b",
  34. "4:",
  35. " la sp, {stack}
  36. li t0, {per_hart_stack_size}
  37. addi t1, a0, 1
  38. 5: add sp, sp, t0
  39. addi t1, t1, -1
  40. bnez t1, 5b",
  41. // 4. Start main function
  42. " call {main}",
  43. " call {exit}",
  44. stack = sym STACK,
  45. per_hart_stack_size = const LEN_STACK_PER_HART,
  46. main = sym crate::rust_main,
  47. exit = sym rust_sbi_exit
  48. )
  49. }
  50. #[no_mangle]
  51. extern "C" fn rust_sbi_exit() -> ! {
  52. sbi_rt::system_reset(sbi_rt::Shutdown, sbi_rt::NoReason);
  53. loop {
  54. core::hint::spin_loop();
  55. }
  56. }