()
| 58 | |
| 59 | #[no_mangle] |
| 60 | pub fn trap_handler() -> ! { |
| 61 | set_kernel_trap_entry(); |
| 62 | let scause = scause::read(); |
| 63 | let stval = stval::read(); |
| 64 | // println!("into {:?}", scause.cause()); |
| 65 | match scause.cause() { |
| 66 | Trap::Exception(Exception::UserEnvCall) => { |
| 67 | // jump to next instruction anyway |
| 68 | let mut cx = current_trap_cx(); |
| 69 | cx.sepc += 4; |
| 70 | |
| 71 | enable_supervisor_interrupt(); |
| 72 | |
| 73 | // get system call return value |
| 74 | let result = syscall(cx.x[17], [cx.x[10], cx.x[11], cx.x[12]]); |
| 75 | // cx is changed during sys_exec, so we have to call it again |
| 76 | cx = current_trap_cx(); |
| 77 | cx.x[10] = result as usize; |
| 78 | } |
| 79 | Trap::Exception(Exception::StoreFault) |
| 80 | | Trap::Exception(Exception::StorePageFault) |
| 81 | | Trap::Exception(Exception::InstructionFault) |
| 82 | | Trap::Exception(Exception::InstructionPageFault) |
| 83 | | Trap::Exception(Exception::LoadFault) |
| 84 | | Trap::Exception(Exception::LoadPageFault) => { |
| 85 | /* |
| 86 | println!( |
| 87 | "[kernel] {:?} in application, bad addr = {:#x}, bad instruction = {:#x}, kernel killed it.", |
| 88 | scause.cause(), |
| 89 | stval, |
| 90 | current_trap_cx().sepc, |
| 91 | ); |
| 92 | */ |
| 93 | current_add_signal(SignalFlags::SIGSEGV); |
| 94 | } |
| 95 | Trap::Exception(Exception::IllegalInstruction) => { |
| 96 | current_add_signal(SignalFlags::SIGILL); |
| 97 | } |
| 98 | Trap::Interrupt(Interrupt::SupervisorTimer) => { |
| 99 | set_next_trigger(); |
| 100 | check_timer(); |
| 101 | suspend_current_and_run_next(); |
| 102 | } |
| 103 | Trap::Interrupt(Interrupt::SupervisorExternal) => { |
| 104 | crate::board::irq_handler(); |
| 105 | } |
| 106 | _ => { |
| 107 | panic!( |
| 108 | "Unsupported trap {:?}, stval = {:#x}!", |
| 109 | scause.cause(), |
| 110 | stval |
| 111 | ); |
| 112 | } |
| 113 | } |
| 114 | // check signals |
| 115 | if let Some((errno, msg)) = check_signals_of_current() { |
| 116 | println!("[kernel] {}", msg); |
| 117 | exit_current_and_run_next(errno); |
nothing calls this directly
no test coverage detected