use num_traits::{PrimInt, Unsigned};
#[derive(Clone, Debug)]
pub struct PageLevel<PTE>
where
PTE: PrimInt + Unsigned,
{
pub shift_bits: usize,
pub va_bits: usize,
pub present_bit: (PTE, PTE),
pub huge_page_bit: (PTE, PTE),
pub page_table_mask: PTE,
}
impl<PTE> PageLevel<PTE>
where
PTE: PrimInt + Unsigned,
{
pub fn entries(&self) -> usize {
1 << self.va_bits
}
pub fn page_size(&self) -> usize {
1 << self.shift_bits
}
pub fn mask(&self) -> usize {
((1 << self.va_bits) - 1) << self.shift_bits
}
pub fn end(&self, addr: usize) -> usize {
addr | (self.page_size() - 1)
}
pub fn pte_index(&self, addr: usize) -> usize {
(addr >> self.shift_bits) & ((1 << self.va_bits) - 1)
}
pub fn is_present(&self, pte: PTE) -> bool {
(pte & self.present_bit.0) == self.present_bit.1
}
pub fn is_huge_page(&self, pte: PTE) -> bool {
if self.huge_page_bit.0 != PTE::zero() {
let mask = self.present_bit.0 | self.huge_page_bit.0;
let value = self.present_bit.1 | self.huge_page_bit.1;
(pte & mask) == value
} else {
false
}
}
}