diff --git a/hal-x86_64/src/control_regs.rs b/hal-x86_64/src/control_regs.rs index 6d68a208..67b200d9 100644 --- a/hal-x86_64/src/control_regs.rs +++ b/hal-x86_64/src/control_regs.rs @@ -1,4 +1,5 @@ use core::arch::asm; +use hal_core::VAddr; use mycelium_util::bits::bitfield; pub mod cr3 { @@ -15,7 +16,7 @@ pub mod cr3 { asm!("mov {0}, cr3", out(reg) val, options(readonly)); }; let addr = PAddr::from_u64(val); - tracing::debug!(?addr); + tracing::trace!(rax = ?addr, "mov rax, cr3"); let pml4_page = Page::starting_at_fixed(addr) .expect("PML4 physical addr not aligned! this is very bad"); (pml4_page, Flags(val)) @@ -236,6 +237,20 @@ impl Cr4 { } } +/// Control Register 2 (CR2) contains the Page Fault Linear Address (PFLA). +pub struct Cr2; + +impl Cr2 { + /// Returns the 32-bit Page Fault Linear Address (PFLA) stored in CR2. + pub fn read() -> VAddr { + let addr: u64; + unsafe { + asm!("mov {0}, cr2", out(reg) addr, options(readonly)); + }; + VAddr::from_u64(addr) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/hal-x86_64/src/interrupt.rs b/hal-x86_64/src/interrupt.rs index fdea4d21..876d2bec 100644 --- a/hal-x86_64/src/interrupt.rs +++ b/hal-x86_64/src/interrupt.rs @@ -269,7 +269,7 @@ impl<'a, T> hal_core::interrupt::Context for Context<'a, T> { impl<'a> ctx::PageFault for Context<'a, PageFaultCode> { fn fault_vaddr(&self) -> crate::VAddr { - unimplemented!("eliza") + crate::control_regs::Cr2::read() } fn debug_error_code(&self) -> &dyn fmt::Debug { diff --git a/src/arch/x86_64/interrupt.rs b/src/arch/x86_64/interrupt.rs index faf972a8..20f6776a 100644 --- a/src/arch/x86_64/interrupt.rs +++ b/src/arch/x86_64/interrupt.rs @@ -71,10 +71,12 @@ impl hal_core::interrupt::Handlers for InterruptHandlers { where C: interrupt::Context + hal_core::interrupt::ctx::PageFault, { + let fault_vaddr = cx.fault_vaddr(); + let code = cx.display_error_code(); oops(Oops::fault_with_details( &cx, "PAGE FAULT", - &format_args!("\n{}", cx.display_error_code()), + &format_args!("at {fault_vaddr:?}\n{code}"), )) }