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