vmi_core/core/
access_context.rs1use serde::{Deserialize, Serialize};
2
3use super::impl_ops;
4use crate::AddressContext;
5
6impl_ops! {
7 pub struct Gfn(pub u64);
9}
10
11impl_ops! {
12 pub struct Pa(pub u64);
14}
15
16impl_ops! {
17 pub struct Va(pub u64);
19}
20
21impl Va {
22 pub fn null() -> Self {
24 Self(0)
25 }
26
27 pub fn is_null(self) -> bool {
29 self.0 == 0
30 }
31}
32
33pub trait VmiVa {
35 fn va(&self) -> Va;
37}
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
45pub enum TranslationMechanism {
46 Direct,
51
52 Paging {
58 root: Option<Pa>,
62 },
63}
64
65#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
72pub struct AccessContext {
73 pub address: u64,
80
81 pub mechanism: TranslationMechanism,
90}
91
92impl AccessContext {
93 pub fn direct(address: impl Into<Pa>) -> Self {
95 Self {
96 address: u64::from(address.into()),
97 mechanism: TranslationMechanism::Direct,
98 }
99 }
100
101 pub fn paging(address: impl Into<Va>, root: impl Into<Pa>) -> Self {
103 Self {
104 address: address.into().0,
105 mechanism: TranslationMechanism::Paging {
106 root: Some(root.into()),
107 },
108 }
109 }
110}
111
112impl From<Pa> for AccessContext {
113 fn from(value: Pa) -> Self {
114 Self::direct(value)
115 }
116}
117
118impl From<(Va, Pa)> for AccessContext {
119 fn from(value: (Va, Pa)) -> Self {
120 Self::paging(value.0, value.1)
121 }
122}
123
124impl From<AddressContext> for AccessContext {
125 fn from(value: AddressContext) -> Self {
126 Self {
127 address: value.va.0,
128 mechanism: TranslationMechanism::Paging {
129 root: Some(value.root),
130 },
131 }
132 }
133}
134
135impl ::std::ops::Add<u64> for AccessContext {
136 type Output = AccessContext;
137
138 fn add(self, rhs: u64) -> Self::Output {
139 Self {
140 address: self.address + rhs,
141 ..self
142 }
143 }
144}
145
146impl ::std::ops::Add<AccessContext> for AccessContext {
147 type Output = AccessContext;
148
149 fn add(self, rhs: AccessContext) -> Self::Output {
150 Self {
151 address: self.address + rhs.address,
152 ..self
153 }
154 }
155}
156
157impl ::std::ops::AddAssign<u64> for AccessContext {
158 fn add_assign(&mut self, rhs: u64) {
159 self.address += rhs;
160 }
161}
162
163impl ::std::ops::AddAssign<AccessContext> for AccessContext {
164 fn add_assign(&mut self, rhs: AccessContext) {
165 self.address += rhs.address;
166 }
167}
168
169impl ::std::ops::Sub<u64> for AccessContext {
170 type Output = AccessContext;
171
172 fn sub(self, rhs: u64) -> Self::Output {
173 Self {
174 address: self.address - rhs,
175 ..self
176 }
177 }
178}
179
180impl ::std::ops::Sub<AccessContext> for AccessContext {
181 type Output = AccessContext;
182
183 fn sub(self, rhs: AccessContext) -> Self::Output {
184 Self {
185 address: self.address - rhs.address,
186 ..self
187 }
188 }
189}
190
191impl ::std::ops::SubAssign<u64> for AccessContext {
192 fn sub_assign(&mut self, rhs: u64) {
193 self.address -= rhs;
194 }
195}
196
197impl ::std::ops::SubAssign<AccessContext> for AccessContext {
198 fn sub_assign(&mut self, rhs: AccessContext) {
199 self.address -= rhs.address;
200 }
201}
202
203impl ::std::ops::Mul<u64> for AccessContext {
204 type Output = AccessContext;
205
206 fn mul(self, rhs: u64) -> Self::Output {
207 Self {
208 address: self.address * rhs,
209 ..self
210 }
211 }
212}
213
214impl ::std::ops::Mul<AccessContext> for AccessContext {
215 type Output = AccessContext;
216
217 fn mul(self, rhs: AccessContext) -> Self::Output {
218 Self {
219 address: self.address * rhs.address,
220 ..self
221 }
222 }
223}
224
225impl ::std::ops::MulAssign<u64> for AccessContext {
226 fn mul_assign(&mut self, rhs: u64) {
227 self.address *= rhs;
228 }
229}
230
231impl ::std::ops::MulAssign<AccessContext> for AccessContext {
232 fn mul_assign(&mut self, rhs: AccessContext) {
233 self.address *= rhs.address;
234 }
235}
236
237impl ::std::ops::Div<u64> for AccessContext {
238 type Output = AccessContext;
239
240 fn div(self, rhs: u64) -> Self::Output {
241 Self {
242 address: self.address / rhs,
243 ..self
244 }
245 }
246}
247
248impl ::std::ops::Div<AccessContext> for AccessContext {
249 type Output = AccessContext;
250
251 fn div(self, rhs: AccessContext) -> Self::Output {
252 Self {
253 address: self.address / rhs.address,
254 ..self
255 }
256 }
257}
258
259impl ::std::ops::DivAssign<u64> for AccessContext {
260 fn div_assign(&mut self, rhs: u64) {
261 self.address /= rhs;
262 }
263}
264
265impl ::std::ops::DivAssign<AccessContext> for AccessContext {
266 fn div_assign(&mut self, rhs: AccessContext) {
267 self.address /= rhs.address;
268 }
269}
270
271impl ::std::ops::BitAnd<u64> for AccessContext {
272 type Output = AccessContext;
273
274 fn bitand(self, rhs: u64) -> Self::Output {
275 Self {
276 address: self.address & rhs,
277 ..self
278 }
279 }
280}
281
282impl ::std::ops::BitAndAssign<u64> for AccessContext {
283 fn bitand_assign(&mut self, rhs: u64) {
284 self.address &= rhs;
285 }
286}
287
288impl ::std::ops::BitOr<u64> for AccessContext {
289 type Output = AccessContext;
290
291 fn bitor(self, rhs: u64) -> Self::Output {
292 Self {
293 address: self.address | rhs,
294 ..self
295 }
296 }
297}
298
299impl ::std::ops::BitOrAssign<u64> for AccessContext {
300 fn bitor_assign(&mut self, rhs: u64) {
301 self.address |= rhs;
302 }
303}