97 lines
3.3 KiB
Rust
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);
|
|
}
|
|
}
|
|
}
|
|
}
|