use core::ops::Range;
use num_traits::{PrimInt, Unsigned};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum PteType {
Page(usize),
PageTable(usize),
}
impl PteType {
pub fn is_page(&self) -> bool {
match self {
PteType::Page(_) => true,
_ => false,
}
}
pub fn is_page_table(&self) -> bool {
match self {
PteType::PageTable(_) => true,
_ => false,
}
}
pub fn level(&self) -> usize {
match self {
Self::Page(level) => *level,
Self::PageTable(level) => *level,
}
}
pub fn is_huge_page(&self) -> bool {
match self {
Self::Page(level) if *level != 0 => true,
_ => false,
}
}
}
pub trait PageWalker<PTE, Error>
where
PTE: PrimInt + Unsigned,
{
fn read_pte(&self, phys_addr: PTE) -> Result<PTE, Error>;
fn handle_pte(
&mut self,
_page_type: PteType,
_range: Range<usize>,
_pte: &PTE,
) -> Result<(), Error> {
Ok(())
}
fn handle_pte_hole(
&mut self,
_level: usize,
_range: Range<usize>,
_pte: &PTE,
) -> Result<(), Error> {
Ok(())
}
fn handle_post_pte(
&mut self,
_level: usize,
_range: Range<usize>,
_pte: &PTE,
) -> Result<(), Error> {
Ok(())
}
}
pub trait PageWalkerMut<PTE, Error>
where
PTE: PrimInt + Unsigned,
{
fn read_pte(&self, phys_addr: PTE) -> Result<PTE, Error>;
fn write_pte(&mut self, phys_addr: PTE, value: PTE) -> Result<(), Error>;
fn handle_pte(
&mut self,
_page_type: PteType,
_range: Range<usize>,
_pte: &mut PTE,
) -> Result<(), Error> {
Ok(())
}
fn handle_pte_hole(
&mut self,
_level: usize,
_range: Range<usize>,
_pte: &mut PTE,
) -> Result<(), Error> {
Ok(())
}
fn handle_post_pte(
&mut self,
_level: usize,
_range: Range<usize>,
_pte: &mut PTE,
) -> Result<(), Error> {
Ok(())
}
}