sparreal_kernel/mem/
addr.rs1use core::fmt::Display;
2use core::marker::PhantomData;
3use core::ops::{Add, Sub};
4use core::ptr::NonNull;
5
6use super::va_offset_now;
7
8#[derive(Debug, Clone, Copy)]
9pub struct Address {
10 pub cpu: usize,
11 pub virt: Option<usize>,
12 pub bus: Option<u64>,
13}
14
15impl Address {
16 pub fn new(cpu: usize, virt: Option<*mut u8>, bus: Option<u64>) -> Self {
17 Self {
18 cpu,
19 virt: virt.map(|s| s as usize),
20 bus,
21 }
22 }
23
24 pub fn as_ptr(&self) -> *const u8 {
25 match self.virt {
26 Some(virt) => virt as *const u8,
27 None => self.cpu as *const u8,
28 }
29 }
30
31 pub fn bus(&self) -> u64 {
32 match self.bus {
33 Some(bus) => bus,
34 None => self.cpu as _,
35 }
36 }
37
38 pub fn physical(&self) -> usize {
39 self.cpu
40 }
41}
42
43impl Add<usize> for Address {
44 type Output = Self;
45
46 fn add(self, rhs: usize) -> Self::Output {
47 Self {
48 cpu: self.cpu + rhs,
49 virt: self.virt.map(|s| s + rhs),
50 bus: self.bus.map(|s| s + rhs as u64),
51 }
52 }
53}
54
55impl Sub<usize> for Address {
56 type Output = Self;
57
58 fn sub(self, rhs: usize) -> Self::Output {
59 Self {
60 cpu: self.cpu - rhs,
61 virt: self.virt.map(|s| s - rhs),
62 bus: self.bus.map(|s| s - rhs as u64),
63 }
64 }
65}
66
67#[derive(Clone, Copy, PartialEq, PartialOrd)]
68#[repr(transparent)]
69pub struct Virt<T>(usize, PhantomData<T>);
70unsafe impl<T> Send for Virt<T> {}
71
72impl<T> From<*const T> for Virt<T> {
73 fn from(value: *const T) -> Self {
74 Self(value as _, PhantomData)
75 }
76}
77impl<T> From<*mut T> for Virt<T> {
78 fn from(value: *mut T) -> Self {
79 Self(value as _, PhantomData)
80 }
81}
82impl<T> From<NonNull<T>> for Virt<T> {
83 fn from(value: NonNull<T>) -> Self {
84 Self(value.as_ptr() as _, PhantomData)
85 }
86}
87
88impl<T> From<Virt<T>> for *const T {
89 fn from(value: Virt<T>) -> Self {
90 value.0 as *const T
91 }
92}
93
94pub type VirtAddr = Virt<u8>;
95
96impl<T> Virt<T> {
97 pub const fn new() -> Self {
98 Self(0, PhantomData)
99 }
100
101 pub fn as_mut_ptr(self) -> *mut T {
102 self.0 as *mut T
103 }
104
105 pub fn as_usize(self) -> usize {
106 self.0
107 }
108}
109
110impl<T> Default for Virt<T> {
111 fn default() -> Self {
112 Self::new()
113 }
114}
115
116impl<T> From<usize> for Virt<T> {
117 fn from(value: usize) -> Self {
118 Self(value, PhantomData)
119 }
120}
121impl<T> From<Virt<T>> for usize {
122 fn from(value: Virt<T>) -> Self {
123 value.0
124 }
125}
126
127impl<T> From<PhysAddr> for Virt<T> {
128 fn from(value: PhysAddr) -> Self {
129 Self((value.0 + va_offset_now()) as _, PhantomData)
130 }
131}
132
133impl From<PhysAddr> for usize {
134 fn from(value: PhysAddr) -> Self {
135 value.0
136 }
137}
138
139impl<T> From<Virt<T>> for PhysAddr {
140 fn from(value: Virt<T>) -> Self {
141 Self(value.as_usize() - va_offset_now())
142 }
143}
144
145#[derive(Default, Clone, Copy, PartialEq, PartialOrd)]
146#[repr(transparent)]
147pub struct PhysAddr(usize);
148
149unsafe impl Send for PhysAddr {}
150
151impl From<usize> for PhysAddr {
152 fn from(value: usize) -> Self {
153 Self(value as _)
154 }
155}
156
157impl PhysAddr {
158 pub const fn new() -> Self {
159 Self(0)
160 }
161
162 pub fn as_usize(&self) -> usize {
163 self.0
164 }
165}
166
167impl Sub<PhysAddr> for PhysAddr {
168 type Output = usize;
169
170 fn sub(self, rhs: PhysAddr) -> Self::Output {
171 self.as_usize() - rhs.as_usize()
172 }
173}
174
175pub trait Align: Clone + Copy
176where
177 usize: From<Self>,
178{
179 fn align_down(self, align: usize) -> Self
180 where
181 Self: From<usize>,
182 {
183 align_down(self.into(), align).into()
184 }
185
186 fn align_up(self, align: usize) -> Self
187 where
188 Self: From<usize>,
189 {
190 align_up(self.into(), align).into()
191 }
192
193 fn is_aligned_4k(self) -> bool {
194 self.is_aligned_to(0x1000)
195 }
196
197 fn is_aligned_to(self, align: usize) -> bool {
198 align_offset(self.into(), align) == 0
199 }
200}
201
202impl<T> Align for T
203where
204 T: Into<usize> + From<usize> + Copy,
205 usize: From<T>,
206{
207}
208
209impl<T> Add<usize> for Virt<T> {
210 type Output = Self;
211
212 fn add(self, rhs: usize) -> Self::Output {
213 let lhs: usize = self.into();
214 (lhs + rhs).into()
215 }
216}
217
218pub const fn align_offset(addr: usize, align: usize) -> usize {
219 addr & (align - 1)
220}
221
222pub const fn align_down(addr: usize, align: usize) -> usize {
223 addr & !(align - 1)
224}
225
226pub const fn align_up(addr: usize, align: usize) -> usize {
227 (addr + align - 1) & !(align - 1)
228}
229
230impl Add<usize> for PhysAddr {
231 type Output = Self;
232
233 fn add(self, rhs: usize) -> Self::Output {
234 (self.as_usize() + rhs).into()
235 }
236}
237
238impl<T> Sub<usize> for Virt<T> {
239 type Output = Self;
240
241 fn sub(self, rhs: usize) -> Self::Output {
242 (self.as_usize() - rhs).into()
243 }
244}
245
246impl<T> Sub<Virt<T>> for Virt<T> {
247 type Output = usize;
248
249 fn sub(self, rhs: Virt<T>) -> Self::Output {
250 self.as_usize() - rhs.as_usize()
251 }
252}
253
254impl Display for PhysAddr {
255 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
256 write!(f, "{:#x}", self.0)
257 }
258}
259impl<T> Display for Virt<T> {
260 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
261 write!(f, "{:#x}", self.0)
262 }
263}
264
265impl core::fmt::Debug for PhysAddr {
266 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
267 write!(f, "{:#x}", self.0)
268 }
269}
270impl<T> core::fmt::Debug for Virt<T> {
271 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
272 write!(f, "{:#x}", self.0)
273 }
274}