sparreal_kernel/mem/
addr.rs

1use 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}