gila/src/kernel/arch/x86_64/paging.rs
August 5a41a9c6a9
Some checks failed
Continuous Integration / Check (push) Successful in 1m7s
Continuous Integration / Clippy (push) Failing after 1m12s
Allocate space and create new page table
2025-11-04 19:58:42 -05:00

97 lines
3.3 KiB
Rust

// Copyright (c) 2025 shibedrill
// SPDX-License-Identifier: MIT
#![allow(dead_code)]
use crate::constants::KERNEL_BUILD_PROFILE;
use crate::{LOGGER, LogLevel, format, log_info, log_trace, memory::HHDM_RESPONSE};
use free_list::{PAGE_SIZE, PageLayout};
use x86_64::{
PhysAddr, VirtAddr,
registers::control::*,
structures::paging::{PageTable, PageTableFlags},
};
pub fn switch_ptable() {
let allocated_region = crate::memory::FREELIST
.lock()
.allocate(PageLayout::from_size_align(PAGE_SIZE, PAGE_SIZE).unwrap())
.expect("Could not allocate pages for new page table!");
log_info!("Got region for new PML4: 0x{:x}", allocated_region.start());
let pml4_start_vaddr = allocated_region.start() + HHDM_RESPONSE.offset() as usize;
let pml4_ptr = pml4_start_vaddr as *mut PageTable;
let mut pml4 = unsafe { crate::memory::alloc::boxed::Box::from_raw(pml4_ptr) };
*pml4 = PageTable::new();
log_info!("Initialized page table at 0x{:p}", pml4);
}
pub fn get_mappings() {
log_info!("Paging: {}", Cr0::read().contains(Cr0Flags::PAGING));
log_info!(
"Protection: {}",
Cr0::read().contains(Cr0Flags::PROTECTED_MODE_ENABLE)
);
log_info!(
"Physical Address Extensions: {}",
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!(
"Paging mode: {}",
match crate::memory::PAGING_REQUEST.get_response().unwrap().mode() {
limine::paging::Mode::FOUR_LEVEL => "Four-Level",
limine::paging::Mode::FIVE_LEVEL => "Five-Level",
_ => unreachable!(),
}
);
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)
);
if KERNEL_BUILD_PROFILE == "debug" {
let pml4_phys_addr = Cr3::read_raw().0.start_address();
log_info!("Page Map Level 4 Address: 0x{:x}", pml4_phys_addr.as_u64());
let pml4: &'static mut PageTable = table_from_phys_addr(pml4_phys_addr);
iter_table(pml4, 4);
}
}
fn table_from_phys_addr(address: PhysAddr) -> &'static mut PageTable {
let virt_addr: VirtAddr = VirtAddr::new(address.as_u64() + HHDM_RESPONSE.offset());
let ptr: *mut PageTable = virt_addr.as_mut_ptr();
unsafe { &mut *ptr }
}
fn iter_table(table: &'static mut PageTable, level: usize) {
if level == 1 {
for page_entry in table.iter() {
if page_entry.flags().contains(PageTableFlags::PRESENT) {
log_trace!(
"Page entry: 0x{:x}, flags: {:?}",
page_entry.addr(),
page_entry.flags()
);
}
}
} else {
for table_entry in table.iter() {
if table_entry.flags().contains(PageTableFlags::PRESENT) {
log_info!(
"Table entry: 0x{:x}, flags: {:?}",
table_entry.addr(),
table_entry.flags()
);
iter_table(table_from_phys_addr(table_entry.addr()), level - 1);
}
}
}
}