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}