-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
- Loading branch information
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
use x86_64::{structures::paging::PageTable, PhysAddr, VirtAddr}; | ||
|
||
pub unsafe fn active_level_4_table(physical_memory_offset: VirtAddr) -> &'static mut PageTable { | ||
Check warning on line 3 in src/memory.rs GitHub Actions / Clippy
Check warning on line 3 in src/memory.rs GitHub Actions / Clippy
Check warning on line 3 in src/memory.rs GitHub Actions / Clippy
Check warning on line 3 in src/memory.rs GitHub Actions / Clippy
Check warning on line 3 in src/memory.rs GitHub Actions / Clippy
Check warning on line 3 in src/memory.rs GitHub Actions / Clippy
Check warning on line 3 in src/memory.rs GitHub Actions / Clippy
Check warning on line 3 in src/memory.rs GitHub Actions / Clippy
Check warning on line 3 in src/memory.rs GitHub Actions / Clippy
Check warning on line 3 in src/memory.rs GitHub Actions / Clippy
Check warning on line 3 in src/memory.rs GitHub Actions / Clippy
Check warning on line 3 in src/memory.rs GitHub Actions / Clippy
Check warning on line 3 in src/memory.rs GitHub Actions / Clippy
Check warning on line 3 in src/memory.rs GitHub Actions / Clippy
|
||
use x86_64::registers::control::Cr3; | ||
|
||
let (level_4_table_frame, _) = Cr3::read(); | ||
|
||
let phys = level_4_table_frame.start_address(); | ||
let virt = physical_memory_offset + phys.as_u64(); | ||
let page_table_ptr: *mut PageTable = virt.as_mut_ptr(); | ||
|
||
&mut *page_table_ptr | ||
} | ||
|
||
pub unsafe fn translate_addr(addr: VirtAddr, physical_memory_offset: VirtAddr) -> Option<PhysAddr> { | ||
Check warning on line 15 in src/memory.rs GitHub Actions / Clippy
Check warning on line 15 in src/memory.rs GitHub Actions / Clippy
Check warning on line 15 in src/memory.rs GitHub Actions / Clippy
Check warning on line 15 in src/memory.rs GitHub Actions / Clippy
Check warning on line 15 in src/memory.rs GitHub Actions / Clippy
Check warning on line 15 in src/memory.rs GitHub Actions / Clippy
Check warning on line 15 in src/memory.rs GitHub Actions / Clippy
Check warning on line 15 in src/memory.rs GitHub Actions / Clippy
Check warning on line 15 in src/memory.rs GitHub Actions / Clippy
Check warning on line 15 in src/memory.rs GitHub Actions / Clippy
Check warning on line 15 in src/memory.rs GitHub Actions / Clippy
Check warning on line 15 in src/memory.rs GitHub Actions / Clippy
Check warning on line 15 in src/memory.rs GitHub Actions / Clippy
Check warning on line 15 in src/memory.rs GitHub Actions / Clippy
|
||
translate_addr_inner(addr, physical_memory_offset) | ||
} | ||
|
||
fn translate_addr_inner(addr: VirtAddr, physical_memory_offset: VirtAddr) -> Option<PhysAddr> { | ||
use x86_64::registers::control::Cr3; | ||
use x86_64::structures::paging::page_table::FrameError; | ||
|
||
// read the active level 4 frame from the CR3 register | ||
let (level_4_table_frame, _) = Cr3::read(); | ||
|
||
let table_indexes = [ | ||
addr.p4_index(), | ||
addr.p3_index(), | ||
addr.p2_index(), | ||
addr.p1_index(), | ||
]; | ||
let mut frame = level_4_table_frame; | ||
|
||
// traverse the multi-level page table | ||
for &index in &table_indexes { | ||
// convert the frame into a page table reference | ||
let virt = physical_memory_offset + frame.start_address().as_u64(); | ||
let table_ptr: *const PageTable = virt.as_ptr(); | ||
let table = unsafe { &*table_ptr }; | ||
|
||
// read the page table entry and update `frame` | ||
let entry = &table[index]; | ||
frame = match entry.frame() { | ||
Ok(frame) => frame, | ||
Err(FrameError::FrameNotPresent) => return None, | ||
Err(FrameError::HugeFrame) => panic!("huge pages not supported"), | ||
}; | ||
} | ||
|
||
// calculate the physical address by adding the page offset | ||
Some(frame.start_address() + u64::from(addr.page_offset())) | ||
} |