kernel/arch/x86_64/mm/vmm/paging/
translate.rs1use super::super::page_type::{HUGE_PAGE_SIZE_1GIB, HUGE_PAGE_SIZE_2MIB};
7use super::helpers::{advance_current_pagetable, is_huge_page, is_present};
8use crate::lib::addr::{PhysAddr, VirtAddr};
9use crate::mm::pmm::FRAME_SIZE;
10use x86_64::structures::paging::PageTable;
11
12pub unsafe fn translate(
13 page_ptr: VirtAddr,
14 virt: VirtAddr
15) -> Option<PhysAddr> {
16 let res = unsafe { translate_with_size(page_ptr, virt)? };
17 Some(res.0)
18}
19
20pub unsafe fn translate_with_size(
21 page_ptr: VirtAddr,
22 virt: VirtAddr
23) -> Option<(PhysAddr, u64)> {
24 let mut current = page_ptr.as_mut_ptr::<PageTable>();
25
26 let entry = unsafe { &(&*current)[virt.p4_index()] };
32 if !is_present(entry) { return None; }
33 current = advance_current_pagetable(entry);
34
35 let entry = unsafe { &(&*current)[virt.p3_index()] };
41 if !is_present(entry) { return None; }
42 if is_huge_page(entry) {
43 return Some((
44 PhysAddr::new(entry.addr().as_u64() + (virt.as_u64() & (HUGE_PAGE_SIZE_1GIB - 1))),
45 HUGE_PAGE_SIZE_1GIB
46 ));
47 }
48 current = advance_current_pagetable(entry);
49
50 let entry = unsafe { &(&*current)[virt.p2_index()] };
56 if !is_present(entry) { return None; }
57 if is_huge_page(entry) {
58 return Some((
59 PhysAddr::new(entry.addr().as_u64() + (virt.as_u64() & (HUGE_PAGE_SIZE_2MIB - 1))),
60 HUGE_PAGE_SIZE_2MIB
61 ));
62 }
63 current = advance_current_pagetable(entry);
64
65 let entry = unsafe { &(&*current)[virt.p1_index()] };
71 if !is_present(entry) { return None; }
72 Some((
73 PhysAddr::new(entry.addr().as_u64() + (virt.as_u64() & (FRAME_SIZE - 1))),
74 FRAME_SIZE
75 ))
76}