dma_api/dma/alloc/
vec.rs

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}