Skip to main content

kernel/mem/x86_64/
vmm_helpers.rs

1// SPDX-License-Identifier: GPL-3.0-only
2//! Shared helper functions for the VMM.
3//!
4//! Authors: MarioS271
5
6use crate::mem::pmm::Pmm;
7use crate::panic::kernel_panic;
8use crate::types::panic_codes::PanicCode;
9use x86_64::structures::paging::{PageTable, PhysFrame};
10use x86_64::PhysAddr;
11
12/// Panic when `unmap_page` hits a page-table level that is not present.
13pub fn invalid_unmap_panic() -> ! {
14    kernel_panic(
15        PanicCode::InvalidPageOperation,
16        "Attempting to unmap a page without a PRESENT flag",
17    );
18}
19
20/// Panic when the VMM cannot allocate a frame from the PMM.
21pub fn out_of_memory_panic() -> ! {
22    kernel_panic(
23        PanicCode::OutOfMemory,
24        "VMM could not allocate a frame, out of memory",
25    )
26}
27
28/// Allocate one physical frame from the PMM, zero it, and return it as a [`PhysFrame`].
29///
30/// # Panics
31/// Panics if the PMM is out of memory.
32pub fn alloc_zeroed_frame(pmm: &Pmm, hhdm_offset: u64) -> PhysFrame {
33    let frame = pmm.alloc().unwrap_or_else(|| out_of_memory_panic());
34
35    // Safe because the PMM gives us a valid piece of memory
36    unsafe {
37        core::ptr::write_bytes((frame.as_u64() + hhdm_offset) as *mut PageTable, 0x00, 1);
38    }
39
40    PhysFrame::from_start_address(PhysAddr::new(frame.as_u64())).unwrap()
41}