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);
14
15#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
17#[repr(transparent)]
18pub struct PhysAddr(usize);
19
20impl_address!(PhysAddr, 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 align_up(self, align: usize) -> Self {
79 Self::new_truncate(self.0.align_up(align))
80 }
81}
82
83pub struct PhysAddrNotValid(pub usize);
89
90impl core::fmt::Debug for PhysAddrNotValid {
91 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92 f.debug_tuple("PhysAddrNotValid")
93 .field(&format_args!("{:#x}", self.0))
94 .finish()
95 }
96}
97
98impl PhysAddr {
99 #[inline]
101 pub const fn new(addr: usize) -> Self {
102 Self(addr)
103 }
104
105 #[inline]
107 pub const fn new_truncate(addr: usize) -> PhysAddr {
108 PhysAddr(addr)
109 }
110
111 #[inline]
115 pub const fn try_new(addr: usize) -> Result<Self, PhysAddrNotValid> {
116 Ok(Self(addr))
117 }
118}
119
120impl Align<usize> for PhysAddr {
121 #[inline]
122 fn align_down(self, align: usize) -> Self {
123 Self::new(self.0.align_down(align))
124 }
125
126 #[inline]
127 fn align_up(self, align: usize) -> Self {
128 Self::new(self.0.align_up(align))
129 }
130}
131
132#[cfg(test)]
133mod tests {
134 use super::*;
135 use crate::{AddrRange, MemoryAddress};
136
137 #[test]
138 pub fn virtaddr_new_truncate() {
139 assert_eq!(VirtAddr::new_truncate(0), VirtAddr(0));
140 assert_eq!(VirtAddr::new_truncate(123), VirtAddr(123));
141 }
142
143 #[test]
144 fn test_from_ptr_array() {
145 let slice = &[1, 2, 3, 4, 5];
146 assert_eq!(VirtAddr::from_ptr(slice), VirtAddr::from_ptr(&slice[0]));
148 }
149
150 #[test]
151 fn test_addr_range() {
152 let r = AddrRange::new(VirtAddr::new(0x0), VirtAddr::new(0x3)).unwrap();
153 assert!(r.contains(&VirtAddr::new(0x0)));
154 assert!(r.contains(&VirtAddr::new(0x1)));
155 assert!(!r.contains(&VirtAddr::new(0x3)));
156 let mut i = r.iter();
157 assert_eq!(i.next().unwrap(), VirtAddr::new(0x0));
158 assert_eq!(i.next().unwrap(), VirtAddr::new(0x1));
159 assert_eq!(i.next().unwrap(), VirtAddr::new(0x2));
160 assert!(i.next().is_none());
161
162 for (i, a) in r.iter().enumerate() {
163 assert_eq!(a.raw(), i);
164 }
165
166 let r = AddrRange::new(PhysAddr::new(0x2), PhysAddr::new(0x4)).unwrap();
167 let mut i = r.iter();
168 assert_eq!(i.next().unwrap(), PhysAddr::new(0x2));
169 assert_eq!(i.next().unwrap(), PhysAddr::new(0x3));
170 assert!(i.next().is_none());
171
172 assert_eq!(r.iter().map(|a| a.raw()).sum::<usize>(), 0x5);
173 }
174}