sparreal_kernel/mem/
addr.rs

1use core::fmt::{Debug, Display};
2use core::marker::PhantomData;
3use core::ops::{Add, Deref, Range, Sub};
4use core::ptr::NonNull;
5
6#[derive(Debug, Clone, Copy)]
7pub struct Address {
8    pub cpu: usize,
9    pub virt: Option<usize>,
10    pub bus: Option<u64>,
11}
12
13impl Address {
14    pub fn new(cpu: usize, virt: Option<*mut u8>, bus: Option<u64>) -> Self {
15        Self {
16            cpu,
17            virt: virt.map(|s| s as usize),
18            bus,
19        }
20    }
21
22    pub fn as_ptr(&self) -> *const u8 {
23        match self.virt {
24            Some(virt) => virt as *const u8,
25            None => self.cpu as *const u8,
26        }
27    }
28
29    pub fn bus(&self) -> u64 {
30        match self.bus {
31            Some(bus) => bus,
32            None => self.cpu as _,
33        }
34    }
35
36    pub fn physical(&self) -> usize {
37        self.cpu
38    }
39}
40
41impl Add<usize> for Address {
42    type Output = Self;
43
44    fn add(self, rhs: usize) -> Self::Output {
45        Self {
46            cpu: self.cpu + rhs,
47            virt: self.virt.map(|s| s + rhs),
48            bus: self.bus.map(|s| s + rhs as u64),
49        }
50    }
51}
52
53impl Sub<usize> for Address {
54    type Output = Self;
55
56    fn sub(self, rhs: usize) -> Self::Output {
57        Self {
58            cpu: self.cpu - rhs,
59            virt: self.virt.map(|s| s - rhs),
60            bus: self.bus.map(|s| s - rhs as u64),
61        }
62    }
63}
64
65macro_rules! def_addr {
66    ($name:ident, $t:ty) => {
67        #[repr(transparent)]
68        #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord)]
69        pub struct $name<T>($t, core::marker::PhantomData<T>);
70
71        impl<T> $name<T> {
72            pub const fn new(val: $t) -> Self {
73                Self(val, core::marker::PhantomData)
74            }
75
76            pub fn raw(self) -> $t {
77                self.0
78            }
79
80            pub fn align_down(self, align: usize) -> Self {
81                (align_down(self.0 as _, align) as $t).into()
82            }
83
84            pub fn align_up(self, align: usize) -> Self {
85                (align_up(self.0 as _, align) as $t).into()
86            }
87
88            pub fn align_offset(self, align: usize) -> usize {
89                align_offset(self.0 as _, align)
90            }
91
92            pub fn is_aligned_4k(self) -> bool {
93                self.is_aligned_to(0x1000)
94            }
95
96            pub fn is_aligned_to(self, align: usize) -> bool {
97                self.align_offset(align) == 0
98            }
99        }
100        impl<T> core::fmt::Debug for $name<T> {
101            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
102                write!(f, "{:#x}", self.0)
103            }
104        }
105        impl<T> core::fmt::Display for $name<T> {
106            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
107                write!(f, "{:#x}", self.0)
108            }
109        }
110        impl<T> From<$t> for $name<T> {
111            fn from(value: $t) -> Self {
112                Self(value, core::marker::PhantomData)
113            }
114        }
115        impl<T> From<$name<T>> for $t {
116            fn from(value: $name<T>) -> Self {
117                value.0
118            }
119        }
120
121        impl<T> core::ops::Add<usize> for $name<T> {
122            type Output = Self;
123
124            fn add(self, rhs: usize) -> Self::Output {
125                Self(self.0 as usize + rhs, core::marker::PhantomData)
126            }
127        }
128
129        impl<T> core::ops::Sub<usize> for $name<T> {
130            type Output = Self;
131
132            fn sub(self, rhs: usize) -> Self::Output {
133                Self(self.0 as usize - rhs, core::marker::PhantomData)
134            }
135        }
136
137        impl<T> core::ops::Sub<Self> for $name<T> {
138            type Output = usize;
139
140            fn sub(self, rhs: Self) -> Self::Output {
141                self.0 as usize - rhs.0 as usize
142            }
143        }
144    };
145}
146
147#[repr(C)]
148#[derive(Clone, Copy)]
149pub struct CRange<T: Debug + Sized + Clone + Copy> {
150    pub start: T,
151    pub end: T,
152}
153
154impl<T: Debug + Sized + Clone + Copy> CRange<T> {
155    pub fn to_range(&self) -> Range<T> {
156        self.start..self.end
157    }
158}
159
160impl<T: Debug + Sized + Clone + Copy> From<Range<T>> for CRange<T> {
161    fn from(value: Range<T>) -> Self {
162        Self {
163            start: value.start,
164            end: value.end,
165        }
166    }
167}
168
169impl<T: Debug + Sized + Clone + Copy> Debug for CRange<T> {
170    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
171        write!(f, "[{:?}, {:?})", self.start, self.end)
172    }
173}
174
175def_addr!(Virt, usize);
176def_addr!(Phys, usize);
177
178pub type VirtAddr = Virt<u8>;
179pub type PhysAddr = Phys<u8>;
180pub type VirtCRange = CRange<VirtAddr>;
181pub type PhysCRange = CRange<PhysAddr>;
182
183/// 运行地址
184pub struct RunAddr(usize);
185
186pub const fn align_offset(addr: usize, align: usize) -> usize {
187    addr & (align - 1)
188}
189
190pub const fn align_down(addr: usize, align: usize) -> usize {
191    addr & !(align - 1)
192}
193
194pub const fn align_up(addr: usize, align: usize) -> usize {
195    (addr + align - 1) & !(align - 1)
196}
197
198impl<T> From<Virt<T>> for *const T {
199    fn from(value: Virt<T>) -> Self {
200        value.0 as _
201    }
202}
203
204impl<T> From<Virt<T>> for *mut T {
205    fn from(value: Virt<T>) -> *mut T {
206        value.0 as _
207    }
208}
209
210impl<T> From<NonNull<T>> for Virt<T> {
211    fn from(value: NonNull<T>) -> Self {
212        Self(value.as_ptr() as _, core::marker::PhantomData)
213    }
214}
215
216#[macro_export]
217macro_rules! pa {
218    (val: $val:expr) => {
219        Phys::new($val as _)
220    };
221}
222
223#[macro_export]
224macro_rules! va {
225    (val: $val:expr) => {
226        Virt::new($val as _)
227    };
228}