use core::alloc::{GlobalAlloc, Layout};
use core::ptr::{self, NonNull};
use crate::prelude::*;
use crate::table::boot::{BootServices, MemoryType};
static mut BOOT_SERVICES: Option<NonNull<BootServices>> = None;
pub unsafe fn init(boot_services: &BootServices) {
BOOT_SERVICES = NonNull::new(boot_services as *const _ as *mut _);
}
fn boot_services() -> NonNull<BootServices> {
unsafe { BOOT_SERVICES.expect("Boot services are unavailable or have been exited") }
}
pub fn exit_boot_services() {
unsafe {
BOOT_SERVICES = None;
}
}
pub struct Allocator;
unsafe impl GlobalAlloc for Allocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let mem_ty = MemoryType::LOADER_DATA;
let size = layout.size();
let align = layout.align();
if align > 8 {
ptr::null_mut()
} else {
boot_services()
.as_ref()
.allocate_pool(mem_ty, size)
.warning_as_error()
.unwrap_or(ptr::null_mut())
}
}
unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
boot_services()
.as_ref()
.free_pool(ptr)
.warning_as_error()
.unwrap();
}
}
#[global_allocator]
static ALLOCATOR: Allocator = Allocator;