1#[cfg(feature = "alloc")]
2use alloc::vec::Vec;
3use core::{
4 alloc::Layout,
5 mem::size_of,
6 ops::{Deref, Index},
7};
8
9use super::DCommon;
10use crate::Direction;
11
12pub struct DVec<T> {
13 inner: DCommon<T>,
14}
15
16impl<T> DVec<T> {
17 const T_SIZE: usize = size_of::<T>();
18
19 pub fn zeros(len: usize, align: usize, direction: Direction) -> Option<Self> {
20 let size = len * size_of::<T>();
21 let layout = Layout::from_size_align(size, align).unwrap();
22
23 Some(Self {
24 inner: DCommon::zeros(layout, direction)?,
25 })
26 }
27
28 #[cfg(feature = "alloc")]
29 pub fn from_vec(value: Vec<T>, direction: Direction) -> Self {
30 Self {
31 inner: DCommon::from_vec(value, direction),
32 }
33 }
34
35 #[cfg(feature = "alloc")]
36 pub fn to_vec(mut self) -> Vec<T> {
37 unsafe {
38 self.inner
39 .preper_read(self.inner.addr.cast(), self.inner.layout.size());
40 crate::unmap(self.inner.addr.cast(), self.inner.layout.size());
41 let len = self.len();
42
43 self.inner.layout = Layout::from_size_align_unchecked(0, 0x1000);
44 Vec::from_raw_parts(self.inner.addr.as_ptr(), len, len)
45 }
46 }
47
48 pub fn len(&self) -> usize {
49 self.inner.layout.size() / size_of::<T>()
50 }
51
52 pub fn is_empty(&self) -> bool {
53 self.len() == 0
54 }
55
56 pub fn bus_addr(&self) -> u64 {
57 self.inner.bus_addr
58 }
59
60 pub fn get(&self, index: usize) -> Option<T> {
61 if index >= self.len() {
62 return None;
63 }
64
65 unsafe {
66 let ptr = self.inner.addr.add(index);
67
68 self.inner.preper_read(ptr.cast(), Self::T_SIZE);
69
70 Some(ptr.read_volatile())
71 }
72 }
73
74 pub fn set(&mut self, index: usize, value: T) {
75 assert!(
76 index < self.len(),
77 "index out of range, index: {},len: {}",
78 index,
79 self.len()
80 );
81
82 unsafe {
83 let ptr = self.inner.addr.add(index);
84
85 ptr.write_volatile(value);
86
87 self.inner.confirm_write(ptr.cast(), Self::T_SIZE);
88 }
89 }
90
91 fn as_slice_mut(&mut self) -> &mut [T] {
92 unsafe { core::slice::from_raw_parts_mut(self.inner.addr.as_ptr(), self.len()) }
93 }
94}
95
96impl<T> Index<usize> for DVec<T> {
97 type Output = T;
98
99 fn index(&self, index: usize) -> &Self::Output {
100 assert!(index < self.len());
101
102 let ptr = unsafe { self.inner.addr.add(index) };
103
104 self.inner.preper_read(ptr.cast(), Self::T_SIZE);
105
106 unsafe { &*ptr.as_ptr() }
107 }
108}
109
110impl<T: Copy> DVec<T> {
111 pub fn copy_from_slice(&mut self, src: &[T]) {
112 assert!(src.len() <= self.len());
113
114 self.as_slice_mut().copy_from_slice(src);
115
116 self.inner
117 .confirm_write(self.inner.addr.cast(), Self::T_SIZE * src.len());
118 }
119}
120
121impl<T> Deref for DVec<T> {
122 type Target = [T];
123
124 fn deref(&self) -> &Self::Target {
125 self.inner
126 .preper_read(self.inner.addr.cast(), Self::T_SIZE * self.len());
127 unsafe { core::slice::from_raw_parts(self.inner.addr.as_ptr(), self.len()) }
128 }
129}