diff options
| author | Tianhao Wang <shrik3@mailbox.org> | 2024-06-05 23:24:01 +0200 |
|---|---|---|
| committer | Tianhao Wang <shrik3@mailbox.org> | 2024-06-11 15:17:14 +0200 |
| commit | ca8bc76fd5319842954508484542f4beb6b591d0 (patch) | |
| tree | 5f096dc62e9bbb65056ee772cb7bbf17bc646107 | |
| parent | 38883485c80841f15365d0502418dcc224f01d45 (diff) | |
interrupt: set up dummy pagefault handler
Signed-off-by: Tianhao Wang <shrik3@mailbox.org>
| -rw-r--r-- | src/arch/x86_64/interrupt/mod.rs | 15 | ||||
| -rw-r--r-- | src/arch/x86_64/paging/fault.rs | 33 | ||||
| -rw-r--r-- | src/arch/x86_64/paging/mod.rs | 6 |
3 files changed, 50 insertions, 4 deletions
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 { |
