diff --git a/xous-rs/src/arch/hosted/mem.rs b/xous-rs/src/arch/hosted/mem.rs index a228e2758..cb3df36b4 100644 --- a/xous-rs/src/arch/hosted/mem.rs +++ b/xous-rs/src/arch/hosted/mem.rs @@ -1,4 +1,8 @@ use crate::{Error, MemoryAddress, MemoryFlags, MemoryRange}; +const PAGE_SIZE: usize = 4096; + +extern crate alloc; +use alloc::alloc::{alloc, dealloc, Layout}; pub fn map_memory_pre( _phys: &Option, @@ -9,21 +13,21 @@ pub fn map_memory_pre( Ok(()) } -#[allow(unused_mut)] pub fn map_memory_post( _phys: Option, _virt: Option, - _size: usize, + size: usize, _flags: MemoryFlags, - mut range: MemoryRange, + _range: MemoryRange, ) -> core::result::Result { - let data = vec![0u8; range.len()]; - let mut data = std::mem::ManuallyDrop::new(data); - data.shrink_to_fit(); - assert_eq!(data.len(), data.capacity()); - let len = data.len(); - let addr = data.as_mut_ptr(); - Ok(unsafe { crate::MemoryRange::new(addr as _, len).unwrap() }) + // let rounded_size = (size + PAGE_SIZE - 1) & !(PAGE_SIZE - 1); + let layout = Layout::from_size_align(size, PAGE_SIZE) + .unwrap() + .pad_to_align(); + let mem = unsafe { alloc(layout) } as usize; + + // println!("Allocated {} bytes (requested {}) @ {:016x}", rounded_size, size, mem); + unsafe { MemoryRange::new(mem, size) } } pub fn unmap_memory_pre(_range: &MemoryRange) -> core::result::Result<(), Error> { @@ -31,48 +35,12 @@ pub fn unmap_memory_pre(_range: &MemoryRange) -> core::result::Result<(), Error> } pub fn unmap_memory_post(range: MemoryRange) -> core::result::Result<(), Error> { - let _v = unsafe { std::vec::Vec::from_raw_parts(range.as_mut_ptr(), range.len(), range.len()) }; + // println!("Request to free {} bytes @ {:016x}", range.len(), range.as_ptr() as usize); + // let rounded_size = (range.len() + 4095) / 4096; + let layout = Layout::from_size_align(range.len(), PAGE_SIZE) + .unwrap() + .pad_to_align(); + let ptr = range.as_mut_ptr(); + unsafe { dealloc(ptr, layout) }; Ok(()) } - -// Ideally we'd use the `alloc` API directly, however this doesn't work for unknown reasons. -// The code is left here as an exercise to someone who wants to figure out why. - -// use crate::{Error, MemoryAddress, MemoryFlags, MemoryRange}; - -// extern crate alloc; -// use alloc::alloc::{alloc, dealloc, Layout}; - -// pub fn map_memory_pre( -// _phys: &Option, -// _virt: &Option, -// _size: usize, -// _flags: MemoryFlags, -// ) -> core::result::Result<(), Error> { -// Ok(()) -// } - -// pub fn map_memory_post( -// _phys: Option, -// _virt: Option, -// size: usize, -// _flags: MemoryFlags, -// _range: MemoryRange, -// ) -> core::result::Result { -// let rounded_size = (size + 4095) / 4096; - -// let layout = Layout::from_size_align(rounded_size, 4096).unwrap(); -// unsafe { MemoryRange::new(alloc(layout) as usize, size) } -// } - -// pub fn unmap_memory_pre(_range: &MemoryRange) -> core::result::Result<(), Error> { -// Ok(()) -// } - -// pub fn unmap_memory_post(range: MemoryRange) -> core::result::Result<(), Error> { -// // let rounded_size = (range.len() + 4095) / 4096; -// // let layout = Layout::from_size_align(rounded_size, 4096).unwrap(); -// // let ptr = range.as_mut_ptr(); -// // unsafe { dealloc(ptr, layout) }; -// Ok(()) -// } diff --git a/xous-rs/src/arch/hosted/mod.rs b/xous-rs/src/arch/hosted/mod.rs index 413bcf4e4..03d12fe96 100644 --- a/xous-rs/src/arch/hosted/mod.rs +++ b/xous-rs/src/arch/hosted/mod.rs @@ -425,12 +425,9 @@ fn read_next_syscall_result( mem::unmap_memory_post(mem).unwrap(); } - // If we're returning memory to the Server, then reconstitute the buffer we just passed, - // and Drop it so it can be freed. + // If we're returning memory to the Server, then free it here if kind == CallMemoryKind::ReturnMemory { - let rebuilt = - unsafe { Vec::from_raw_parts(mem.as_mut_ptr(), mem.len(), mem.len()) }; - drop(rebuilt); + mem::unmap_memory_post(mem).unwrap(); } } return (msg_thread_id, response);