diff --git a/kernel/src/arch/riscv32/interrupt.rs b/kernel/src/arch/riscv32/interrupt.rs index 4e73f31..7a7a12b 100644 --- a/kernel/src/arch/riscv32/interrupt.rs +++ b/kernel/src/arch/riscv32/interrupt.rs @@ -72,6 +72,9 @@ pub extern fn rust_trap(tf: &mut TrapFrame) { Trap::Interrupt(I::SupervisorTimer) => timer(), Trap::Exception(E::IllegalInstruction) => illegal_inst(tf), Trap::Exception(E::UserEnvCall) => syscall(tf), + Trap::Exception(E::LoadPageFault) => page_fault(tf), + Trap::Exception(E::StoreFault) => page_fault(tf), + Trap::Exception(E::InstructionPageFault) => page_fault(tf), _ => ::trap::error(tf), } ::trap::before_return(); @@ -111,6 +114,24 @@ fn illegal_inst(tf: &mut TrapFrame) { } } +/* +* @param: +* TrapFrame: the Trapframe for the page fault exception +* @brief: +* process page fault exception +*/ +fn page_fault(tf: &mut TrapFrame) { + let addr: usize; + // move stval(i.e. sbadaddr) to addr + addr = stval::read(); + error!("\nEXCEPTION: Page Fault @ {:#x}", addr); + + use memory::page_fault_handler; + if !page_fault_handler(addr) { + ::trap::error(tf); + } +} + /// Migrate from riscv-pk /* * @param: diff --git a/kernel/src/memory.rs b/kernel/src/memory.rs index 0f203f3..6e38762 100644 --- a/kernel/src/memory.rs +++ b/kernel/src/memory.rs @@ -52,7 +52,14 @@ pub fn active_table() -> MutexGuard<'static, CowExt> { ACTIVE_TABLE.lock() } -// Return true to continue, false to halt +/* +* @param: +* addr: the virtual address of the page fault +* @brief: +* handle page fault +* @retval: +* Return true to continue, false to halt +*/ pub fn page_fault_handler(addr: usize) -> bool { // Handle copy on write unsafe { ACTIVE_TABLE.force_unlock(); }