main.rs 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #![feature(naked_functions, asm_const)]
  2. #![no_std]
  3. #![no_main]
  4. #[macro_use]
  5. extern crate log;
  6. #[macro_use]
  7. mod macros;
  8. mod board;
  9. mod console;
  10. mod dynamic;
  11. mod fail;
  12. mod reset;
  13. mod trap;
  14. use panic_halt as _;
  15. use riscv::register::mstatus;
  16. extern "C" fn main(hart_id: usize, opaque: usize, nonstandard_a2: usize) -> usize {
  17. let _ = (hart_id, opaque);
  18. console::init();
  19. info!("RustSBI version {}", rustsbi::VERSION);
  20. rustsbi::LOGO.lines().for_each(|line| info!("{}", line));
  21. info!("Initializing RustSBI machine-mode environment.");
  22. let info = dynamic::read_paddr(nonstandard_a2).unwrap_or_else(fail::no_dynamic_info_available);
  23. let (mpp, next_addr) = dynamic::mpp_next_addr(&info).unwrap_or_else(fail::invalid_dynamic_data);
  24. info!("Redirecting harts to 0x{:x} in {:?} mode.", next_addr, mpp);
  25. trap::init();
  26. unsafe { mstatus::set_mpp(mpp) };
  27. next_addr
  28. }
  29. const LEN_STACK_PER_HART: usize = 16 * 1024;
  30. pub(crate) const NUM_HART_MAX: usize = 8;
  31. const LEN_STACK: usize = LEN_STACK_PER_HART * NUM_HART_MAX;
  32. // TODO contribute `Stack` struct into the crate `riscv`
  33. #[repr(C, align(128))]
  34. struct Stack<const N: usize>([u8; N]);
  35. #[link_section = ".bss.uninit"]
  36. static STACK: Stack<LEN_STACK> = Stack([0; LEN_STACK]);
  37. #[naked]
  38. #[link_section = ".text.entry"]
  39. #[export_name = "_start"]
  40. unsafe extern "C" fn start() -> ! {
  41. core::arch::asm!(
  42. // 1. Turn off interrupt
  43. " csrw mie, zero",
  44. // 2. Initialize programming langauge runtime
  45. // only clear bss if hartid is zero
  46. " csrr t0, mhartid",
  47. " bnez t0, 2f",
  48. // clear bss segment
  49. " la t0, sbss
  50. la t1, ebss
  51. 1: bgeu t0, t1, 2f
  52. sd zero, 0(t0)
  53. addi t0, t0, 8
  54. j 1b",
  55. // prepare data segment
  56. " la t3, sidata
  57. la t4, sdata
  58. la t5, edata
  59. 1: bgeu t4, t5, 2f
  60. ld t6, 0(t3)
  61. sd t6, 0(t4)
  62. addi t3, t3, 8
  63. addi t4, t4, 8
  64. j 1b",
  65. "2: ",
  66. // 3. Prepare stack for each hart
  67. " la sp, {stack}",
  68. " li t0, {stack_size_per_hart}",
  69. " csrr t1, mhartid",
  70. " addi t1, t1, 1",
  71. "1: ",
  72. " add sp, sp, t0",
  73. " addi t1, t1, -1",
  74. " bnez t1, 1b",
  75. // 4. Run Rust main function
  76. " call {main}",
  77. // 5. Jump to following boot sequences
  78. " csrw mepc, a0",
  79. " mret",
  80. stack_size_per_hart = const LEN_STACK_PER_HART,
  81. stack = sym STACK,
  82. main = sym main,
  83. options(noreturn)
  84. )
  85. }