use ax_memory_addr::{PhysAddr, VirtAddr};
use axvm_types::{GuestPhysAddr, MappingFlags};
use crate::AddrSpaceResult;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(usize)]
pub enum PageSize {
Size4K = 0x1000,
Size1M = 0x10_0000,
Size2M = 0x20_0000,
Size1G = 0x4000_0000,
}
impl PageSize {
pub const fn is_huge(self) -> bool {
!matches!(self, Self::Size4K)
}
}
impl From<PageSize> for usize {
fn from(size: PageSize) -> usize {
size as usize
}
}
pub trait NestedPageTableOps {
fn root_paddr(&self) -> PhysAddr;
fn levels(&self) -> usize;
fn alloc_frame(&self) -> Option<PhysAddr>;
fn dealloc_frame(&self, paddr: PhysAddr);
fn phys_to_virt(&self, paddr: PhysAddr) -> VirtAddr;
fn map(
&mut self,
vaddr: GuestPhysAddr,
paddr: PhysAddr,
size: PageSize,
flags: MappingFlags,
) -> AddrSpaceResult;
fn unmap(
&mut self,
vaddr: GuestPhysAddr,
) -> AddrSpaceResult<(PhysAddr, MappingFlags, PageSize)>;
fn map_region(
&mut self,
vaddr: GuestPhysAddr,
get_paddr: impl Fn(GuestPhysAddr) -> PhysAddr,
size: usize,
flags: MappingFlags,
allow_huge: bool,
) -> AddrSpaceResult;
fn unmap_region(&mut self, start: GuestPhysAddr, size: usize) -> AddrSpaceResult;
fn remap(&mut self, start: GuestPhysAddr, paddr: PhysAddr, flags: MappingFlags) -> bool;
fn protect_region(
&mut self,
start: GuestPhysAddr,
size: usize,
new_flags: MappingFlags,
) -> bool;
fn query(&self, vaddr: GuestPhysAddr) -> AddrSpaceResult<(PhysAddr, MappingFlags, PageSize)>;
fn translate(&self, vaddr: GuestPhysAddr) -> Option<PhysAddr> {
self.query(vaddr).ok().map(|(paddr, ..)| paddr)
}
}