1use core::ops::Index;
2
3use crate::{DeviceDma, Direction, DmaError, common::DCommon};
4
5pub struct DArray<T> {
6 data: DCommon<T>,
7}
8
9unsafe impl<T> Send for DArray<T> where T: Send {}
10
11impl<T> DArray<T> {
12 pub(crate) fn new_zero(
13 os: &DeviceDma,
14 size: usize,
15 align: usize,
16 direction: Direction,
17 ) -> Result<Self, DmaError> {
18 let mut data = DCommon::new(os, size * core::mem::size_of::<T>(), align, direction)?;
19 data.as_mut_slice().fill(0);
20 data.confirm_write_all();
21 Ok(Self { data })
22 }
23
24 pub fn dma_addr(&self) -> crate::DmaAddr {
25 self.data.handle.dma_addr
26 }
27
28 pub fn len(&self) -> usize {
29 self.data.handle.size() / core::mem::size_of::<T>()
30 }
31
32 pub fn is_empty(&self) -> bool {
33 self.len() == 0
34 }
35
36 pub fn read(&self, index: usize) -> Option<T> {
37 if index >= self.len() {
38 return None;
39 }
40
41 unsafe {
42 let offset = index * core::mem::size_of::<T>();
43 self.data.prepare_read(offset, size_of::<T>());
44 Some(self.data.get_ptr(offset).cast::<T>().read_volatile())
45 }
46 }
47
48 pub fn set(&mut self, index: usize, value: T) {
49 assert!(
50 index < self.len(),
51 "index out of range, index: {},len: {}",
52 index,
53 self.len()
54 );
55
56 unsafe {
57 let offset = index * size_of::<T>();
58 let ptr = self.data.get_ptr(offset).cast::<T>();
59 ptr.write_volatile(value);
60 self.data.confirm_write(offset, size_of::<T>());
61 }
62 }
63
64 pub fn iter(&self) -> DArrayIter<'_, T> {
65 DArrayIter {
66 array: self,
67 index: 0,
68 }
69 }
70
71 pub fn copy_from_slice(&mut self, src: &[T]) {
72 assert!(
73 src.len() <= self.len(),
74 "source slice is larger than DArray, src len: {}, DArray len: {}",
75 src.len(),
76 self.len()
77 );
78 let src_bytes = unsafe {
79 core::slice::from_raw_parts(src.as_ptr() as *const u8, core::mem::size_of_val(src))
80 };
81 self.data.as_mut_slice().copy_from_slice(src_bytes);
82 self.data.confirm_write_all();
83 }
84
85 pub unsafe fn as_mut_slice(&mut self) -> &mut [T] {
89 let byte_slice = self.data.as_mut_slice();
90 unsafe {
91 core::slice::from_raw_parts_mut(
92 byte_slice.as_mut_ptr() as *mut T,
93 byte_slice.len() / core::mem::size_of::<T>(),
94 )
95 }
96 }
97
98 pub fn as_ptr(&self) -> *mut T {
99 self.data.handle.as_ptr().cast::<T>()
100 }
101}
102
103pub struct DArrayIter<'a, T> {
104 array: &'a DArray<T>,
105 index: usize,
106}
107
108impl<'a, T> Iterator for DArrayIter<'a, T> {
109 type Item = T;
110
111 fn next(&mut self) -> Option<Self::Item> {
112 if self.index >= self.array.len() {
113 return None;
114 }
115 let value = self.array.read(self.index);
116 self.index += 1;
117 value
118 }
119}
120
121impl<T: Copy> Index<usize> for DArray<T> {
122 type Output = T;
123
124 fn index(&self, index: usize) -> &Self::Output {
125 assert!(
126 index < self.len(),
127 "index out of range, index: {},len: {}",
128 index,
129 self.len()
130 );
131 unsafe {
132 let offset = index * core::mem::size_of::<T>();
136 let ptr = self.data.get_ptr(offset).cast::<T>();
137 self.data.prepare_read(offset, size_of::<T>());
138 &*ptr
139 }
140 }
141}