1use core::{
2 marker::PhantomData,
3 mem::{size_of, size_of_val},
4 ops::{Deref, Index},
5 ptr::{slice_from_raw_parts, NonNull},
6};
7
8use crate::{flush, map, unmap, Direction};
9
10#[repr(transparent)]
11pub struct DSlice<'a, T> {
12 inner: DSliceCommon<'a, T>,
13}
14
15impl<T> DSlice<'_, T> {
16 pub fn len(&self) -> usize {
17 self.inner.len()
18 }
19
20 pub fn bus_addr(&self) -> u64 {
21 self.inner.bus_addr
22 }
23
24 pub fn is_empty(&self) -> bool {
25 self.len() == 0
26 }
27}
28
29impl<'a, T> From<&'a [T]> for DSlice<'a, T> {
30 fn from(value: &'a [T]) -> Self {
31 Self {
32 inner: DSliceCommon::new(value, Direction::ToDevice),
33 }
34 }
35}
36
37impl<T> Index<usize> for DSlice<'_, T> {
38 type Output = T;
39
40 fn index(&self, index: usize) -> &Self::Output {
41 self.inner.index(index)
42 }
43}
44
45impl<T> Deref for DSlice<'_, T> {
46 type Target = [T];
47
48 fn deref(&self) -> &Self::Target {
49 &self.inner
50 }
51}
52
53#[repr(transparent)]
54pub struct DSliceMut<'a, T> {
55 inner: DSliceCommon<'a, T>,
56}
57
58impl<'a, T> DSliceMut<'a, T> {
59 pub fn from(value: &'a mut [T], direction: Direction) -> Self {
60 Self {
61 inner: DSliceCommon::new(value, direction),
62 }
63 }
64
65 pub fn bus_addr(&self) -> u64 {
66 self.inner.bus_addr
67 }
68
69 pub fn len(&self) -> usize {
70 self.inner.len()
71 }
72
73 pub fn is_empty(&self) -> bool {
74 self.len() == 0
75 }
76
77 pub fn set(&self, index: usize, value: T) {
78 assert!(index < self.len());
79
80 unsafe {
81 let ptr = self.inner.addr.add(index);
82
83 ptr.write_volatile(value);
84
85 self.inner
86 .direction
87 .confirm_write(ptr.cast(), size_of::<T>());
88 }
89 }
90
91 pub fn preper_read_all(&self) {
92 self.inner.preper_read_all();
93 }
94
95 pub fn preper_write_all(&self) {
96 self.inner
97 .direction
98 .confirm_write(self.inner.addr.cast(), self.inner.size);
99 }
100}
101
102impl<T> Index<usize> for DSliceMut<'_, T> {
103 type Output = T;
104
105 fn index(&self, index: usize) -> &Self::Output {
106 self.inner.index(index)
107 }
108}
109
110impl<T> Deref for DSliceMut<'_, T> {
111 type Target = [T];
112
113 fn deref(&self) -> &Self::Target {
114 &self.inner
115 }
116}
117
118struct DSliceCommon<'a, T> {
119 addr: NonNull<T>,
120 size: usize,
121 bus_addr: u64,
122 direction: Direction,
123 _marker: PhantomData<&'a T>,
124}
125
126impl<'a, T> DSliceCommon<'a, T> {
127 fn new(s: &'a [T], direction: Direction) -> Self {
128 let size = size_of_val(s);
129 let ptr = unsafe { NonNull::new_unchecked(s.as_ptr() as usize as *mut T) };
130 let bus_addr = map(ptr.cast(), size, direction);
131
132 flush(ptr.cast(), size);
133
134 Self {
135 addr: ptr,
136 size,
137 bus_addr,
138 direction,
139 _marker: PhantomData,
140 }
141 }
142
143 fn len(&self) -> usize {
144 self.size / size_of::<T>()
145 }
146
147 fn index(&self, index: usize) -> &T {
148 assert!(index < self.len());
149
150 let ptr = unsafe { self.addr.add(index) };
151
152 self.direction.preper_read(ptr.cast(), size_of::<T>());
153
154 unsafe { ptr.as_ref() }
155 }
156
157 fn preper_read_all(&self) {
158 self.direction.preper_read(self.addr.cast(), self.size);
159 }
160}
161
162impl<T> Drop for DSliceCommon<'_, T> {
163 fn drop(&mut self) {
164 unmap(self.addr.cast(), self.size);
165 }
166}
167
168impl<T> Deref for DSliceCommon<'_, T> {
169 type Target = [T];
170
171 fn deref(&self) -> &Self::Target {
172 self.direction.preper_read(self.addr.cast(), self.size);
173 unsafe { &*slice_from_raw_parts(self.addr.as_ptr(), self.len()) }
174 }
175}