// SPDX-License-Identifier: MIT OR Apache-2.0 // // Copyright (c) 2021-2022 Andre Richter //! Page allocation. use super::MemoryRegion; use crate::{ memory::{AddressType, Virtual}, synchronization::IRQSafeNullLock, warn, }; use core::num::NonZeroUsize; //-------------------------------------------------------------------------------------------------- // Public Definitions //-------------------------------------------------------------------------------------------------- /// A page allocator that can be lazyily initialized. pub struct PageAllocator { pool: Option>, } //-------------------------------------------------------------------------------------------------- // Global instances //-------------------------------------------------------------------------------------------------- static KERNEL_MMIO_VA_ALLOCATOR: IRQSafeNullLock> = IRQSafeNullLock::new(PageAllocator::new()); //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- /// Return a reference to the kernel's MMIO virtual address allocator. pub fn kernel_mmio_va_allocator() -> &'static IRQSafeNullLock> { &KERNEL_MMIO_VA_ALLOCATOR } impl PageAllocator { /// Create an instance. pub const fn new() -> Self { Self { pool: None } } /// Initialize the allocator. pub fn init(&mut self, pool: MemoryRegion) { if self.pool.is_some() { warn!("Already initialized"); return; } self.pool = Some(pool); } /// Allocate a number of pages. pub fn alloc( &mut self, num_requested_pages: NonZeroUsize, ) -> Result, &'static str> { if self.pool.is_none() { return Err("Allocator not initialized"); } self.pool .as_mut() .unwrap() .take_first_n_pages(num_requested_pages) } }