1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
use core::{mem, ptr}; use core::ops::{Deref, DerefMut}; use Result; struct PhysBox { address: usize, size: usize } impl PhysBox { fn new(size: usize) -> Result<PhysBox> { let address = unsafe { ::physalloc(size)? }; Ok(PhysBox { address: address, size: size }) } } impl Drop for PhysBox { fn drop(&mut self) { let _ = unsafe { ::physfree(self.address, self.size) }; } } pub struct Dma<T> { phys: PhysBox, virt: *mut T } impl<T> Dma<T> { pub fn new(value: T) -> Result<Dma<T>> { let phys = PhysBox::new(mem::size_of::<T>())?; let virt = unsafe { ::physmap(phys.address, phys.size, ::PHYSMAP_WRITE)? } as *mut T; unsafe { ptr::write(virt, value); } Ok(Dma { phys: phys, virt: virt }) } pub fn zeroed() -> Result<Dma<T>> { let phys = PhysBox::new(mem::size_of::<T>())?; let virt = unsafe { ::physmap(phys.address, phys.size, ::PHYSMAP_WRITE)? } as *mut T; unsafe { ptr::write_bytes(virt as *mut u8, 0, phys.size); } Ok(Dma { phys: phys, virt: virt }) } pub fn physical(&self) -> usize { self.phys.address } } impl<T> Deref for Dma<T> { type Target = T; fn deref(&self) -> &T { unsafe { &*self.virt } } } impl<T> DerefMut for Dma<T> { fn deref_mut(&mut self) -> &mut T { unsafe { &mut *self.virt } } } impl<T> Drop for Dma<T> { fn drop(&mut self) { unsafe { drop(ptr::read(self.virt)); } let _ = unsafe { ::physunmap(self.virt as usize) }; } }