From a2938fc7a3370f87069a8bbdf2179949d98b8241 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Sun, 19 Jan 2020 12:36:02 +1100 Subject: [PATCH 1/2] Allow Dma to use ?Sized types, mostly for slices. --- src/io/dma.rs | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/io/dma.rs b/src/io/dma.rs index f2a9a12..44ca782 100644 --- a/src/io/dma.rs +++ b/src/io/dma.rs @@ -24,7 +24,7 @@ impl Drop for PhysBox { } } -pub struct Dma { +pub struct Dma { phys: PhysBox, virt: *mut T } @@ -49,28 +49,45 @@ impl Dma { virt: virt }) } - pub fn physical(&self) -> usize { self.phys.address } } +impl Dma<[T]> { + /// Crates a new DMA buffer with a size only known at runtime. + /// ## Safety + /// * `T` must be properly aligned. + /// * `T` must be valid as zeroed (i.e. no NonNull pointers). + pub unsafe fn zeroed_unsized(count: usize) -> Result { + let phys = PhysBox::new(mem::size_of::() * count)?; + let virt_ptr = crate::physmap(phys.address, phys.size, crate::PHYSMAP_WRITE)? as *mut T; + ptr::write_bytes(virt_ptr, 0, count); -impl Deref for Dma { + let virt = core::slice::from_raw_parts_mut(virt_ptr, count); + + Ok(Dma { + phys, + virt, + }) + } +} + +impl Deref for Dma { type Target = T; fn deref(&self) -> &T { unsafe { &*self.virt } } } -impl DerefMut for Dma { +impl DerefMut for Dma { fn deref_mut(&mut self) -> &mut T { unsafe { &mut *self.virt } } } -impl Drop for Dma { +impl Drop for Dma { fn drop(&mut self) { - unsafe { drop(ptr::read(self.virt)); } - let _ = unsafe { crate::physunmap(self.virt as usize) }; + unsafe { ptr::drop_in_place(self.virt) } + let _ = unsafe { crate::physunmap(self.virt as *mut u8 as usize) }; } } From 08a3800e873b2cf018ecd7fb2695b0ea43326a9b Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Sun, 19 Jan 2020 13:16:56 +1100 Subject: [PATCH 2/2] Also allow ?Sized types to get the physaddr. --- src/io/dma.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/io/dma.rs b/src/io/dma.rs index 44ca782..d3ffbb9 100644 --- a/src/io/dma.rs +++ b/src/io/dma.rs @@ -49,10 +49,13 @@ impl Dma { virt: virt }) } +} +impl Dma { pub fn physical(&self) -> usize { self.phys.address } } + impl Dma<[T]> { /// Crates a new DMA buffer with a size only known at runtime. /// ## Safety