memory_addresses/arch/
fallback.rs1use crate::impl_address;
4use core::fmt;
5
6use align_address::Align;
7
8#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
10#[repr(transparent)]
11pub struct VirtAddr(usize);
12
13impl_address!(VirtAddr, usize, as_usize);
14
15#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
17#[repr(transparent)]
18pub struct PhysAddr(usize);
19
20impl_address!(PhysAddr, usize, as_usize);
21
22pub struct VirtAddrNotValid(pub usize);
24
25impl core::fmt::Debug for VirtAddrNotValid {
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 f.debug_tuple("VirtAddrNotValid")
28 .field(&format_args!("{:#x}", self.0))
29 .finish()
30 }
31}
32
33impl VirtAddr {
34 #[inline]
36 pub const fn new(addr: usize) -> VirtAddr {
37 Self(addr)
38 }
39
40 #[inline]
42 pub const fn try_new(addr: usize) -> Result<VirtAddr, VirtAddrNotValid> {
43 Ok(Self(addr))
44 }
45
46 #[inline]
48 pub const fn new_truncate(addr: usize) -> VirtAddr {
49 Self(addr)
50 }
51
52 #[inline]
54 pub fn from_ptr<T: ?Sized>(ptr: *const T) -> Self {
55 Self::new(ptr as *const () as usize)
56 }
57
58 #[inline]
60 pub const fn as_ptr<T>(self) -> *const T {
61 self.0 as *const T
62 }
63
64 #[inline]
66 pub const fn as_mut_ptr<T>(self) -> *mut T {
67 self.as_ptr::<T>() as *mut T
68 }
69}
70
71impl Align<usize> for VirtAddr {
72 #[inline]
73 fn align_down(self, align: usize) -> Self {
74 Self::new_truncate(self.0.align_down(align))
75 }
76
77 #[inline]
78 fn checked_align_up(self, align: usize) -> Option<Self> {
79 let addr = self.0.checked_align_up(align)?;
80 Some(Self::new_truncate(addr))
81 }
82}
83
84pub struct PhysAddrNotValid(pub usize);
90
91impl core::fmt::Debug for PhysAddrNotValid {
92 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93 f.debug_tuple("PhysAddrNotValid")
94 .field(&format_args!("{:#x}", self.0))
95 .finish()
96 }
97}
98
99impl PhysAddr {
100 #[inline]
102 pub const fn new(addr: usize) -> Self {
103 Self(addr)
104 }
105
106 #[inline]
108 pub const fn new_truncate(addr: usize) -> PhysAddr {
109 PhysAddr(addr)
110 }
111
112 #[inline]
116 pub const fn try_new(addr: usize) -> Result<Self, PhysAddrNotValid> {
117 Ok(Self(addr))
118 }
119}
120
121impl Align<usize> for PhysAddr {
122 #[inline]
123 fn align_down(self, align: usize) -> Self {
124 Self::new(self.0.align_down(align))
125 }
126
127 #[inline]
128 fn checked_align_up(self, align: usize) -> Option<Self> {
129 let addr = self.0.checked_align_up(align)?;
130 let this = Self::try_new(addr).ok()?;
131 Some(this)
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use super::*;
138 use crate::{AddrRange, MemoryAddress};
139
140 #[test]
141 pub fn virtaddr_new_truncate() {
142 assert_eq!(VirtAddr::new_truncate(0), VirtAddr(0));
143 assert_eq!(VirtAddr::new_truncate(123), VirtAddr(123));
144 }
145
146 #[test]
147 fn test_from_ptr_array() {
148 let slice = &[1, 2, 3, 4, 5];
149 assert_eq!(VirtAddr::from_ptr(slice), VirtAddr::from_ptr(&slice[0]));
151 }
152
153 #[test]
154 fn test_addr_range() {
155 let r = AddrRange::new(VirtAddr::new(0x0), VirtAddr::new(0x3)).unwrap();
156 assert!(r.contains(&VirtAddr::new(0x0)));
157 assert!(r.contains(&VirtAddr::new(0x1)));
158 assert!(!r.contains(&VirtAddr::new(0x3)));
159 let mut i = r.iter();
160 assert_eq!(i.next().unwrap(), VirtAddr::new(0x0));
161 assert_eq!(i.next().unwrap(), VirtAddr::new(0x1));
162 assert_eq!(i.next().unwrap(), VirtAddr::new(0x2));
163 assert!(i.next().is_none());
164
165 for (i, a) in r.iter().enumerate() {
166 assert_eq!(a.raw(), i);
167 }
168
169 let r = AddrRange::new(PhysAddr::new(0x2), PhysAddr::new(0x4)).unwrap();
170 let mut i = r.iter();
171 assert_eq!(i.next().unwrap(), PhysAddr::new(0x2));
172 assert_eq!(i.next().unwrap(), PhysAddr::new(0x3));
173 assert!(i.next().is_none());
174
175 assert_eq!(r.iter().map(|a| a.raw()).sum::<usize>(), 0x5);
176 }
177}