use std::error;
use std::fmt;
pub use hv_sys as sys;
pub use vcpu::Vcpu;
pub use vm::Vm;
mod vcpu;
pub mod vm;
#[cfg(target_arch = "aarch64")]
pub mod arm64;
#[cfg(target_arch = "x86_64")]
pub mod x86;
pub type Size = u64;
pub type Addr = *const u8;
pub type GPAddr = u64;
bitflags::bitflags! {
pub struct Memory: u32 {
const READ = sys::HV_MEMORY_READ;
const WRITE = sys::HV_MEMORY_WRITE;
const EXEC = sys::HV_MEMORY_EXEC;
}
}
#[macro_export]
macro_rules! call {
($f:expr) => {{
let code = unsafe { $f };
match code {
0 => Ok(()),
_ => Err(Error::from(code)),
}
}};
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Error {
Unsuccessful,
Busy,
BadArgument,
NoResources,
NoDevice,
Unsupported,
Unknown(sys::hv_return_t),
}
impl error::Error for Error {}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::Unsuccessful => write!(f, "The operation was unsuccessful"),
Error::Busy => write!(f, "The operation was unsuccessful because the owning resource was busy"),
Error::BadArgument => write!(f, "The operation was unsuccessful because the function call had an invalid argument"),
Error::NoResources => write!(f, "The operation was unsuccessful because the host had no resources available to complete the request"),
Error::NoDevice => write!(f, "The operation was unsuccessful because no VM or vCPU was available"),
Error::Unsupported => write!(f, "The operation requested isn’t supported by the hypervisor"),
Error::Unknown(code) => write!(f, "Error code: {}", *code as i32),
}
}
}
impl From<sys::hv_return_t> for Error {
fn from(value: sys::hv_return_t) -> Self {
let v = value as i64;
match v {
0xfae94001 => Error::Unsuccessful,
0xfae94002 => Error::Busy,
0xfae94003 => Error::BadArgument,
0xfae94005 => Error::NoResources,
0xfae94006 => Error::NoDevice,
0xfae9400f => Error::Unsupported,
_ => Error::Unknown(value),
}
}
}