kernel/arch/x86_64/mm/vmm/paging/
map_range.rs1use crate::arch::x86_64::mm::vmm::page_type::{PageType, HUGE_PAGE_SIZE_1GIB, HUGE_PAGE_SIZE_2MIB};
7use crate::lib::addr::{PhysAddr, VirtAddr};
8use crate::mm::pmm::Pmm;
9use crate::mm::vmm::VmmResult;
10use x86_64::structures::paging::PageTableFlags;
11
12pub unsafe fn map_range(
13 pmm: &mut Pmm,
14 page_ptr: VirtAddr,
15 virt: VirtAddr,
16 phys: PhysAddr,
17 size: u64,
18 flags: PageTableFlags,
19 can_overmap: bool
20) -> VmmResult {
21 #[cfg(feature = "debug-checks")]
22 {
23 use super::helpers::misaligned_address_panic;
24 use crate::mm::pmm::FRAME_SIZE;
25 if !virt.is_aligned(FRAME_SIZE) || !phys.is_aligned(FRAME_SIZE) || size % FRAME_SIZE != 0 {
26 misaligned_address_panic(PageType::Normal);
27 }
28 }
29
30 let mut offset = 0u64;
31
32 while offset < size {
33 let virt = virt + offset;
34 let phys = phys + offset;
35 let remaining = size - offset;
36
37 let fits = |page_size: u64| {
38 virt.is_aligned(page_size)
39 && phys.is_aligned(page_size)
40 && (can_overmap || remaining >= page_size)
41 };
42
43 let page_type = if fits(HUGE_PAGE_SIZE_1GIB) {
44 PageType::HugePage1GiB
45 }
46 else if fits(HUGE_PAGE_SIZE_2MIB) {
47 PageType::HugePage2MiB
48 }
49 else {
50 PageType::Normal
51 };
52
53 unsafe {
54 super::map_page::map_page(pmm, page_ptr, virt, phys, page_type, flags)?;
55 }
56
57 offset += page_type as u64;
58 }
59
60 Ok(())
61}