1use crate::hal;
4use crate::mem::pfa::PAGE_SIZE;
5use crate::mem::vmm::{AddressSpacelike, Backing, Perms, Region};
6use crate::sync::spinlock::SpinLocked;
7use alloc::Allocator;
8use core::ptr::NonNull;
9use hal::mem::PhysAddr;
10
11pub mod alloc;
12pub mod pfa;
13pub mod vmm;
14
15#[allow(dead_code)]
16pub const BITS_PER_PTR: usize = core::mem::size_of::<usize>() * 8;
17
18unsafe extern "C" {
19 unsafe static __stack_top: u8;
20}
21
22pub(crate) static GLOBAL_ALLOCATOR: SpinLocked<alloc::bestfit::BestFitAllocator> =
24 SpinLocked::new(alloc::bestfit::BestFitAllocator::new());
25
26pub fn init_memory() -> vmm::AddressSpace {
32 let stack_top = &raw const __stack_top as usize;
33 if let Err(e) = pfa::init_pfa(PhysAddr::new(stack_top)) {
34 panic!("failed to initialize PFA. Error: {e}");
36 }
37
38 let total_pgs = 64;
40 let heap_pgs = 8; let mut kaddr_space = vmm::AddressSpace::new(total_pgs).unwrap_or_else(|e| {
43 panic!("failed to create kernel address space. Error: {e}");
44 });
45
46 let begin = kaddr_space
47 .map(Region::new(
48 None,
49 heap_pgs * PAGE_SIZE,
50 Backing::Zeroed,
51 Perms::all(),
52 ))
53 .unwrap_or_else(|e| {
54 panic!("failed to map kernel address space. Error: {e}");
55 });
56
57 {
58 let mut allocator = GLOBAL_ALLOCATOR.lock();
59
60 let range = begin..(begin + heap_pgs * PAGE_SIZE);
61 if let Err(e) = unsafe { allocator.add_range(&range) } {
62 panic!("failed to add range to allocator. Error: {e}");
63 }
64 }
65
66 kaddr_space
67}
68
69pub fn malloc(size: usize, align: usize) -> Option<NonNull<u8>> {
76 let mut allocator = GLOBAL_ALLOCATOR.lock();
77 unsafe { allocator.malloc(size, align, None).ok() }
79}
80
81pub unsafe fn free(ptr: NonNull<u8>, size: usize) {
90 let mut allocator = GLOBAL_ALLOCATOR.lock();
91 unsafe { allocator.free(ptr, size) };
92}
93
94#[cfg(any(feature = "metrics", metrics))]
96pub(crate) fn global_metrics() -> alloc::Metrics {
97 GLOBAL_ALLOCATOR.lock().metrics()
98}
99
100pub fn align_up(size: usize) -> usize {
106 if size >= (usize::MAX - align_of::<u128>()) {
107 return usize::MAX;
108 }
109
110 let align = align_of::<u128>();
111 (size + align - 1) & !(align - 1)
112}