diff --git a/src/kernel/arch/x86_64/asm.rs b/src/kernel/arch/x86_64/asm.rs index 30fc7e8..4b6aac7 100644 --- a/src/kernel/arch/x86_64/asm.rs +++ b/src/kernel/arch/x86_64/asm.rs @@ -28,6 +28,12 @@ pub fn write_cr3(val: u64) { unsafe { asm!("mov cr3, {0:r}", in(reg) val) } } +pub fn read_cr4() -> u64 { + let cr4: u64; + unsafe { asm!("mov {0:r}, cr4", out(reg) cr4) } + cr4 +} + pub fn interrupt_disable() { unsafe { asm!("cli"); diff --git a/src/kernel/arch/x86_64/interrupts.rs b/src/kernel/arch/x86_64/interrupts.rs index 94158d3..5384b7a 100644 --- a/src/kernel/arch/x86_64/interrupts.rs +++ b/src/kernel/arch/x86_64/interrupts.rs @@ -1,7 +1,8 @@ // Copyright (c) 2025 shibedrill // SPDX-License-Identifier: GPL-3.0-or-later -use crate::format; +use crate::LogLevel; +use crate::{LOGGER, arch::asm::read_cr2, format, log_trace}; use lazy_static::lazy_static; use x86_64::structures::idt::*; @@ -25,6 +26,12 @@ extern "x86-interrupt" fn double_fault(info: InterruptStackFrame, _: u64) -> ! { #[allow(dead_code)] extern "x86-interrupt" fn page_fault(info: InterruptStackFrame, errcode: PageFaultErrorCode) { + let addr = read_cr2(); + log_trace!( + "Fault: Page fault with address 0x{:x}, error code 0b{:b}", + addr, + errcode + ); if errcode.contains(PageFaultErrorCode::USER_MODE) { // Fault occurred in usermode. Non fatal. todo!() @@ -35,13 +42,10 @@ extern "x86-interrupt" fn page_fault(info: InterruptStackFrame, errcode: PageFau if errcode.contains(PageFaultErrorCode::PROTECTION_VIOLATION) | errcode.contains(PageFaultErrorCode::MALFORMED_TABLE) { - let addr = unsafe { - let a: usize; - core::arch::asm! {"mov {}, cr2", out(reg) a}; - a - }; let info_formatted = format!("{info:#?}"); crate::interrupt::page_fault(addr, info_formatted) + } else { + todo!() } } } diff --git a/src/kernel/arch/x86_64/paging.rs b/src/kernel/arch/x86_64/paging.rs index c86c864..0b360fe 100644 --- a/src/kernel/arch/x86_64/paging.rs +++ b/src/kernel/arch/x86_64/paging.rs @@ -65,7 +65,7 @@ impl PageMapLevel5Entry { } pub struct PageMapLevel4 { - entries: [PageMapLevel4Entry; 512], + pub entries: [PageMapLevel4Entry; 512], } pub struct PageMapLevel4Entry { diff --git a/src/kernel/main.rs b/src/kernel/main.rs index bf26fc9..f2d050d 100644 --- a/src/kernel/main.rs +++ b/src/kernel/main.rs @@ -25,6 +25,7 @@ use arch::x86_64::serial::Serialport; use boot::{modules::*, params, *}; use constants::*; +use intbits::Bits; use limine::firmware_type::FirmwareType; use log::*; use memory::alloc::{format, string::*, vec}; @@ -35,11 +36,17 @@ use limine::memory_map::EntryType; #[allow(unused_imports)] use lzma_rs::lzma_decompress; +use crate::arch::paging::PageMapLevel4; +use crate::arch::x86_64::interrupts::IDT; + #[unsafe(no_mangle)] unsafe extern "C" fn main() -> ! { // Assert supported bootloader version assert!(BASE_REVISION.is_supported()); + // Ensure IDT exists + IDT.load(); + // Set up logging level from params // Nothing we can do here if this fails since no log subscribers are initialized yet if let Some(level) = PARAMS.get("-loglevel") @@ -196,6 +203,30 @@ unsafe extern "C" fn main() -> ! { log_info!("HHDM offset: 0x{:X}", HHDM_RESPONSE.offset()); + log_info!("Paging: {}", arch::asm::read_cr0().bit(31)); + log_info!("Protection: {}", arch::asm::read_cr0().bit(0)); + log_info!( + "Physical Address Extensions: {}", + arch::asm::read_cr4().bit(5) + ); + log_info!("Page Size Extensions: {}", arch::asm::read_cr4().bit(4)); + log_info!( + "Paging mode: {}", + match memory::PAGING_REQUEST.get_response().unwrap().mode() { + limine::paging::Mode::FOUR_LEVEL => "Four-Level", + limine::paging::Mode::FIVE_LEVEL => "Five-Level", + _ => unreachable!(), + } + ); + log_info!("CR3 Value: 0b{:064b}", arch::asm::read_cr3()); + // Physical address of Page Map Level 4 Table + let pml4_ptr = ((arch::asm::read_cr3().bits(12..=63) << 12) + HHDM_RESPONSE.offset()) + as *const PageMapLevel4; + log_info!("Page Map Level 4 Table Address: 0x{:x}", pml4_ptr.addr()); + log_info!("Physical address of first entry: {}", unsafe { + (*pml4_ptr).entries[0].physical_address() + }); + panic!("Bailing"); #[allow(unreachable_code)] diff --git a/src/kernel/memory.rs b/src/kernel/memory.rs index 1da72f0..461c4cd 100644 --- a/src/kernel/memory.rs +++ b/src/kernel/memory.rs @@ -3,7 +3,7 @@ use lazy_static::lazy_static; use limine::{ - request::{ExecutableAddressRequest, HhdmRequest, MemoryMapRequest}, + request::{ExecutableAddressRequest, HhdmRequest, MemoryMapRequest, PagingModeRequest}, response::HhdmResponse, }; @@ -11,6 +11,10 @@ use talc::*; pub extern crate alloc; +#[used] +#[unsafe(link_section = ".requests")] +pub static PAGING_REQUEST: PagingModeRequest = limine::request::PagingModeRequest::new(); + #[used] #[unsafe(link_section = ".requests")] pub static ADDRESS_REQUEST: ExecutableAddressRequest =