use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct GuestAddress(pub u64);
impl GuestAddress {
#[must_use]
pub const fn new(addr: u64) -> Self {
Self(addr)
}
#[must_use]
pub const fn raw(&self) -> u64 {
self.0
}
#[must_use]
pub const fn offset(&self, offset: u64) -> Self {
Self(self.0 + offset)
}
#[must_use]
pub const fn align_up(&self, alignment: u64) -> Self {
let mask = alignment - 1;
Self((self.0 + mask) & !mask)
}
#[must_use]
pub const fn align_down(&self, alignment: u64) -> Self {
let mask = alignment - 1;
Self(self.0 & !mask)
}
#[must_use]
pub const fn is_aligned(&self, alignment: u64) -> bool {
self.0 & (alignment - 1) == 0
}
}
impl fmt::Display for GuestAddress {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:#x}", self.0)
}
}
impl From<u64> for GuestAddress {
fn from(addr: u64) -> Self {
Self(addr)
}
}
impl From<GuestAddress> for u64 {
fn from(addr: GuestAddress) -> Self {
addr.0
}
}
#[derive(Debug, Clone)]
pub struct MemoryRegion {
pub guest_addr: GuestAddress,
pub size: u64,
pub host_addr: Option<*mut u8>,
pub read_only: bool,
}
impl MemoryRegion {
#[must_use]
pub const fn new(guest_addr: GuestAddress, size: u64) -> Self {
Self {
guest_addr,
size,
host_addr: None,
read_only: false,
}
}
#[must_use]
pub const fn end(&self) -> GuestAddress {
GuestAddress(self.guest_addr.0 + self.size)
}
#[must_use]
pub const fn contains(&self, addr: GuestAddress) -> bool {
addr.0 >= self.guest_addr.0 && addr.0 < self.guest_addr.0 + self.size
}
#[must_use]
pub const fn contains_range(&self, addr: GuestAddress, size: u64) -> bool {
addr.0 >= self.guest_addr.0 && addr.0 + size <= self.guest_addr.0 + self.size
}
}
unsafe impl Send for MemoryRegion {}
unsafe impl Sync for MemoryRegion {}
pub const PAGE_SIZE: u64 = 4096;
pub const LARGE_PAGE_SIZE: u64 = 2 * 1024 * 1024;
pub const HUGE_PAGE_SIZE: u64 = 1024 * 1024 * 1024;