use memory_addr::VirtAddr;
use page_table_entry::riscv::Rv64PTE;
use crate::{PageTable64, PageTable64Cursor, PagingMetaData};
pub trait SvVirtAddr: memory_addr::MemoryAddr + Send + Sync {
fn flush_tlb(vaddr: Option<Self>);
}
impl SvVirtAddr for VirtAddr {
#[inline]
fn flush_tlb(vaddr: Option<Self>) {
if let Some(vaddr) = vaddr {
riscv::asm::sfence_vma(0, vaddr.as_usize())
} else {
riscv::asm::sfence_vma_all();
}
}
}
pub struct Sv39MetaData<VA: SvVirtAddr> {
_virt_addr: core::marker::PhantomData<VA>,
}
pub struct Sv48MetaData<VA: SvVirtAddr> {
_virt_addr: core::marker::PhantomData<VA>,
}
impl<VA: SvVirtAddr> PagingMetaData for Sv39MetaData<VA> {
const LEVELS: usize = 3;
const PA_MAX_BITS: usize = 56;
const VA_MAX_BITS: usize = 39;
type VirtAddr = VA;
#[inline]
fn flush_tlb(vaddr: Option<VA>) {
<VA as SvVirtAddr>::flush_tlb(vaddr);
}
}
impl<VA: SvVirtAddr> PagingMetaData for Sv48MetaData<VA> {
const LEVELS: usize = 4;
const PA_MAX_BITS: usize = 56;
const VA_MAX_BITS: usize = 48;
type VirtAddr = VA;
#[inline]
fn flush_tlb(vaddr: Option<VA>) {
<VA as SvVirtAddr>::flush_tlb(vaddr);
}
}
pub type Sv39PageTable<H> = PageTable64<Sv39MetaData<VirtAddr>, Rv64PTE, H>;
pub type Sv39PageTableCursor<'a, H> = PageTable64Cursor<'a, Sv39MetaData<VirtAddr>, Rv64PTE, H>;
pub type Sv48PageTable<H> = PageTable64<Sv48MetaData<VirtAddr>, Rv64PTE, H>;
pub type Sv48PageTableCursor<'a, H> = PageTable64Cursor<'a, Sv48MetaData<VirtAddr>, Rv64PTE, H>;