main.rs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // A test kernel to test RustSBI function on all platforms
  2. #![feature(naked_functions, global_asm, asm, llvm_asm)]
  3. #![no_std]
  4. #![no_main]
  5. #[macro_use]
  6. mod console;
  7. mod sbi;
  8. use riscv::register::{sepc, stvec::{self, TrapMode}};
  9. use core::panic::PanicInfo;
  10. #[cfg_attr(not(test), panic_handler)]
  11. #[allow(unused)]
  12. fn panic(_info: &PanicInfo) -> ! {
  13. loop {}
  14. }
  15. const BOOT_STACK_SIZE: usize = 4096 * 4 * 8;
  16. static mut BOOT_STACK: [u8; BOOT_STACK_SIZE] = [0; BOOT_STACK_SIZE];
  17. #[naked]
  18. #[link_section = ".text.entry"]
  19. #[export_name = "_start"]
  20. unsafe extern "C" fn entry() -> ! {
  21. asm!("
  22. # 1. set sp
  23. # sp = bootstack + (hartid + 1) * 0x10000
  24. add t0, a0, 1
  25. slli t0, t0, 14
  26. 1: auipc sp, %pcrel_hi({boot_stack})
  27. addi sp, sp, %pcrel_lo(1b)
  28. add sp, sp, t0
  29. # 2. jump to rust_main (absolute address)
  30. 1: auipc t0, %pcrel_hi({rust_main})
  31. addi t0, t0, %pcrel_lo(1b)
  32. jr t0
  33. ",
  34. boot_stack = sym BOOT_STACK,
  35. rust_main = sym rust_main,
  36. options(noreturn))
  37. }
  38. pub extern "C" fn rust_main(hartid: usize, dtb_pa: usize) -> ! {
  39. println!("<< Test-kernel: Hart id = {}, DTB physical address = {:#x}", hartid, dtb_pa);
  40. unsafe { stvec::write(start_trap as usize, TrapMode::Direct) };
  41. println!(">> Test-kernel: Trigger illegal exception");
  42. unsafe { asm!("unimp") };
  43. println!("<< Test-kernel: SBI test success, shutdown");
  44. sbi::shutdown()
  45. }
  46. #[naked]
  47. #[link_section = ".text"]
  48. unsafe extern "C" fn start_trap() {
  49. asm!("
  50. .altmacro
  51. .macro STORE reg, offset
  52. sd \\reg, \\offset* {REGBYTES} (sp)
  53. .endm
  54. .macro LOAD reg, offset
  55. ld \\reg, \\offset* {REGBYTES} (sp)
  56. .endm
  57. addi sp, sp, -16 * {REGBYTES}
  58. STORE ra, 0
  59. STORE t0, 1
  60. STORE t1, 2
  61. STORE t2, 3
  62. STORE t3, 4
  63. STORE t4, 5
  64. STORE t5, 6
  65. STORE t6, 7
  66. STORE a0, 8
  67. STORE a1, 9
  68. STORE a2, 10
  69. STORE a3, 11
  70. STORE a4, 12
  71. STORE a5, 13
  72. STORE a6, 14
  73. STORE a7, 15
  74. mv a0, sp
  75. call {rust_trap_exception}
  76. LOAD ra, 0
  77. LOAD t0, 1
  78. LOAD t1, 2
  79. LOAD t2, 3
  80. LOAD t3, 4
  81. LOAD t4, 5
  82. LOAD t5, 6
  83. LOAD t6, 7
  84. LOAD a0, 8
  85. LOAD a1, 9
  86. LOAD a2, 10
  87. LOAD a3, 11
  88. LOAD a4, 12
  89. LOAD a5, 13
  90. LOAD a6, 14
  91. LOAD a7, 15
  92. addi sp, sp, 16 * {REGBYTES}
  93. sret
  94. ",
  95. REGBYTES = const core::mem::size_of::<usize>(),
  96. rust_trap_exception = sym rust_trap_exception,
  97. options(noreturn))
  98. }
  99. pub extern "C" fn rust_trap_exception() {
  100. println!("<< Test-kernel: Illegal exception");
  101. sepc::write(sepc::read().wrapping_add(4));
  102. }