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
96impl<T> Index<usize> for DSliceMut<'_, T> {
97 type Output = T;
98
99 fn index(&self, index: usize) -> &Self::Output {
100 self.inner.index(index)
101 }
102}
103
104impl<T> Deref for DSliceMut<'_, T> {
105 type Target = [T];
106
107 fn deref(&self) -> &Self::Target {
108 &self.inner
109 }
110}
111
112struct DSliceCommon<'a, T> {
113 addr: NonNull<T>,
114 size: usize,
115 bus_addr: u64,
116 direction: Direction,
117 _marker: PhantomData<&'a T>,
118}
119
120impl<'a, T> DSliceCommon<'a, T> {
121 fn new(s: &'a [T], direction: Direction) -> Self {
122 let size = size_of_val(s);
123 let ptr = unsafe { NonNull::new_unchecked(s.as_ptr() as usize as *mut T) };
124 let bus_addr = map(ptr.cast(), size, direction);
125
126 flush(ptr.cast(), size);
127
128 Self {
129 addr: ptr,
130 size,
131 bus_addr,
132 direction,
133 _marker: PhantomData,
134 }
135 }
136
137 fn len(&self) -> usize {
138 self.size / size_of::<T>()
139 }
140
141 fn index(&self, index: usize) -> &T {
142 assert!(index < self.len());
143
144 let ptr = unsafe { self.addr.add(index) };
145
146 self.direction.preper_read(ptr.cast(), size_of::<T>());
147
148 unsafe { ptr.as_ref() }
149 }
150
151 fn preper_read_all(&self) {
152 self.direction.preper_read(self.addr.cast(), self.size);
153 }
154}
155
156impl<T> Drop for DSliceCommon<'_, T> {
157 fn drop(&mut self) {
158 unmap(self.addr.cast(), self.size);
159 }
160}
161
162impl<T> Deref for DSliceCommon<'_, T> {
163 type Target = [T];
164
165 fn deref(&self) -> &Self::Target {
166 self.direction.preper_read(self.addr.cast(), self.size);
167 unsafe { &*slice_from_raw_parts(self.addr.as_ptr(), self.len()) }
168 }
169}