mod context; use core::arch::global_asm; use riscv::register::{ mtvec::TrapMode, scause::{self, Exception, Trap}, stval, stvec, }; pub use context::TrapContext; // use crate::batch::run_next_app; use crate::println; use crate::syscall::syscall; // 引入陷入保存寄存器需要的汇编代码 global_asm!(include_str!("trap.S")); /// 初始化stvec 寄存器, 这个寄存器保存陷入时, 入口函数的地址 pub fn init() { extern "C" { fn __alltraps(); } unsafe { stvec::write(__alltraps as usize, TrapMode::Direct); } } // 这个函数是 trap.S 中__alltraps 保存完所有寄存器在内核栈 之后会进入到这里 #[no_mangle] pub fn trap_handler(trap_context: &mut TrapContext) -> &mut TrapContext { let scause = scause::read(); // trap 发生的原因 let stval = stval::read(); // trap的附加信息 // 根据发生的原因判断是那种类别 match scause.cause() { // 用户态发出的系统调用 Trap::Exception(Exception::UserEnvCall) => { trap_context.sepc += 4; // +4 是因为我们需要返回 ecall指令的下一个指令 trap_context.x[10] = syscall(trap_context.x[17], [trap_context.x[10], trap_context.x[11], trap_context.x[12]]) as usize; } // 访问不允许的内存 Trap::Exception(Exception::StoreFault) | Trap::Exception(Exception::StorePageFault) => { println!("[kernel] PageFault in application, kernel killed it."); // run_next_app(); } // 非法指令 Trap::Exception(Exception::IllegalInstruction) => { println!("[kernel] IllegalInstruction in application, kernel killed it."); // run_next_app(); } // 未知错误 _ => { panic!( "Unsupported trap {:?}, stval = {:#x}!", scause.cause(), stval ); } } trap_context }