use alloc::sync::Arc;
use core::alloc::Layout;
use ax_dma::{self, DMAInfo};
use super::{
error::{IonError, IonResult},
types::{IonBuffer, IonHeapType},
};
pub struct IonHeapManager;
impl Default for IonHeapManager {
fn default() -> Self {
Self::new()
}
}
impl IonHeapManager {
pub const fn new() -> Self {
Self
}
pub fn alloc_buffer(
&self,
size: usize,
align: usize,
heap_type: IonHeapType,
) -> IonResult<Arc<IonBuffer>> {
debug!(
"Allocating Ion buffer: size={}, align={}, heap_type={:?}",
size, align, heap_type
);
if size == 0 {
return Err(IonError::InvalidArg);
}
let dma_info = match heap_type {
IonHeapType::System => {
self.alloc_dma_buffer(size, align)?
}
IonHeapType::DmaCoherent => {
self.alloc_dma_buffer(size, align)?
}
IonHeapType::Carveout => {
warn!("Carveout heap not implemented, using DMA heap instead");
self.alloc_dma_buffer(size, align)?
}
};
let buffer = Arc::new(IonBuffer::new(dma_info, size));
debug!("Allocated Ion buffer with handle: {:?}", buffer.handle);
Ok(buffer)
}
fn alloc_dma_buffer(&self, size: usize, align: usize) -> IonResult<DMAInfo> {
let layout = Layout::from_size_align(size, align).map_err(|_| IonError::InvalidArg)?;
unsafe { ax_dma::alloc_coherent_pages(layout).map_err(|_| IonError::NoMemory) }
}
}