hermit/mm/
device_alloc.rs

1use core::alloc::{AllocError, Allocator, Layout};
2use core::ptr::{self, NonNull};
3
4use align_address::Align;
5
6use crate::arch::mm::paging::{BasePageSize, PageSize};
7
8/// An [`Allocator`] for memory that is used to communicate with devices.
9///
10/// Allocations from this allocator always correspond to contiguous physical memory.
11pub struct DeviceAlloc;
12
13unsafe impl Allocator for DeviceAlloc {
14	fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
15		assert!(layout.align() <= BasePageSize::SIZE as usize);
16		let size = layout.size().align_up(BasePageSize::SIZE as usize);
17		let ptr = super::allocate(size, true).as_mut_ptr::<u8>();
18		let slice = ptr::slice_from_raw_parts_mut(ptr, size);
19		Ok(NonNull::new(slice).unwrap())
20	}
21
22	unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
23		assert!(layout.align() <= BasePageSize::SIZE as usize);
24		let size = layout.size().align_up(BasePageSize::SIZE as usize);
25		let addr = ptr.as_ptr().expose_provenance().into();
26		super::deallocate(addr, size);
27	}
28}