Browse Source

Dump all trap frame registers when exception happened in reference implementations

luojia65 3 years ago
parent
commit
7eec516d16
4 changed files with 41 additions and 8 deletions
  1. 2 0
      CHANGELOG.md
  2. 16 2
      platform/k210/src/main.rs
  3. 21 4
      platform/qemu/src/main.rs
  4. 2 2
      rustsbi/src/privileged.rs

+ 2 - 0
CHANGELOG.md

@@ -21,6 +21,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - Align to 4 bytes for interrupt handler on QEMU and test kernel
 - Update `riscv` crate dependency for QEMU platform
 - Use `mtval` to read instruction on QEMU; still need to be kept on K210 as 1.9.1 does not define this register behavior
+- Modify second parameter of `enter_privileged` to `opaque` other than `dtb_pa`
+- Dump all trap frame registers when exception happened in reference implementations
 
 ### Fixed
 - Test kernel console now will lock before `println` line is finished

+ 16 - 2
platform/k210/src/main.rs

@@ -360,6 +360,16 @@ struct TrapFrame {
     a7: usize,
 }
 
+impl core::fmt::Display for TrapFrame {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        writeln!(f, "")?;
+        writeln!(f, "ra: {:016x}, t0: {:016x}, t1: {:016x}, t2: {:016x}", self.ra, self.t0, self.t1, self.t2)?;
+        writeln!(f, "t3: {:016x}, t4: {:016x}, t5: {:016x}, t6: {:016x}", self.t3, self.t4, self.t5, self.t6)?;
+        writeln!(f, "a0: {:016x}, a1: {:016x}, a2: {:016x}, a3: {:016x}", self.a0, self.a1, self.a2, self.a3)?;
+        writeln!(f, "a4: {:016x}, a5: {:016x}, a6: {:016x}, a7: {:016x}", self.a4, self.a5, self.a6, self.a7)
+    }
+}
+
 #[export_name = "_start_trap_rust"]
 extern "C" fn start_trap_rust(trap_frame: &mut TrapFrame) {
     let cause = mcause::read().cause();
@@ -514,14 +524,18 @@ extern "C" fn start_trap_rust(trap_frame: &mut TrapFrame) {
                     mepc::write(stvec::read().address());
                 };
             } else { // 真正来自M特权层的异常
-                panic!("invalid instruction! mepc: {:016x?}, instruction: {:08x?}", mepc::read(), ins);
+                panic!(
+                    "invalid instruction from machine level, mepc: {:016x?}, instruction: {:08x?}, trap frame: {}", 
+                    mepc::read(), ins, trap_frame
+                );
             }
         }
         cause => panic!(
-            "unhandled trap! mcause: {:?}, mepc: {:016x?}, mtval: {:016x?}",
+            "unhandled trap, mcause: {:?}, mepc: {:016x?}, mtval: {:016x?}, trap frame: {}",
             cause,
             mepc::read(),
             mtval::read(),
+            trap_frame
         ),
     }
 }

+ 21 - 4
platform/qemu/src/main.rs

@@ -402,6 +402,24 @@ impl TrapFrame {
     }
 }
 
+impl core::fmt::Display for TrapFrame {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        writeln!(f, "")?;
+        #[cfg(target_pointer_width = "64")] {
+            writeln!(f, "ra: {:016x}, t0: {:016x}, t1: {:016x}, t2: {:016x}", self.ra, self.t0, self.t1, self.t2)?;
+            writeln!(f, "t3: {:016x}, t4: {:016x}, t5: {:016x}, t6: {:016x}", self.t3, self.t4, self.t5, self.t6)?;
+            writeln!(f, "a0: {:016x}, a1: {:016x}, a2: {:016x}, a3: {:016x}", self.a0, self.a1, self.a2, self.a3)?;
+            writeln!(f, "a4: {:016x}, a5: {:016x}, a6: {:016x}, a7: {:016x}", self.a4, self.a5, self.a6, self.a7)
+        }
+        #[cfg(target_pointer_width = "32")] {
+            writeln!(f, "ra: {:08x}, t0: {:08x}, t1: {:08x}, t2: {:08x}", self.ra, self.t0, self.t1, self.t2)?;
+            writeln!(f, "t3: {:08x}, t4: {:08x}, t5: {:08x}, t6: {:08x}", self.t3, self.t4, self.t5, self.t6)?;
+            writeln!(f, "a0: {:08x}, a1: {:08x}, a2: {:08x}, a3: {:08x}", self.a0, self.a1, self.a2, self.a3)?;
+            writeln!(f, "a4: {:08x}, a5: {:08x}, a6: {:08x}, a7: {:08x}", self.a4, self.a5, self.a6, self.a7)
+        }
+    }
+}
+
 #[export_name = "_start_trap_rust"]
 extern "C" fn start_trap_rust(trap_frame: &mut TrapFrame) {
     let cause = mcause::read().cause();
@@ -479,18 +497,17 @@ extern "C" fn start_trap_rust(trap_frame: &mut TrapFrame) {
             } else {
                 // 真·非法指令异常,是M层出现的
                 #[cfg(target_pointer_width = "64")]
-                panic!("invalid instruction, mepc: {:016x?}, instruction: {:016x?}", mepc::read(), ins);
+                panic!("invalid instruction from machine level, mepc: {:016x?}, instruction: {:016x?}, trap frame: {}", mepc::read(), ins, trap_frame);
                 #[cfg(target_pointer_width = "32")]
-                panic!("invalid instruction, mepc: {:08x?}, instruction: {:08x?}", mepc::read(), ins);
+                panic!("invalid instruction from machine level, mepc: {:08x?}, instruction: {:08x?}, trap frame: {}", mepc::read(), ins, trap_frame);
             }
         }
         #[cfg(target_pointer_width = "64")]
         cause => panic!(
-            "Unhandled exception! mcause: {:?}, mepc: {:016x?}, mtval: {:016x?}, trap frame: {:p}, {:x?}",
+            "Unhandled exception! mcause: {:?}, mepc: {:016x?}, mtval: {:016x?}, trap frame: {:x?}",
             cause,
             mepc::read(),
             mtval::read(),
-            &trap_frame as *const _,
             trap_frame
         ),
         #[cfg(target_pointer_width = "32")]

+ 2 - 2
rustsbi/src/privileged.rs

@@ -24,13 +24,13 @@
 /// }
 /// ```
 #[inline]
-pub unsafe fn enter_privileged(mhartid: usize, dtb_pa: usize) -> ! {
+pub unsafe fn enter_privileged(mhartid: usize, opaque: usize) -> ! {
     match () {
         #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
         () => asm!("
             csrrw   sp, mscratch, sp
             mret
-        ", in("a0") mhartid, in("a1") dtb_pa, options(nomem, noreturn)),
+        ", in("a0") mhartid, in("a1") opaque, options(nomem, noreturn)),
         #[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
         () => {
             drop(mhartid);