use super::{PAGE_SHIFT, PTRS_PER_TABLE, PageLevel, PageProt};
const PA_BITS: usize = 56;
pub const PTE_V: usize = 1 << 0;
pub const PTE_R: usize = 1 << 1;
pub const PTE_W: usize = 1 << 2;
pub const PTE_X: usize = 1 << 3;
pub const PTE_U: usize = 1 << 4;
pub const PTE_G: usize = 1 << 5;
pub const PTE_A: usize = 1 << 6;
pub const PTE_D: usize = 1 << 7;
pub const SWAPPER_MM_NORMALFLAGS: usize = PTE_V | PTE_R | PTE_W | PTE_X | PTE_G | PTE_A | PTE_D;
pub const SWAPPER_MM_NORMAL_PXN_FLAGS: usize = PTE_V | PTE_R | PTE_W | PTE_G | PTE_A | PTE_D;
pub const SWAPPER_MM_IOFLAGS: usize = PTE_V | PTE_R | PTE_W | PTE_G | PTE_A | PTE_D;
pub const PTRS_PER_PGD: usize = PTRS_PER_TABLE;
pub const PTRS_PER_PMD: usize = PTRS_PER_TABLE;
pub const PTRS_PER_PTE: usize = PTRS_PER_TABLE;
const PPN_SHIFT: usize = 10;
const PPN_MASK: usize = (1usize << (PA_BITS - PAGE_SHIFT)) - 1;
#[inline(always)]
fn paddr_to_ppn(paddr: usize) -> usize {
(paddr >> PAGE_SHIFT) << PPN_SHIFT
}
#[inline(always)]
fn ppn_to_paddr(entry: usize) -> usize {
((entry >> PPN_SHIFT) & PPN_MASK) << PAGE_SHIFT
}
#[inline(always)]
pub(crate) fn paddr_to_table(paddr: usize) -> usize {
paddr_to_ppn(paddr) | PTE_V
}
#[inline(always)]
pub(crate) fn table_to_paddr(entry: usize) -> usize {
ppn_to_paddr(entry)
}
#[inline(always)]
pub(crate) fn paddr_to_leaf(paddr: usize, prot: PageProt, _level: PageLevel) -> usize {
paddr_to_ppn(paddr) | prot_to_attr(prot)
}
#[inline(always)]
pub(crate) fn leaf_to_paddr(entry: usize) -> usize {
ppn_to_paddr(entry)
}
#[inline(always)]
pub(crate) fn entry_is_valid(entry: usize) -> bool {
entry & PTE_V != 0
}
#[inline(always)]
pub(crate) fn entry_is_leaf(entry: usize) -> bool {
entry & PTE_V != 0 && entry & (PTE_R | PTE_X) != 0
}
const fn mk_attr(bits: usize) -> usize {
let mut flags = PTE_V | PTE_A;
if bits & 1 != 0 {
flags |= PTE_R;
}
if bits & 2 != 0 {
flags |= PTE_W | PTE_D;
}
if bits & 4 != 0 {
flags |= PTE_X;
}
if bits & 8 != 0 {
flags |= PTE_U;
}
flags
}
const fn build_table() -> [usize; 16] {
let mut table = [0usize; 16];
let mut idx = 0usize;
while idx < 16 {
table[idx] = mk_attr(idx);
idx += 1;
}
table
}
const ATTR_TABLE: [usize; 16] = build_table();
#[inline(always)]
fn prot_to_attr(prot: PageProt) -> usize {
ATTR_TABLE[prot.bits() & 0xF]
}