hal_api/
mem.rs

1use core::{
2    fmt::{Display, LowerHex, UpperHex},
3    ops::{Add, Div, Rem, Sub},
4    ptr::NonNull,
5};
6
7#[repr(transparent)]
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
9pub struct PhysAddr(usize);
10
11impl PhysAddr {
12    pub const MAX: Self = Self(usize::MAX);
13
14    #[inline]
15    pub fn new(addr: usize) -> Self {
16        Self(addr)
17    }
18
19    #[inline]
20    pub fn as_usize(&self) -> usize {
21        self.0
22    }
23
24    pub fn as_mut_ptr<T>(&self) -> *mut T {
25        self.0 as *mut T
26    }
27
28    pub fn checked_add(&self, other: usize) -> Option<Self> {
29        self.0.checked_add(other).map(Self)
30    }
31
32    pub fn checked_sub(&self, other: usize) -> Option<Self> {
33        self.0.checked_sub(other).map(Self)
34    }
35
36    pub fn is_multiple_of(&self, align: usize) -> bool {
37        self.0.is_multiple_of(align)
38    }
39
40    pub fn diff(&self, other: Self) -> usize {
41        if self.0 >= other.0 {
42            // Cannot underflow because of the check above.
43            self.0.checked_sub(other.0).unwrap()
44        } else {
45            // Cannot underflow because of the check above.
46            other.0.checked_sub(self.0).unwrap()
47        }
48    }
49}
50
51impl<T> From<NonNull<T>> for PhysAddr {
52    #[inline]
53    fn from(ptr: NonNull<T>) -> Self {
54        Self(ptr.as_ptr() as usize)
55    }
56}
57
58impl Display for PhysAddr {
59    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
60        write!(f, "0x{:x}", self.0)
61    }
62}
63
64impl Add<usize> for PhysAddr {
65    type Output = Self;
66
67    #[inline]
68    fn add(self, rhs: usize) -> Self::Output {
69        Self(self.0 + rhs)
70    }
71}
72
73impl Sub<usize> for PhysAddr {
74    type Output = Self;
75
76    #[inline]
77    fn sub(self, rhs: usize) -> Self::Output {
78        Self(self.0 - rhs)
79    }
80}
81
82impl Div<usize> for PhysAddr {
83    type Output = Self;
84
85    #[inline]
86    fn div(self, rhs: usize) -> Self::Output {
87        Self(self.0 / rhs)
88    }
89}
90
91impl Rem<usize> for PhysAddr {
92    type Output = Self;
93
94    #[inline]
95    fn rem(self, rhs: usize) -> Self::Output {
96        Self(self.0 % rhs)
97    }
98}
99
100impl From<PhysAddr> for usize {
101    #[inline]
102    fn from(addr: PhysAddr) -> Self {
103        addr.0
104    }
105}
106
107impl LowerHex for PhysAddr {
108    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
109        write!(f, "{:x}", self.0)
110    }
111}
112
113impl UpperHex for PhysAddr {
114    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
115        write!(f, "{:X}", self.0)
116    }
117}
118
119#[repr(transparent)]
120#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
121pub struct VirtAddr(usize);
122
123impl VirtAddr {
124    #[inline]
125    pub fn new(addr: usize) -> Self {
126        Self(addr)
127    }
128
129    #[inline]
130    pub fn as_usize(&self) -> usize {
131        self.0
132    }
133
134    #[inline]
135    pub fn saturating_add(&self, other: usize) -> Self {
136        Self(self.0.saturating_add(other))
137    }
138
139    #[inline]
140    pub fn saturating_sub(&self, other: usize) -> Self {
141        Self(self.0.saturating_sub(other))
142    }
143}
144
145impl From<VirtAddr> for usize {
146    #[inline]
147    fn from(addr: VirtAddr) -> Self {
148        addr.0
149    }
150}