浏览代码

Transfer illegal instruction exception to S level on K210

luojia65 3 年之前
父节点
当前提交
c0ceb9a79e
共有 2 个文件被更改,包括 18 次插入4 次删除
  1. 1 1
      platform/k210/Cargo.toml
  2. 17 3
      platform/k210/src/main.rs

+ 1 - 1
platform/k210/Cargo.toml

@@ -9,7 +9,7 @@ publish = false
 
 [dependencies]
 rustsbi = { path = "../../rustsbi" }
-riscv = { git = "https://github.com/rust-embedded/riscv", features = ["inline-asm"] }
+riscv = { git = "https://github.com/rust-embedded/riscv", rev = "7e9d2e5b", features = ["inline-asm"] }
 linked_list_allocator = "0.8"
 k210-hal = { git = "https://github.com/riscv-rust/k210-hal" }
 r0 = "1.0"

+ 17 - 3
platform/k210/src/main.rs

@@ -14,10 +14,10 @@ use rustsbi::{enter_privileged, print, println};
 use riscv::register::{
     mcause::{self, Exception, Interrupt, Trap},
     medeleg, mepc, mhartid, mideleg, mie, mip, misa::{self, MXL},
-    mstatus::{self, MPP},
+    mstatus::{self, MPP, SPP},
     mtval,
     mtvec::{self, TrapMode},
-    satp,
+    satp, stvec, scause, stval, sepc,
 };
 
 #[global_allocator]
@@ -497,7 +497,21 @@ extern "C" fn start_trap_rust(trap_frame: &mut TrapFrame) {
                 unsafe { llvm_asm!(".word 0x10400073") }; // sfence.vm x0
                 // ::"r"(rs1_vaddr)
                 mepc::write(mepc::read().wrapping_add(4)); // skip current instruction
-            } else {
+            } else if mstatus::read().mpp() != MPP::Machine { // invalid instruction, can't emulate, raise to supervisor
+                // 出现非法指令异常,转发到S特权层
+                unsafe { 
+                    scause::set(scause::Trap::Exception(scause::Exception::IllegalInstruction));
+                    stval::write(mtval::read());
+                    sepc::write(mepc::read());
+                    mstatus::set_mpp(MPP::Supervisor);
+                    mstatus::set_spp(SPP::Supervisor);
+                    if mstatus::read().sie() {
+                        mstatus::set_spie()
+                    }
+                    mstatus::clear_sie();
+                    mepc::write(stvec::read().address());
+                };
+            } else { // 真正来自M特权层的异常
                 panic!("invalid instruction! mepc: {:016x?}, instruction: {:08x?}", mepc::read(), ins);
             }
         }