kernel/lib/addr/
virt_addr.rs1use crate::lib::addr::PhysAddr;
7use core::fmt::{Debug, Display, LowerHex, Pointer, UpperHex};
8use core::ops::{Add, AddAssign, Sub, SubAssign};
9use crate::state::kstate::KSTATE;
10
11#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
13#[repr(transparent)]
14pub struct VirtAddr(u64);
15
16impl VirtAddr {
17 pub const fn new(addr: u64) -> Self {
19 Self(addr)
20 }
21
22 pub const fn null() -> Self {
24 Self(0)
25 }
26
27 pub fn from_ptr<T>(ptr: *const T) -> Self {
29 Self(ptr as u64)
30 }
31
32 pub fn from_phys(phys: PhysAddr) -> Self {
34 Self(phys.as_u64() + KSTATE.mm.hhdm_offset())
35 }
36
37 pub fn as_u64(self) -> u64 {
39 self.0
40 }
41
42 pub fn as_usize(self) -> usize {
44 self.0 as usize
45 }
46
47 pub fn as_ptr<T>(self) -> *const T {
49 self.0 as *const T
50 }
51
52 pub fn as_mut_ptr<T>(self) -> *mut T {
54 self.0 as *mut T
55 }
56
57 pub fn align_up(self, align: u64) -> Self {
62 debug_assert!(align.is_power_of_two());
63 Self((self.0 + (align - 1)) & !(align - 1))
64 }
65
66 pub fn align_down(self, align: u64) -> Self {
71 debug_assert!(align.is_power_of_two());
72 Self(self.0 & !(align - 1))
73 }
74
75 pub fn is_aligned(self, align: u64) -> bool {
77 self.0 & (align - 1) == 0
78 }
79}
80
81#[cfg(target_arch = "x86_64")]
82impl VirtAddr {
83 pub fn as_x86_64(self) -> x86_64::VirtAddr {
85 x86_64::VirtAddr::new(self.0)
86 }
87
88 pub fn p1_index(self) -> x86_64::structures::paging::PageTableIndex {
90 x86_64::structures::paging::PageTableIndex::new(((self.0 >> 12) & 0x01FF) as u16)
91 }
92
93 pub fn p2_index(self) -> x86_64::structures::paging::PageTableIndex {
95 x86_64::structures::paging::PageTableIndex::new(((self.0 >> 21) & 0x01FF) as u16)
96 }
97
98 pub fn p3_index(self) -> x86_64::structures::paging::PageTableIndex {
100 x86_64::structures::paging::PageTableIndex::new(((self.0 >> 30) & 0x01FF) as u16)
101 }
102
103 pub fn p4_index(self) -> x86_64::structures::paging::PageTableIndex {
105 x86_64::structures::paging::PageTableIndex::new(((self.0 >> 39) & 0x01FF) as u16)
106 }
107}
108
109impl Add<u64> for VirtAddr {
110 type Output = Self;
111
112 fn add(self, rhs: u64) -> Self::Output {
114 VirtAddr::new(self.0 + rhs)
115 }
116}
117impl Add<VirtAddr> for VirtAddr {
118 type Output = Self;
119
120 fn add(self, rhs: VirtAddr) -> Self::Output {
122 VirtAddr::new(self.0 + rhs.0)
123 }
124}
125impl AddAssign<u64> for VirtAddr {
126 fn add_assign(&mut self, rhs: u64) {
128 self.0 += rhs
129 }
130}
131impl AddAssign<VirtAddr> for VirtAddr {
132 fn add_assign(&mut self, rhs: VirtAddr) {
134 self.0 += rhs.0
135 }
136}
137
138impl Sub<u64> for VirtAddr {
139 type Output = Self;
140
141 fn sub(self, rhs: u64) -> Self::Output {
143 VirtAddr::new(self.0 - rhs)
144 }
145}
146impl Sub<VirtAddr> for VirtAddr {
147 type Output = Self;
148
149 fn sub(self, rhs: VirtAddr) -> Self::Output {
151 VirtAddr::new(self.0 - rhs.0)
152 }
153}
154impl SubAssign<u64> for VirtAddr {
155 fn sub_assign(&mut self, rhs: u64) {
157 self.0 -= rhs
158 }
159}
160impl SubAssign<VirtAddr> for VirtAddr {
161 fn sub_assign(&mut self, rhs: VirtAddr) {
163 self.0 -= rhs.0
164 }
165}
166
167impl Display for VirtAddr {
168 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
170 write!(f, "{:#x}", self.0)
171 }
172}
173impl Debug for VirtAddr {
174 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
176 write!(f, "VirtAddr({:#x})", self.0)
177 }
178}
179impl LowerHex for VirtAddr {
180 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
182 LowerHex::fmt(&self.0, f)
183 }
184}
185impl UpperHex for VirtAddr {
186 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
188 UpperHex::fmt(&self.0, f)
189 }
190}
191impl Pointer for VirtAddr {
192 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
194 Pointer::fmt(&(self.0 as *const ()), f)
195 }
196}