From d96343c249d39fa7a845a088ae8c8c5cfe246abb Mon Sep 17 00:00:00 2001 From: Astro Date: Thu, 18 Jun 2020 00:51:13 +0200 Subject: [PATCH] uncached: refactor into UncachedSlice --- libcortex_a9/src/lib.rs | 3 ++- libcortex_a9/src/uncached.rs | 43 +++++++++++++++++++----------------- libsupport_zynq/src/ram.rs | 2 +- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/libcortex_a9/src/lib.rs b/libcortex_a9/src/lib.rs index e366476..dc6e930 100644 --- a/libcortex_a9/src/lib.rs +++ b/libcortex_a9/src/lib.rs @@ -8,8 +8,9 @@ pub mod asm; pub mod regs; pub mod cache; pub mod mmu; -pub mod uncached; pub mod mutex; pub mod sync_channel; +mod uncached; +pub use uncached::UncachedSlice; global_asm!(include_str!("exceptions.s")); diff --git a/libcortex_a9/src/uncached.rs b/libcortex_a9/src/uncached.rs index ee28492..add8559 100644 --- a/libcortex_a9/src/uncached.rs +++ b/libcortex_a9/src/uncached.rs @@ -2,26 +2,26 @@ use core::{ ops::{Deref, DerefMut}, mem::{align_of, size_of}, }; -use alloc::alloc::{alloc_zeroed, dealloc, Layout, LayoutErr}; +use alloc::alloc::{dealloc, Layout, LayoutErr}; use crate::mmu::{L1_PAGE_SIZE, L1Table}; -pub struct Uncached<'t, T: 't> { +pub struct UncachedSlice { layout: Layout, - data: &'t mut T, + slice: &'static mut [T], } -impl<'t, T: 't> Uncached<'t, T> { +impl UncachedSlice { /// allocates in chunks of 1 MB - pub fn alloc(src: T) -> Result { + pub fn new T>(len: usize, default: F) -> Result { // round to full pages - let size = (size_of::() | (L1_PAGE_SIZE - 1)) + 1; + let size = ((len * size_of::() - 1) | (L1_PAGE_SIZE - 1)) + 1; let align = align_of::() .max(L1_PAGE_SIZE); let layout = Layout::from_size_align(size, align)?; let ptr = unsafe { alloc::alloc::alloc(layout).cast::() }; - assert_eq!((ptr as usize) & (L1_PAGE_SIZE - 1), 0); - let start = ptr as usize; + assert_eq!(start & (L1_PAGE_SIZE - 1), 0); + for page_start in (start..(start + size)).step_by(L1_PAGE_SIZE) { L1Table::get() .update(page_start as *const (), |l1_section| { @@ -29,34 +29,37 @@ impl<'t, T: 't> Uncached<'t, T> { l1_section.bufferable = false; }); } - + + let slice = unsafe { core::slice::from_raw_parts_mut(ptr, len) }; + // verify size + assert!(unsafe { slice.get_unchecked(len) } as *const _ as usize <= start + size); // initialize - unsafe { - core::ptr::write(ptr, src); + for e in slice.iter_mut() { + *e = default(); } - let data = unsafe { &mut *ptr }; - Ok(Uncached { layout, data }) + Ok(UncachedSlice { layout, slice }) } } -impl<'t, T: 't> Drop for Uncached<'t, T> { +/// Does not yet mark the pages cachable again +impl Drop for UncachedSlice { fn drop(&mut self) { unsafe { - dealloc(self.data as *mut _ as *mut u8, self.layout); + dealloc(self.slice.as_mut_ptr() as *mut _ as *mut u8, self.layout); } } } -impl<'t, T: 't> Deref for Uncached<'t, T> { - type Target = T; +impl Deref for UncachedSlice { + type Target = [T]; fn deref(&self) -> &Self::Target { - self.data + self.slice } } -impl<'t, T: 't> DerefMut for Uncached<'t, T> { +impl DerefMut for UncachedSlice { fn deref_mut(&mut self) -> &mut Self::Target { - self.data + self.slice } } diff --git a/libsupport_zynq/src/ram.rs b/libsupport_zynq/src/ram.rs index 5a5b95a..f7721f8 100644 --- a/libsupport_zynq/src/ram.rs +++ b/libsupport_zynq/src/ram.rs @@ -8,7 +8,7 @@ use libboard_zynq::ddr::DdrRam; #[global_allocator] static ALLOCATOR: CortexA9Alloc = CortexA9Alloc(Mutex::new(Heap::empty())); -/// LockedHeap doesn't locking properly +/// LockedHeap doesn't lock properly struct CortexA9Alloc(Mutex); unsafe impl Sync for CortexA9Alloc {}