trap.rs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. use core::arch::asm;
  2. use riscv::register::{
  3. mstatus::Mstatus,
  4. mtvec::{self, TrapMode},
  5. };
  6. // Typically, the `stvec` Will be overrided by supervisor software, e.g. kernel, hypervisor or secure environments.
  7. pub fn init() {
  8. let mut addr = machine_trap as usize;
  9. if addr & 0b10 != 0 {
  10. addr += 0b10; // mtvec base address must align to 4 bytes.
  11. }
  12. unsafe { mtvec::write(addr, TrapMode::Direct) };
  13. }
  14. extern "C" fn rust_machine_trap(ctx: &mut SupervisorContext) {
  15. error!("ctx: {:x?}", ctx);
  16. }
  17. #[naked]
  18. unsafe extern "C" fn machine_trap() -> ! {
  19. asm!(
  20. ".align 2",
  21. "csrrw sp, mscratch, sp",
  22. "sd ra, 0*8(sp)
  23. sd gp, 2*8(sp)
  24. sd tp, 3*8(sp)
  25. sd t0, 4*8(sp)
  26. sd t1, 5*8(sp)
  27. sd t2, 6*8(sp)
  28. sd s0, 7*8(sp)
  29. sd s1, 8*8(sp)
  30. sd a0, 9*8(sp)
  31. sd a1, 10*8(sp)
  32. sd a2, 11*8(sp)
  33. sd a3, 12*8(sp)
  34. sd a4, 13*8(sp)
  35. sd a5, 14*8(sp)
  36. sd a6, 15*8(sp)
  37. sd a7, 16*8(sp)
  38. sd s2, 17*8(sp)
  39. sd s3, 18*8(sp)
  40. sd s4, 19*8(sp)
  41. sd s5, 20*8(sp)
  42. sd s6, 21*8(sp)
  43. sd s7, 22*8(sp)
  44. sd s8, 23*8(sp)
  45. sd s9, 24*8(sp)
  46. sd s10, 25*8(sp)
  47. sd s11, 26*8(sp)
  48. sd t3, 27*8(sp)
  49. sd t4, 28*8(sp)
  50. sd t5, 29*8(sp)
  51. sd t6, 30*8(sp)",
  52. "csrr t0, mstatus
  53. sd t0, 31*8(sp)",
  54. "csrr t1, mepc
  55. sd t1, 32*8(sp)",
  56. "csrr t2, mscratch",
  57. "sd t2, 1*8(sp)",
  58. "mv a0, sp",
  59. "call {rust_machine_trap}",
  60. "ld t0, 31*8(sp)
  61. ld t1, 32*8(sp)
  62. csrw mstatus, t0
  63. csrw mepc, t1",
  64. "ld ra, 0*8(sp)
  65. ld gp, 2*8(sp)
  66. ld tp, 3*8(sp)
  67. ld t0, 4*8(sp)
  68. ld t1, 5*8(sp)
  69. ld t2, 6*8(sp)
  70. ld s0, 7*8(sp)
  71. ld s1, 8*8(sp)
  72. ld a0, 9*8(sp)
  73. ld a1, 10*8(sp)
  74. ld a2, 11*8(sp)
  75. ld a3, 12*8(sp)
  76. ld a4, 13*8(sp)
  77. ld a5, 14*8(sp)
  78. ld a6, 15*8(sp)
  79. ld a7, 16*8(sp)
  80. ld s2, 17*8(sp)
  81. ld s3, 18*8(sp)
  82. ld s4, 19*8(sp)
  83. ld s5, 20*8(sp)
  84. ld s6, 21*8(sp)
  85. ld s7, 22*8(sp)
  86. ld s8, 23*8(sp)
  87. ld s9, 24*8(sp)
  88. ld s10, 25*8(sp)
  89. ld s11, 26*8(sp)
  90. ld t3, 27*8(sp)
  91. ld t4, 28*8(sp)
  92. ld t5, 29*8(sp)
  93. ld t6, 30*8(sp)",
  94. "csrrw sp, mscratch, sp",
  95. "mret",
  96. rust_machine_trap = sym rust_machine_trap,
  97. options(noreturn)
  98. );
  99. }
  100. #[derive(Debug)]
  101. #[repr(C)]
  102. pub struct SupervisorContext {
  103. pub ra: usize, // 0
  104. pub sp: usize,
  105. pub gp: usize,
  106. pub tp: usize,
  107. pub t0: usize,
  108. pub t1: usize,
  109. pub t2: usize,
  110. pub s0: usize,
  111. pub s1: usize,
  112. pub a0: usize,
  113. pub a1: usize,
  114. pub a2: usize,
  115. pub a3: usize,
  116. pub a4: usize,
  117. pub a5: usize,
  118. pub a6: usize,
  119. pub a7: usize,
  120. pub s2: usize,
  121. pub s3: usize,
  122. pub s4: usize,
  123. pub s5: usize,
  124. pub s6: usize,
  125. pub s7: usize,
  126. pub s8: usize,
  127. pub s9: usize,
  128. pub s10: usize,
  129. pub s11: usize,
  130. pub t3: usize,
  131. pub t4: usize,
  132. pub t5: usize,
  133. pub t6: usize, // 30
  134. pub mstatus: Mstatus, // 31
  135. pub mepc: usize, // 32
  136. }