diff --git a/src/kernel/arch/x86_64/asm.rs b/src/kernel/arch/x86_64/asm.rs index 4b6aac7..05dbdb6 100644 --- a/src/kernel/arch/x86_64/asm.rs +++ b/src/kernel/arch/x86_64/asm.rs @@ -1,125 +1,6 @@ // Copyright (c) 2025 shibedrill // SPDX-License-Identifier: GPL-3.0-or-later -#![allow(clippy::missing_safety_doc)] -#![allow(dead_code)] - -use core::arch::asm; - -pub fn read_cr0() -> u64 { - let cr0: u64; - unsafe { asm!("mov {0:r}, cr0", out(reg) cr0) } - cr0 -} - -pub fn read_cr2() -> usize { - let cr2: usize; - unsafe { asm!("mov {0:r}, cr2", out(reg) cr2) } - cr2 -} - -pub fn read_cr3() -> u64 { - let cr3: u64; - unsafe { asm!("mov {0:r}, cr3", out(reg) cr3) } - cr3 -} - -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"); - } -} - -pub fn interrupt_enable() { - unsafe { - asm!("sti"); - } -} - -pub fn halt() { - unsafe { - asm!("hlt"); - } -} - pub fn nop() { - unsafe { - asm!("nop"); - } -} - -pub fn port_read_u8(port: u16) -> u8 { - let result: u8; - unsafe { - asm! { - "in al dx", - in("dx") port, - out("al") result - } - } - result -} - -pub fn port_read_u16(port: u16) -> u16 { - let result: u16; - unsafe { - asm! { - "in ax dx", - in("dx") port, - out("ax") result - } - } - result -} - -pub fn port_read_u32(port: u16) -> u32 { - let result: u32; - unsafe { - asm! { - "in eax dx", - in("dx") port, - out("eax") result - } - } - result -} - -pub fn port_write_u8(port: u16, data: u8) { - unsafe { - asm! { - "out dx, al", - in("dx") port, - in("al") data, - } - } -} - -pub fn port_write_u16(port: u16, data: u16) { - unsafe { - asm! { - "out dx, ax", - in("dx") port, - in("ax") data, - } - } -} - -pub fn port_write_u32(port: u16, data: u32) { - unsafe { - asm! { - "out dx eax", - in("dx") port, - in("eax") data, - } - } + ::x86_64::instructions::nop(); } diff --git a/src/kernel/arch/x86_64/interrupts.rs b/src/kernel/arch/x86_64/interrupts.rs index 5384b7a..3a45773 100644 --- a/src/kernel/arch/x86_64/interrupts.rs +++ b/src/kernel/arch/x86_64/interrupts.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later use crate::LogLevel; -use crate::{LOGGER, arch::asm::read_cr2, format, log_trace}; +use crate::{LOGGER, format, log_trace}; use lazy_static::lazy_static; use x86_64::structures::idt::*; @@ -26,10 +26,13 @@ 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(); + let addr = x86_64::registers::control::Cr2::read(); log_trace!( - "Fault: Page fault with address 0x{:x}, error code 0b{:b}", - addr, + "Fault: Page fault with {}, error code 0b{:b}", + match addr { + Ok(addr_inner) => format!("address 0x{:x}", addr_inner), + Err(_) => "invalid virtual address".into(), + }, errcode ); if errcode.contains(PageFaultErrorCode::USER_MODE) { @@ -43,7 +46,7 @@ extern "x86-interrupt" fn page_fault(info: InterruptStackFrame, errcode: PageFau | errcode.contains(PageFaultErrorCode::MALFORMED_TABLE) { let info_formatted = format!("{info:#?}"); - crate::interrupt::page_fault(addr, info_formatted) + crate::interrupt::page_fault(addr.unwrap().as_u64() as usize, info_formatted) } else { todo!() } diff --git a/src/kernel/arch/x86_64/paging.rs b/src/kernel/arch/x86_64/paging.rs index 94fbe8c..f15bd82 100644 --- a/src/kernel/arch/x86_64/paging.rs +++ b/src/kernel/arch/x86_64/paging.rs @@ -1,22 +1,22 @@ #![allow(dead_code)] -use crate::arch; -use crate::memory::HHDM_RESPONSE; -use crate::{LOGGER, LogLevel, format, log_info, log_trace}; -use intbits::Bits; -use x86_64::structures::paging::PageTableFlags; -use x86_64::structures::paging::page_table::PageTable; +use crate::{LOGGER, LogLevel, format, log_info}; +use x86_64::registers::control::*; pub fn get_mappings() { - 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!("Paging: {}", Cr0::read().contains(Cr0Flags::PAGING)); + log_info!( + "Protection: {}", + Cr0::read().contains(Cr0Flags::PROTECTED_MODE_ENABLE) + ); log_info!( "Physical Address Extensions: {}", - arch::asm::read_cr4().bit(5) + x86_64::registers::control::Cr4::read().contains(Cr4Flags::PHYSICAL_ADDRESS_EXTENSION) + ); + log_info!( + "Page Size Extensions: {}", + Cr4::read().contains(Cr4Flags::PAGE_SIZE_EXTENSION) ); - log_info!("Page Size Extensions: {}", arch::asm::read_cr4().bit(4)); log_info!( "Paging mode: {}", match crate::memory::PAGING_REQUEST.get_response().unwrap().mode() { @@ -25,14 +25,14 @@ pub fn get_mappings() { _ => unreachable!(), } ); - log_info!("CR3 Value: 0b{:064b}", arch::asm::read_cr3()); - // Physical address of Page Map Level 4 Table - let pml4_ptr: *const PageTable = - ((arch::asm::read_cr3().bits(12..=63) << 12) + HHDM_RESPONSE.offset()) as *const PageTable; - let pagemap_lvl4 = unsafe { &*pml4_ptr }; - for entry in pagemap_lvl4.iter() { - if entry.flags().contains(PageTableFlags::PRESENT) { - log_trace!("Page Table Level 4 Entry: 0x{:X}", entry.addr()); - } - } + let pml4_addr = Cr3::read_raw().0.start_address(); + log_info!("Page Map Level 4 Address: 0x{:X}", pml4_addr.as_u64()); + log_info!( + "Page-Level Write-Through: {}", + Cr3::read().1.contains(Cr3Flags::PAGE_LEVEL_WRITETHROUGH) + ); + log_info!( + "Page-Level Cache Disable: {}", + Cr3::read().1.contains(Cr3Flags::PAGE_LEVEL_CACHE_DISABLE) + ); } diff --git a/src/kernel/arch/x86_64/serial.rs b/src/kernel/arch/x86_64/serial.rs index d2e03e4..650ee56 100644 --- a/src/kernel/arch/x86_64/serial.rs +++ b/src/kernel/arch/x86_64/serial.rs @@ -1,24 +1,13 @@ // Copyright (c) 2025 shibedrill // SPDX-License-Identifier: GPL-3.0-or-later -use crate::arch::asm::*; use crate::log::LogSubscriber; +use x86_64::instructions::port::Port; -#[derive(Clone, Copy)] -pub struct Serialport { - port: u16, -} - -impl LogSubscriber for Serialport { - fn write(&self, msg: &str) { +impl LogSubscriber for Port { + fn log_write(&mut self, msg: &str) { for c in msg.chars() { - port_write_u8(self.port, c as u8); + unsafe { self.write(c as u8) }; } } } - -impl Serialport { - pub fn new(port: u16) -> Self { - Serialport { port } - } -} diff --git a/src/kernel/log.rs b/src/kernel/log.rs index 094fe46..6658982 100644 --- a/src/kernel/log.rs +++ b/src/kernel/log.rs @@ -80,7 +80,7 @@ pub struct LoggerInner { } pub trait LogSubscriber: Send + Sync { - fn write(&self, msg: &str); + fn log_write(&mut self, msg: &str); } impl Default for LoggerInner { @@ -112,7 +112,7 @@ impl LoggerInner { "[{level_string}] {file}:{line},{column} - {msg}" ) .unwrap(); - sub.lock().write(&message); + sub.lock().log_write(&message); } } } diff --git a/src/kernel/main.rs b/src/kernel/main.rs index afbcc41..a08017a 100644 --- a/src/kernel/main.rs +++ b/src/kernel/main.rs @@ -20,9 +20,6 @@ mod process; #[macro_use] mod util; -#[cfg(target_arch = "x86_64")] -use arch::x86_64::serial::Serialport; - use boot::{BASE_REVISION, params, *}; use constants::*; use limine::firmware_type::FirmwareType; @@ -44,6 +41,9 @@ unsafe extern "C" fn main() -> ! { // Ensure IDT exists IDT.load(); + #[cfg(target_arch = "x86_64")] + let serial: x86_64::instructions::port::Port = x86_64::instructions::port::Port::new(0x3f8); + // 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") @@ -60,7 +60,7 @@ unsafe extern "C" fn main() -> ! { if log_device_list.contains(&"serial") { // TODO: Set up device discovery #[cfg(target_arch = "x86_64")] - LOGGER.add_subscriber(Serialport::new(0x3f8)); + LOGGER.add_subscriber(serial); } log_trace!("Configured kernel logging devices"); } @@ -120,6 +120,7 @@ unsafe extern "C" fn main() -> ! { boot::modules::log_modules(); memory::log_memory(); + memory::log_address(); arch::x86_64::paging::get_mappings(); diff --git a/src/kernel/memory.rs b/src/kernel/memory.rs index c1d74e5..76943ad 100644 --- a/src/kernel/memory.rs +++ b/src/kernel/memory.rs @@ -86,6 +86,22 @@ pub fn log_memory() { } } +pub fn log_address() { + if let Some(resp) = ADDRESS_REQUEST.get_response() { + log_info!( + "Kernel physical start address: 0x{:X}", + resp.physical_base() + ); + log_info!("Kernel virtual start address: 0x{:X}", resp.virtual_base()); + } else { + log_warning!("No kernel address response provided."); + } + log_info!( + "Higher Half direct map offset: 0x{:X}", + HHDM_RESPONSE.offset() + ); +} + #[used] #[unsafe(link_section = ".requests")] pub static PAGING_REQUEST: PagingModeRequest = limine::request::PagingModeRequest::new();