vmi_core/core/
access_context.rsuse serde::{Deserialize, Serialize};
use super::macros::impl_ops;
use crate::AddressContext;
impl_ops!(Gfn, u64, "Guest Frame Number");
impl_ops!(Pa, u64, "Guest Physical Address");
impl_ops!(Va, u64, "Guest Virtual Address");
impl Va {
pub fn is_null(self) -> bool {
self.0 == 0
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub enum TranslationMechanism {
Direct,
Paging {
root: Option<Pa>,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct AccessContext {
pub address: u64,
pub mechanism: TranslationMechanism,
}
impl AccessContext {
pub fn direct(address: impl Into<Pa>) -> Self {
Self {
address: u64::from(address.into()),
mechanism: TranslationMechanism::Direct,
}
}
pub fn paging(address: impl Into<Va>, root: impl Into<Pa>) -> Self {
Self {
address: address.into().0,
mechanism: TranslationMechanism::Paging {
root: Some(root.into()),
},
}
}
}
impl From<Pa> for AccessContext {
fn from(value: Pa) -> Self {
Self::direct(value)
}
}
impl From<(Va, Pa)> for AccessContext {
fn from(value: (Va, Pa)) -> Self {
Self::paging(value.0, value.1)
}
}
impl From<AddressContext> for AccessContext {
fn from(value: AddressContext) -> Self {
Self::paging(value.va, value.root)
}
}
impl ::std::ops::Add<u64> for AccessContext {
type Output = AccessContext;
fn add(self, rhs: u64) -> Self::Output {
Self {
address: self.address + rhs,
..self
}
}
}
impl ::std::ops::Add<AccessContext> for AccessContext {
type Output = AccessContext;
fn add(self, rhs: AccessContext) -> Self::Output {
Self {
address: self.address + rhs.address,
..self
}
}
}
impl ::std::ops::AddAssign<u64> for AccessContext {
fn add_assign(&mut self, rhs: u64) {
self.address += rhs;
}
}
impl ::std::ops::AddAssign<AccessContext> for AccessContext {
fn add_assign(&mut self, rhs: AccessContext) {
self.address += rhs.address;
}
}
impl ::std::ops::Sub<u64> for AccessContext {
type Output = AccessContext;
fn sub(self, rhs: u64) -> Self::Output {
Self {
address: self.address - rhs,
..self
}
}
}
impl ::std::ops::Sub<AccessContext> for AccessContext {
type Output = AccessContext;
fn sub(self, rhs: AccessContext) -> Self::Output {
Self {
address: self.address - rhs.address,
..self
}
}
}
impl ::std::ops::SubAssign<u64> for AccessContext {
fn sub_assign(&mut self, rhs: u64) {
self.address -= rhs;
}
}
impl ::std::ops::SubAssign<AccessContext> for AccessContext {
fn sub_assign(&mut self, rhs: AccessContext) {
self.address -= rhs.address;
}
}
impl ::std::ops::Mul<u64> for AccessContext {
type Output = AccessContext;
fn mul(self, rhs: u64) -> Self::Output {
Self {
address: self.address * rhs,
..self
}
}
}
impl ::std::ops::Mul<AccessContext> for AccessContext {
type Output = AccessContext;
fn mul(self, rhs: AccessContext) -> Self::Output {
Self {
address: self.address * rhs.address,
..self
}
}
}
impl ::std::ops::MulAssign<u64> for AccessContext {
fn mul_assign(&mut self, rhs: u64) {
self.address *= rhs;
}
}
impl ::std::ops::MulAssign<AccessContext> for AccessContext {
fn mul_assign(&mut self, rhs: AccessContext) {
self.address *= rhs.address;
}
}
impl ::std::ops::Div<u64> for AccessContext {
type Output = AccessContext;
fn div(self, rhs: u64) -> Self::Output {
Self {
address: self.address / rhs,
..self
}
}
}
impl ::std::ops::Div<AccessContext> for AccessContext {
type Output = AccessContext;
fn div(self, rhs: AccessContext) -> Self::Output {
Self {
address: self.address / rhs.address,
..self
}
}
}
impl ::std::ops::DivAssign<u64> for AccessContext {
fn div_assign(&mut self, rhs: u64) {
self.address /= rhs;
}
}
impl ::std::ops::DivAssign<AccessContext> for AccessContext {
fn div_assign(&mut self, rhs: AccessContext) {
self.address /= rhs.address;
}
}
impl ::std::ops::BitAnd<u64> for AccessContext {
type Output = AccessContext;
fn bitand(self, rhs: u64) -> Self::Output {
Self {
address: self.address & rhs,
..self
}
}
}
impl ::std::ops::BitAndAssign<u64> for AccessContext {
fn bitand_assign(&mut self, rhs: u64) {
self.address &= rhs;
}
}
impl ::std::ops::BitOr<u64> for AccessContext {
type Output = AccessContext;
fn bitor(self, rhs: u64) -> Self::Output {
Self {
address: self.address | rhs,
..self
}
}
}
impl ::std::ops::BitOrAssign<u64> for AccessContext {
fn bitor_assign(&mut self, rhs: u64) {
self.address |= rhs;
}
}