1use core::{
2 marker::PhantomData,
3 mem::{size_of, size_of_val},
4 ops::Index,
5 ptr::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<'a, T> DSlice<'a, 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 pub fn from(value: &'a [T], direction: Direction) -> Self {
29 Self {
30 inner: DSliceCommon::new(value, direction),
31 }
32 }
33
34 pub fn preper_read_all(&self) {
35 self.inner.preper_read_all();
36 }
37
38 pub fn confirm_write_all(&self) {
39 self.inner.confirm_write_all();
40 }
41}
42
43impl<T> Index<usize> for DSlice<'_, T> {
44 type Output = T;
45
46 fn index(&self, index: usize) -> &Self::Output {
47 self.inner.index(index)
48 }
49}
50
51impl<T> AsRef<[T]> for DSlice<'_, T> {
52 fn as_ref(&self) -> &[T] {
53 self.inner.as_ref()
54 }
55}
56
57#[repr(transparent)]
58pub struct DSliceMut<'a, T> {
59 inner: DSliceCommon<'a, T>,
60}
61
62impl<'a, T> DSliceMut<'a, T> {
63 pub fn from(value: &'a mut [T], direction: Direction) -> Self {
64 Self {
65 inner: DSliceCommon::new(value, direction),
66 }
67 }
68
69 pub fn bus_addr(&self) -> u64 {
70 self.inner.bus_addr
71 }
72
73 pub fn len(&self) -> usize {
74 self.inner.len()
75 }
76
77 pub fn is_empty(&self) -> bool {
78 self.len() == 0
79 }
80
81 pub fn set(&self, index: usize, value: T) {
82 assert!(index < self.len());
83
84 unsafe {
85 let ptr = self.inner.addr.add(index);
86
87 ptr.write_volatile(value);
88
89 self.inner
90 .direction
91 .confirm_write(ptr.cast(), size_of::<T>());
92 }
93 }
94
95 pub fn preper_read_all(&self) {
96 self.inner.preper_read_all();
97 }
98
99 pub fn confirm_write_all(&self) {
100 self.inner.confirm_write_all();
101 }
102}
103
104impl<T> Index<usize> for DSliceMut<'_, T> {
105 type Output = T;
106
107 fn index(&self, index: usize) -> &Self::Output {
108 self.inner.index(index)
109 }
110}
111
112impl<T> AsRef<[T]> for DSliceMut<'_, T> {
113 fn as_ref(&self) -> &[T] {
114 self.inner.as_ref()
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
159 .preper_read(self.addr.cast(), self.size * size_of::<T>());
160 }
161
162 fn confirm_write_all(&self) {
163 self.direction
164 .confirm_write(self.addr.cast(), self.size * size_of::<T>());
165 }
166}
167
168impl<T> Drop for DSliceCommon<'_, T> {
169 fn drop(&mut self) {
170 unmap(self.addr.cast(), self.size);
171 }
172}
173
174impl<T> AsRef<[T]> for DSliceCommon<'_, T> {
175 fn as_ref(&self) -> &[T] {
176 self.preper_read_all();
177 unsafe { core::slice::from_raw_parts_mut(self.addr.as_ptr(), self.len()) }
178 }
179}