blob: 12bbd8e1c396e103775462801e4893b83a38e410 [file] [log] [blame]
Imre Kisd5b96fd2024-09-11 17:04:32 +02001// SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4use core::ops::Range;
5
6use super::Xlat;
7
8#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
9pub struct PhysicalAddress(pub(super) usize);
10
11impl PhysicalAddress {
12 pub const unsafe fn new(address: usize) -> Self {
13 Self(address)
14 }
15
16 pub const fn add_offset(self, offset: usize) -> Option<Self> {
17 if let Some(address) = self.0.checked_add(offset) {
18 Some(Self(address))
19 } else {
20 None
21 }
22 }
23
24 pub const fn identity_va(self) -> VirtualAddress {
25 VirtualAddress(self.0)
26 }
27
28 pub const fn diff(self, rhs: Self) -> Option<usize> {
29 self.0.checked_sub(rhs.0)
30 }
31}
32
33impl From<PhysicalAddress> for usize {
34 fn from(value: PhysicalAddress) -> Self {
35 value.0
36 }
37}
38
39impl From<PhysicalAddress> for u64 {
40 fn from(value: PhysicalAddress) -> Self {
41 value.0 as u64
42 }
43}
44
45#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
46pub struct VirtualAddress(pub(super) usize);
47
48impl VirtualAddress {
49 pub const unsafe fn new(address: usize) -> Self {
50 Self(address)
51 }
52
53 pub const fn add_offset(self, offset: usize) -> Option<Self> {
54 if let Some(address) = self.0.checked_add(offset) {
55 Some(Self(address))
56 } else {
57 None
58 }
59 }
60
61 pub const fn identity_pa(self) -> PhysicalAddress {
62 PhysicalAddress(self.0)
63 }
64
65 pub const fn mask_for_level(self, level: usize) -> Self {
66 Self(self.0 & (Xlat::GRANULE_SIZES[level] - 1))
67 }
68
69 pub const fn get_level_index(self, level: usize) -> usize {
70 self.0 / Xlat::GRANULE_SIZES[level]
71 }
72
73 pub const fn mask_bits(self, mask: usize) -> Self {
74 Self(self.0 & mask)
75 }
76
77 pub const fn diff(self, rhs: Self) -> Option<usize> {
78 self.0.checked_sub(rhs.0)
79 }
80}
81
82impl From<VirtualAddress> for usize {
83 fn from(value: VirtualAddress) -> Self {
84 value.0
85 }
86}
87
88impl From<VirtualAddress> for u64 {
89 fn from(value: VirtualAddress) -> Self {
90 value.0 as u64
91 }
92}
93
94pub struct VirtualAddressRange {
95 pub(super) start: VirtualAddress,
96 pub(super) end: VirtualAddress,
97}
98
99impl VirtualAddressRange {
100 pub fn new(start: VirtualAddress, end: VirtualAddress) -> Self {
101 Self { start, end }
102 }
103
104 pub unsafe fn from_range(value: Range<usize>) -> Self {
105 Self::new(
106 VirtualAddress::new(value.start),
107 VirtualAddress::new(value.end),
108 )
109 }
110
111 pub fn len(&self) -> Option<usize> {
112 self.end.diff(self.start)
113 }
114
115 pub fn step_by(self, step: usize) -> VirtualAddressIterator {
116 VirtualAddressIterator {
117 next: self.start,
118 end: self.end,
119 step,
120 }
121 }
122}
123
124pub struct VirtualAddressIterator {
125 next: VirtualAddress,
126 end: VirtualAddress,
127 step: usize,
128}
129
130impl Iterator for VirtualAddressIterator {
131 type Item = VirtualAddress;
132
133 fn next(&mut self) -> Option<Self::Item> {
134 if self.next < self.end {
135 let current = self.next;
136
137 self.next = if let Some(next) = self.next.add_offset(self.step) {
138 next
139 } else {
140 self.end
141 };
142
143 Some(current)
144 } else {
145 None
146 }
147 }
148}