From ca8bc76fd5319842954508484542f4beb6b591d0 Mon Sep 17 00:00:00 2001 From: Tianhao Wang Date: Wed, 5 Jun 2024 23:24:01 +0200 Subject: interrupt: set up dummy pagefault handler Signed-off-by: Tianhao Wang --- src/arch/x86_64/interrupt/mod.rs | 15 +++++++++++---- src/arch/x86_64/paging/fault.rs | 33 +++++++++++++++++++++++++++++++++ src/arch/x86_64/paging/mod.rs | 6 ++++++ 3 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 src/arch/x86_64/paging/fault.rs (limited to 'src/arch') diff --git a/src/arch/x86_64/interrupt/mod.rs b/src/arch/x86_64/interrupt/mod.rs index 6663b23..ed08223 100644 --- a/src/arch/x86_64/interrupt/mod.rs +++ b/src/arch/x86_64/interrupt/mod.rs @@ -1,6 +1,7 @@ pub mod pic_8259; pub mod pit; use crate::arch::x86_64::arch_regs::TrapFrame; +use crate::arch::x86_64::paging::fault; use crate::io::*; use core::arch::asm; use core::slice; @@ -71,13 +72,19 @@ extern "C" fn trap_gate(_nr: u16, fp: u64) { // able to release the lock if the interrupt handler blocks on it. Try // spamming the keyboard with the following line of code uncommented: it // will deadlock! - println!("interrupt received 0x{:x}", _nr); - if _nr < 0x20 { - let _frame = unsafe { &mut *(fp as *mut TrapFrame) }; - println!("trap: @{:#X} {:#X?}", fp, _frame); + // TODO this is only a POC, use proper defines and match later + let _frame = unsafe { &mut *(fp as *mut TrapFrame) }; + if _nr == 0xe { + // Pagefault + let fault_address = fault::get_fault_addr(); + fault::page_fault_handler(_frame, fault_address) + } else if _nr < 0x20 { + println!("[trap[ {:#X?}", _frame); unsafe { asm!("hlt"); } + } else { + // deal with irq } interrupt_enable(); } diff --git a/src/arch/x86_64/paging/fault.rs b/src/arch/x86_64/paging/fault.rs new file mode 100644 index 0000000..7b27649 --- /dev/null +++ b/src/arch/x86_64/paging/fault.rs @@ -0,0 +1,33 @@ +use crate::arch::x86_64::arch_regs::TrapFrame; +use crate::io::*; +use core::arch::asm; + +/// handle page fault: for now we only check if the faulting addr is within +/// kernel heap range. +/// TODO: improve this later +pub fn page_fault_handler(frame: &mut TrapFrame, fault_addr: u64) { + let err_code = frame.err_code; + println!("pagefault @ {:#X}, err {:#X?}", fault_addr, err_code); + unsafe { asm!("hlt") }; +} + +/// for x86_64, return the CR3 register. +/// TODO: use page root in task struct instead of raw cr3 +#[inline] +pub fn get_root() -> u64 { + let cr3: u64; + unsafe { + asm!("mov {}, cr3", out(reg) cr3); + } + return cr3; +} + +/// for x86_64, return the CR3 register. +#[inline] +pub fn get_fault_addr() -> u64 { + let cr2: u64; + unsafe { + asm!("mov {}, cr2", out(reg) cr2); + } + return cr2; +} diff --git a/src/arch/x86_64/paging/mod.rs b/src/arch/x86_64/paging/mod.rs index ab93938..257b7b3 100644 --- a/src/arch/x86_64/paging/mod.rs +++ b/src/arch/x86_64/paging/mod.rs @@ -1,6 +1,7 @@ // code derived from the x86_64 crate // https://docs.rs/x86_64/latest/src/x86_64/addr.rs.html // see ATTRIBUTIONS +pub mod fault; use crate::defs::*; use bitflags::bitflags; #[repr(align(4096))] @@ -98,6 +99,11 @@ impl Pagetable { pub fn is_empty(&self) -> bool { self.iter().all(|entry| entry.is_unused()) } + + /// walk the page table, create missing tables, return mapped physical frame + pub fn map_page(&self, _va: VAddr) { + todo!() + } } impl VAddr { -- cgit v1.2.3-70-g09d2