#![allow(dead_code)]
use core::num::NonZeroUsize;
use core::ptr::{self, NonNull};
use frame_alloc::{PageSize, Provenance};
use std::alloc::{Layout, alloc, dealloc};
pub const PS_64: PageSize = PageSize::from_log2(6);
pub const PS_256: PageSize = PageSize::from_log2(8);
pub const N1: NonZeroUsize = NonZeroUsize::MIN;
pub fn n(v: usize) -> NonZeroUsize {
NonZeroUsize::new(v).unwrap()
}
pub struct OwnedRegion {
ptr: NonNull<u8>,
layout: Layout,
}
impl OwnedRegion {
pub fn new(size: usize, align: usize) -> Self {
let layout = Layout::from_size_align(size, align).unwrap();
let ptr = NonNull::new(unsafe { alloc(layout) }).expect("region allocation failed");
OwnedRegion { ptr, layout }
}
pub fn addr(&self) -> usize {
self.ptr.as_ptr().expose_provenance()
}
pub fn phys_addr(&self) -> usize {
self.addr() - HHDM_OFFSET
}
}
impl Drop for OwnedRegion {
fn drop(&mut self) {
unsafe { dealloc(self.ptr.as_ptr(), self.layout) }
}
}
pub struct TestProvenance;
unsafe impl Provenance for TestProvenance {
unsafe fn create(phys: usize) -> NonNull<u8> {
unsafe { NonNull::new_unchecked(ptr::with_exposed_provenance_mut(phys)) }
}
unsafe fn destroy<T>(ptr: NonNull<T>) -> usize {
ptr.addr().get()
}
}
pub const HHDM_OFFSET: usize = 0x1000;
pub struct HhdmProvenance;
unsafe impl Provenance for HhdmProvenance {
unsafe fn create(phys: usize) -> NonNull<u8> {
unsafe { NonNull::new_unchecked(ptr::with_exposed_provenance_mut(phys + HHDM_OFFSET)) }
}
unsafe fn destroy<T>(ptr: NonNull<T>) -> usize {
ptr.addr().get() - HHDM_OFFSET
}
}
#[allow(unused_imports)]
pub use regioned::Regioned1;
mod regioned {
use core::num::NonZeroUsize;
#[cfg(feature = "stats")]
use frame_alloc::AllocatorStats;
use frame_alloc::{
AllocError, InitError, PageSize, PhysRange, PhysicalAllocator, RegionInit,
RegionedAllocator,
};
pub struct Regioned1<A>(RegionedAllocator<1, A>);
impl<A> Regioned1<A> {
pub fn new(base: PageSize, inner: A) -> Self {
Regioned1(RegionedAllocator::new(base, [inner]))
}
}
unsafe impl<A: RegionInit> RegionInit for Regioned1<A> {
unsafe fn try_init(
&self,
phys_base: usize,
span_len: usize,
usable: &[PhysRange],
) -> Result<(), InitError> {
unsafe { self.0.try_init_at(0, phys_base, span_len, usable) }
}
unsafe fn add_usable(&self, base: usize, len: usize) {
unsafe { self.0.add_usable(base, len) };
}
}
unsafe impl<A: PhysicalAllocator> PhysicalAllocator for Regioned1<A> {
fn allocate_physical(
&self,
ps: PageSize,
count: NonZeroUsize,
) -> Result<usize, AllocError> {
self.0.allocate_physical(ps, count)
}
unsafe fn deallocate_physical(&self, ps: PageSize, count: NonZeroUsize, phys: usize) {
unsafe { self.0.deallocate_physical(ps, count, phys) };
}
}
#[cfg(feature = "stats")]
impl<A: AllocatorStats> AllocatorStats for Regioned1<A> {
fn total_bytes(&self) -> usize {
self.0.total_bytes()
}
fn free_bytes(&self) -> usize {
self.0.free_bytes()
}
fn largest_free_bytes(&self) -> usize {
self.0.largest_free_bytes()
}
}
}