dma_api/
array.rs

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    /// # Safety
86    ///
87    /// slice will not auto do cache sync operations.
88    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 ptr = self.data.handle.origin_virt.cast::<T>().add(index);
133            // self.data.prepare_read(ptr.cast(), size_of::<T>());
134            // &*ptr.as_ptr()
135            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}