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