hermit/arch/x86_64/mm/
mod.rs1pub(crate) mod paging;
2
3#[cfg(feature = "common-os")]
4use core::slice;
5
6use memory_addresses::arch::x86_64::{PhysAddr, VirtAddr};
7#[cfg(feature = "common-os")]
8use x86_64::structures::paging::{PageSize, Size4KiB as BasePageSize};
9
10#[cfg(feature = "common-os")]
11use crate::arch::mm::paging::{PageTableEntryFlags, PageTableEntryFlagsExt};
12use crate::mm::{FrameAlloc, PageAlloc, PageRangeAllocator};
13
14#[cfg(feature = "common-os")]
15pub fn create_new_root_page_table() -> usize {
16 use free_list::PageLayout;
17 use x86_64::registers::control::Cr3;
18
19 use crate::mm::{FrameAlloc, PageBox, PageRangeAllocator};
20
21 let layout = PageLayout::from_size(BasePageSize::SIZE as usize).unwrap();
22 let frame_range = FrameAlloc::allocate(layout).unwrap();
23 let physaddr = PhysAddr::from(frame_range.start());
24
25 let layout = PageLayout::from_size(2 * BasePageSize::SIZE as usize).unwrap();
26 let page_range = PageBox::new(layout).unwrap();
27 let virtaddr = VirtAddr::from(page_range.start());
28 let mut flags = PageTableEntryFlags::empty();
29 flags.normal().writable();
30
31 let entry: u64 = unsafe {
32 let (frame, _flags) = Cr3::read();
33 paging::map::<BasePageSize>(virtaddr, frame.start_address().into(), 1, flags);
34 let entry: &u64 = &*virtaddr.as_ptr();
35
36 *entry
37 };
38
39 let slice_addr = virtaddr + BasePageSize::SIZE;
40 paging::map::<BasePageSize>(slice_addr, physaddr, 1, flags);
41
42 unsafe {
43 let pml4 = slice::from_raw_parts_mut(slice_addr.as_mut_ptr(), 512);
44
45 for elem in pml4.iter_mut() {
47 *elem = 0;
48 }
49
50 pml4[0] = entry;
52 pml4[511] = physaddr.as_u64() + 0x3; };
55
56 paging::unmap::<BasePageSize>(virtaddr, 2);
57
58 physaddr.as_usize()
59}
60
61pub unsafe fn init() {
62 paging::init();
63 unsafe {
64 FrameAlloc::init();
65 }
66 unsafe {
67 paging::log_page_tables();
68 }
69 unsafe {
70 PageAlloc::init();
71 }
72
73 #[cfg(feature = "common-os")]
74 {
75 use x86_64::registers::control::Cr3;
76
77 let (frame, _flags) = Cr3::read();
78 crate::scheduler::BOOT_ROOT_PAGE_TABLE
79 .set(frame.start_address().as_u64().try_into().unwrap())
80 .unwrap();
81 }
82}