|
@@ -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);
|
|
|
}
|
|
|
}
|
|
|
}
|