dma_api/dma/alloc/
box.rs

1use core::alloc::Layout;
2
3use crate::Direction;
4
5use super::DCommon;
6
7pub struct DBox<T> {
8    inner: DCommon<T>,
9}
10
11impl<T> DBox<T> {
12    const SIZE: usize = core::mem::size_of::<T>();
13
14    pub fn zero_with_align(direction: Direction, align: usize) -> Option<Self> {
15        let layout = Layout::from_size_align(Self::SIZE, align).ok()?;
16
17        Some(Self {
18            inner: DCommon::zeros(layout, direction)?,
19        })
20    }
21
22    pub fn zero(direction: Direction) -> Option<Self> {
23        let layout = Layout::new::<T>();
24        Some(Self {
25            inner: DCommon::zeros(layout, direction)?,
26        })
27    }
28    pub fn bus_addr(&self) -> u64 {
29        self.inner.bus_addr
30    }
31
32    pub fn read(&self) -> T {
33        unsafe {
34            let ptr = self.inner.addr;
35
36            self.inner.preper_read(ptr.cast(), Self::SIZE);
37
38            ptr.read_volatile()
39        }
40    }
41
42    pub fn write(&mut self, value: T) {
43        unsafe {
44            let ptr = self.inner.addr;
45
46            ptr.write_volatile(value);
47
48            self.inner.confirm_write(ptr.cast(), Self::SIZE);
49        }
50    }
51
52    pub fn modify(&mut self, f: impl FnOnce(&mut T)) {
53        unsafe {
54            let mut ptr = self.inner.addr;
55
56            self.inner.preper_read(ptr.cast(), Self::SIZE);
57
58            f(ptr.as_mut());
59
60            self.inner.confirm_write(ptr.cast(), Self::SIZE);
61        }
62    }
63}