Browse Source

Merge pull request #64 from woshiluo/bump-riscv

feat: bump `riscv` to 1.12.1
guttatus 1 month ago
parent
commit
472f2bd23f
4 changed files with 69 additions and 41 deletions
  1. 13 1
      Cargo.lock
  2. 1 1
      prototyper/Cargo.toml
  3. 12 0
      prototyper/src/fail.rs
  4. 43 39
      prototyper/src/sbi/trap/mod.rs

+ 13 - 1
Cargo.lock

@@ -407,6 +407,7 @@ dependencies = [
  "critical-section",
  "embedded-hal 1.0.0",
  "paste",
+ "riscv-macros",
  "riscv-pac",
 ]
 
@@ -416,6 +417,17 @@ version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cf8b4cfb0da0528321d22daee4299a23a8c5ac8848623d716e898d2a9eec0694"
 
+[[package]]
+name = "riscv-macros"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f265be5d634272320a7de94cea15c22a3bfdd4eb42eb43edc528415f066a1f25"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "riscv-pac"
 version = "0.2.0"
@@ -470,7 +482,7 @@ dependencies = [
  "fast-trap",
  "log",
  "panic-halt",
- "riscv 0.11.1",
+ "riscv 0.12.1",
  "riscv-decode",
  "rustsbi",
  "sbi-spec 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)",

+ 1 - 1
prototyper/Cargo.toml

@@ -12,7 +12,7 @@ forced-target = "riscv64imac-unknown-none-elf"
 aclint = "=0.1.0"
 log = "0.4"
 panic-halt = "1.0.0"
-riscv = "0.11.1"
+riscv = "0.12.1"
 sifive-test-device = "0.0.0"
 spin = "0.9.8"
 uart16550 = "0.0.1"

+ 12 - 0
prototyper/src/fail.rs

@@ -3,6 +3,9 @@ use serde_device_tree::Dtb;
 
 use crate::devicetree;
 
+use riscv::interrupt::machine::{Exception, Interrupt};
+use riscv::register::{mcause::Trap, mepc, mtval};
+
 #[cfg(all(feature = "payload", feature = "jump"))]
 compile_error!("feature \"payload\" and feature \"jump\" cannot be enabled at the same time");
 
@@ -19,6 +22,15 @@ fn panic(info: &core::panic::PanicInfo) -> ! {
     loop {}
 }
 
+pub fn unsupported_trap(trap: Option<Trap<Interrupt, Exception>>) -> ! {
+    error!("-----------------------------");
+    error!("trap:    {trap:?}");
+    error!("mepc:    {:#018x}", mepc::read());
+    error!("mtval:   {:#018x}", mtval::read());
+    error!("-----------------------------");
+    panic!("Stopped with unsupported trap")
+}
+
 /// Handles device tree format parsing errors by logging and resetting.
 #[cold]
 pub fn device_tree_format(_err: devicetree::ParseDeviceTreeError) -> Dtb {

+ 43 - 39
prototyper/src/sbi/trap/mod.rs

@@ -1,10 +1,13 @@
 pub mod boot;
 pub mod handler;
 
+use crate::fail::unsupported_trap;
+
 use fast_trap::{FastContext, FastResult};
+use riscv::interrupt::machine::{Exception, Interrupt};
 use riscv::register::{
-    mcause::{self, Exception as E, Interrupt, Trap as T},
-    mepc, mip, mstatus, mtval,
+    mcause::{self, Trap},
+    mepc, mip, mstatus,
 };
 
 /// Fast trap handler for all trap.
@@ -25,47 +28,48 @@ pub extern "C" fn fast_handler(
         ctx.regs().a = [ctx.a0(), a1, a2, a3, a4, a5, a6, a7];
     };
 
-    match mcause::read().cause() {
-        // Handle Msoft
-        T::Interrupt(Interrupt::MachineSoft) => {
-            save_regs(&mut ctx);
-            handler::msoft_handler(ctx)
-        }
-        // Handle MTimer
-        T::Interrupt(Interrupt::MachineTimer) => {
-            use crate::sbi::ipi;
+    match mcause::read().cause().try_into() {
+        Ok(cause) => {
+            match cause {
+                // Handle Msoft
+                Trap::Interrupt(Interrupt::MachineSoft) => {
+                    save_regs(&mut ctx);
+                    handler::msoft_handler(ctx)
+                }
+                // Handle MTimer
+                Trap::Interrupt(Interrupt::MachineTimer) => {
+                    use crate::sbi::ipi;
 
-            ipi::clear_mtime();
-            unsafe {
-                mip::clear_stimer();
-            }
-            save_regs(&mut ctx);
-            ctx.restore()
-        }
-        // Handle SBI calls
-        T::Exception(E::SupervisorEnvCall) => {
-            handler::sbi_call_handler(ctx, a1, a2, a3, a4, a5, a6, a7)
-        }
-        // Handle illegal instructions
-        T::Exception(E::IllegalInstruction) => {
-            if mstatus::read().mpp() == mstatus::MPP::Machine {
-                panic!("Cannot handle illegal instruction exception from M-MODE");
-            }
+                    ipi::clear_mtime();
+                    unsafe {
+                        mip::clear_stimer();
+                    }
+                    save_regs(&mut ctx);
+                    ctx.restore()
+                }
+                // Handle SBI calls
+                Trap::Exception(Exception::SupervisorEnvCall) => {
+                    handler::sbi_call_handler(ctx, a1, a2, a3, a4, a5, a6, a7)
+                }
+                // Handle illegal instructions
+                Trap::Exception(Exception::IllegalInstruction) => {
+                    if mstatus::read().mpp() == mstatus::MPP::Machine {
+                        panic!("Cannot handle illegal instruction exception from M-MODE");
+                    }
 
-            save_regs(&mut ctx);
-            if !handler::illegal_instruction_handler(&mut ctx) {
-                handler::delegate(&mut ctx);
+                    save_regs(&mut ctx);
+                    if !handler::illegal_instruction_handler(&mut ctx) {
+                        handler::delegate(&mut ctx);
+                    }
+                    ctx.restore()
+                }
+                // Handle other traps
+                trap => unsupported_trap(Some(trap)),
             }
-            ctx.restore()
         }
-        // Handle other traps
-        trap => {
-            error!("-----------------------------");
-            error!("trap:    {trap:?}");
-            error!("mepc:    {:#018x}", mepc::read());
-            error!("mtval:   {:#018x}", mtval::read());
-            error!("-----------------------------");
-            panic!("Stopped with unsupported trap")
+        Err(err) => {
+            error!("Failed to parse mcause: {:?}", err);
+            unsupported_trap(None);
         }
     }
 }