1use crate::mm::address::operations::{AlignOps, CalcOps, UsizeConvert};
8use core::mem::size_of;
9use core::ops::Range;
10
11pub trait Address:
16 CalcOps + AlignOps + UsizeConvert + Copy + Clone + PartialEq + PartialOrd + Eq + Ord
17{
18 fn is_null(self) -> bool {
20 self.as_usize() == 0
21 }
22
23 fn null() -> Self {
25 Self::from_usize(0)
26 }
27
28 fn page_offset(self) -> usize {
30 self.as_usize() & (crate::config::PAGE_SIZE - 1)
32 }
33
34 fn addr_diff(self, other: Self) -> isize {
36 self.as_usize() as isize - other.as_usize() as isize
37 }
38
39 fn add<T>(self) -> Self {
44 self.add_by(size_of::<T>())
45 }
46
47 fn add_n<T>(self, n: usize) -> Self {
52 self.add_by(size_of::<T>() * n)
53 }
54
55 fn add_by(self, offset: usize) -> Self {
57 Self::from_usize(self.as_usize() + offset)
58 }
59
60 fn sub(self) -> Self {
62 self.sub_by(size_of::<Self>())
63 }
64
65 fn sub_n(self, n: usize) -> Self {
67 self.sub_by(size_of::<Self>() * n)
68 }
69
70 fn sub_by(self, offset: usize) -> Self {
72 Self::from_usize(self.as_usize() - offset)
73 }
74
75 fn step(&mut self) {
77 self.step_by(size_of::<Self>())
78 }
79
80 fn step_n(&mut self, n: usize) {
82 self.step_by(size_of::<Self>() * n)
83 }
84
85 fn step_back(&mut self) {
87 self.step_back_by(size_of::<Self>())
88 }
89
90 fn step_back_n(&mut self, n: usize) {
92 self.step_back_by(size_of::<Self>() * n)
93 }
94
95 fn step_by(&mut self, offset: usize) {
97 *self = self.add_by(offset);
98 }
99
100 fn step_back_by(&mut self, offset: usize) {
102 *self = self.sub_by(offset);
103 }
104}
105
106#[macro_export]
113macro_rules! impl_address {
114 ($type:ty) => {
115 impl $crate::mm::address::operations::UsizeConvert for $type {
116 fn as_usize(&self) -> usize {
118 unsafe { core::mem::transmute::<Self, usize>(*self) }
120 }
121
122 fn from_usize(value: usize) -> Self {
124 unsafe { core::mem::transmute::<usize, Self>(value) }
126 }
127 }
128
129 $crate::impl_calc_ops!($type);
130 impl $crate::mm::address::operations::AlignOps for $type {}
131
132 impl $crate::mm::address::address::Address for $type {}
133
134 unsafe impl Sync for $type {}
136 unsafe impl Send for $type {}
137 };
138}
139
140pub trait ConvertablePaddr {
144 fn is_valid_paddr(&self) -> bool;
146 fn to_vaddr(&self) -> Vaddr;
148}
149
150#[repr(transparent)]
154#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
155pub struct Paddr(pub *const ());
156impl_address!(Paddr);
157
158impl ConvertablePaddr for Paddr {
159 fn is_valid_paddr(&self) -> bool {
160 self.as_usize() == unsafe { crate::arch::mm::vaddr_to_paddr(self.as_usize()) }
163 }
164
165 fn to_vaddr(&self) -> Vaddr {
166 Vaddr::from_usize(crate::arch::mm::paddr_to_vaddr(self.as_usize()))
168 }
169}
170
171pub trait ConvertableVaddr {
175 fn is_valid_vaddr(&self) -> bool;
177 fn to_paddr(&self) -> Paddr;
179}
180
181#[repr(transparent)]
185#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
186pub struct Vaddr(pub *const ());
187impl_address!(Vaddr);
188
189impl ConvertableVaddr for Vaddr {
190 fn is_valid_vaddr(&self) -> bool {
191 self.as_usize() == crate::arch::mm::paddr_to_vaddr(self.as_usize())
193 }
194
195 fn to_paddr(&self) -> Paddr {
196 Paddr::from_usize(unsafe { crate::arch::mm::vaddr_to_paddr(self.as_usize()) })
198 }
199}
200
201impl Vaddr {
202 pub fn from_ref<T>(r: &T) -> Self {
204 Self::from_ptr(r as *const T)
205 }
206
207 pub fn from_ptr<T>(p: *const T) -> Self {
209 Self::from_usize(p as usize)
210 }
211
212 pub unsafe fn as_ref<T>(&self) -> &T {
220 unsafe { &*(self.as_usize() as *const T) }
221 }
222
223 pub unsafe fn as_mut<T>(&mut self) -> &mut T {
231 unsafe { &mut *(self.as_usize() as *mut T) }
232 }
233
234 pub fn as_ptr<T>(&self) -> *const T {
236 self.as_usize() as *const T
237 }
238
239 pub unsafe fn as_mut_ptr<T>(&mut self) -> *mut T {
244 self.as_usize() as *mut T
245 }
246}
247
248#[repr(C)]
252#[derive(Clone, Copy, Debug, PartialEq, Eq)]
253pub struct AddressRange<T>
254where
255 T: Address,
256{
257 start: T,
259 end: T,
261}
262
263impl<T> AddressRange<T>
264where
265 T: Address,
266{
267 pub fn new(start: T, end: T) -> Self {
269 Self { start, end }
270 }
271
272 pub fn from_range(range: Range<T>) -> Self {
274 Self {
275 start: range.start,
276 end: range.end,
277 }
278 }
279
280 pub fn from_start_len(start: T, len: usize) -> Self {
282 Self {
283 start,
284 end: T::from_usize(start.as_usize() + len),
285 }
286 }
287
288 pub fn from_slices(slices: &[T]) -> Option<Self> {
293 if slices.len() < 2 {
294 return None;
295 }
296 Some(Self {
299 start: slices[0],
300 end: slices[slices.len() - 1],
301 })
302 }
303
304 pub fn start(&self) -> T {
306 self.start
307 }
308
309 pub fn end(&self) -> T {
311 self.end
312 }
313
314 pub fn len(&self) -> usize {
316 debug_assert!(self.end.as_usize() >= self.start.as_usize());
317 self.end.as_usize() - self.start.as_usize()
318 }
319
320 pub fn empty(&self) -> bool {
322 self.start == self.end
323 }
324
325 pub fn contains(&self, addr: T) -> bool {
327 addr >= self.start && addr < self.end
328 }
329
330 pub fn contains_range(&self, other: &Self) -> bool {
332 other.start >= self.start && other.end <= self.end
333 }
334
335 pub fn contains_in(&self, other: &Self) -> bool {
337 self.start >= other.start && self.end <= other.end
338 }
339
340 pub fn intersects(&self, other: &Self) -> bool {
342 self.start < other.end && other.start < self.end
343 }
344
345 pub fn adjacent(&self, other: &Self) -> bool {
347 self.end == other.start || other.end == self.start
348 }
349
350 pub fn intersection(&self, other: &Self) -> Option<Self> {
355 if !self.intersects(other) {
356 return None;
357 }
358 let start = core::cmp::max(self.start, other.start);
359 let end = core::cmp::min(self.end, other.end);
360 Some(Self { start, end })
361 }
362
363 pub fn union(&self, other: &Self) -> Option<Self> {
368 if !self.intersects(other) && !self.adjacent(other) {
369 return None;
370 }
371 let start = core::cmp::min(self.start, other.start);
372 let end = core::cmp::max(self.end, other.end);
373 Some(Self { start, end })
374 }
375
376 pub fn iter(&self) -> AddressRangeIterator<T> {
378 AddressRangeIterator {
379 range: *self,
380 current: self.start,
381 }
382 }
383}
384
385impl<T> IntoIterator for AddressRange<T>
386where
387 T: Address,
388{
389 type Item = T;
390 type IntoIter = AddressRangeIterator<T>;
391
392 fn into_iter(self) -> Self::IntoIter {
393 self.iter()
394 }
395}
396
397pub struct AddressRangeIterator<T>
401where
402 T: Address,
403{
404 range: AddressRange<T>,
405 current: T,
406}
407
408impl<T> Iterator for AddressRangeIterator<T>
409where
410 T: Address,
411{
412 type Item = T;
413
414 fn next(&mut self) -> Option<Self::Item> {
415 if self.current >= self.range.end {
416 return None;
417 }
418 let addr = self.current;
419 self.current.step(); Some(addr)
421 }
422}
423
424pub type PaddrRange = AddressRange<Paddr>;
426
427pub type VaddrRange = AddressRange<Vaddr>;
429
430#[cfg(test)]
431mod address_basic_tests {
432 use super::*;
433 use crate::arch::mm::paddr_to_vaddr;
435 use crate::{kassert, test_case};
436
437 test_case!(test_address_roundtrip, {
439 let test_values = [0x0, 0x1000, 0x8000_0000, 0x8000_1234];
440
441 for &val in &test_values {
442 let paddr = Paddr::from_usize(val);
443 kassert!(paddr.as_usize() == val);
444
445 let vaddr = Vaddr::from_usize(val);
446 kassert!(vaddr.as_usize() == val);
447 }
448 });
449
450 test_case!(test_null_address, {
452 let paddr = Paddr::null();
453 kassert!(paddr.is_null());
454 kassert!(paddr.as_usize() == 0);
455 });
456
457 test_case!(test_page_offset, {
459 let cases = [(0x8000_0000, 0), (0x8000_0123, 0x123), (0x8000_0FFF, 0xFFF)];
460 for &(addr, expected) in &cases {
461 kassert!(Paddr::from_usize(addr).page_offset() == expected);
463 kassert!(Vaddr::from_usize(addr).page_offset() == expected);
464 }
465 });
466
467 test_case!(test_paddr_vaddr_conversion, {
469 let paddrs = [0x8000_0000, 0x8000_1000, 0x8020_0000];
470
471 for &paddr_val in &paddrs {
472 let paddr = Paddr::from_usize(paddr_val);
473 let vaddr = paddr.to_vaddr();
474 let back = vaddr.to_paddr();
475 kassert!(back.as_usize() == paddr_val);
476 kassert!(vaddr.as_usize() == paddr_to_vaddr(paddr_val));
477 }
478 });
479
480 test_case!(test_address_comparison, {
482 let a1 = Paddr::from_usize(0x8000_0000);
483 let a2 = Paddr::from_usize(0x8000_0000);
484 let a3 = Paddr::from_usize(0x8000_1000);
485
486 kassert!(a1 == a2);
487 kassert!(a1 < a3);
488 kassert!(a3 > a1);
489 });
490
491 test_case!(test_address_arithmetic, {
493 let start = Paddr::from_usize(0x1000);
494
495 kassert!(start.add_by(0x123).as_usize() == 0x1123);
497
498 kassert!(start.add::<u32>().as_usize() == 0x1004);
500
501 kassert!(start.add_n::<u16>(3).as_usize() == 0x1006);
503
504 let mut p = start;
506 p.step();
507 kassert!(p.as_usize() == start.as_usize() + size_of::<Paddr>());
508
509 let mut p = Paddr::from_usize(0x2000);
511 p.step_back_by(0x10);
512 kassert!(p.as_usize() == 0x1FF0);
513 });
514}