Use x86_64 crate for asm

This commit is contained in:
August 2025-09-28 23:04:00 -04:00
parent 4097ae0b53
commit f48426c59c
Signed by: shibedrill
GPG Key ID: 5FE0CB25945EFAA2
7 changed files with 58 additions and 168 deletions

View File

@ -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();
}

View File

@ -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!()
}

View File

@ -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)
);
}

View File

@ -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<u8> {
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 }
}
}

View File

@ -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);
}
}
}

View File

@ -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<u8> = 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();

View File

@ -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();