feat: arch: riscv: allow to get current pagetable

This commit is contained in:
Paul Pan 2024-06-15 19:58:41 +08:00
parent 00b7c7d7df
commit 39dab16baa
4 changed files with 22 additions and 0 deletions

View File

@ -38,6 +38,12 @@ trait GenericPhysAddrPage: AddressOps {
self.extract_ppn() << Self::PPN_OFFSET self.extract_ppn() << Self::PPN_OFFSET
} }
fn from_ppn(ppn: usize) -> usize {
let addr = ppn << Self::PG_OFFSET;
let bits = Self::PG_OFFSET + Self::PPN_BITS;
sign_extend(addr, bits)
}
fn from_pte(pte: usize) -> usize { fn from_pte(pte: usize) -> usize {
let addr = ((pte & Self::PTE_PPN_MASK) >> Self::PPN_OFFSET) << Self::PG_OFFSET; let addr = ((pte & Self::PTE_PPN_MASK) >> Self::PPN_OFFSET) << Self::PG_OFFSET;
let bits = Self::PPN_BITS + Self::PG_OFFSET; let bits = Self::PPN_BITS + Self::PG_OFFSET;

View File

@ -21,6 +21,10 @@ impl PhysAddrPage for PhysAddr {
GenericPhysAddrPage::extract_ppn_shifted(self) GenericPhysAddrPage::extract_ppn_shifted(self)
} }
fn from_ppn(ppn: usize) -> PhysAddr {
PhysAddr::from(<PhysAddr as GenericPhysAddrPage>::from_ppn(ppn))
}
fn from_pte(pte: usize) -> PhysAddr { fn from_pte(pte: usize) -> PhysAddr {
PhysAddr::from(<PhysAddr as GenericPhysAddrPage>::from_pte(pte)) PhysAddr::from(<PhysAddr as GenericPhysAddrPage>::from_pte(pte))
} }

View File

@ -100,3 +100,12 @@ pub unsafe fn install_pagetable(addr: PhysAddr) {
riscv::register::satp::set(page_table_mode(), 0, addr.extract_ppn()); riscv::register::satp::set(page_table_mode(), 0, addr.extract_ppn());
riscv::asm::sfence_vma_all(); riscv::asm::sfence_vma_all();
} }
pub unsafe fn get_current_pagetable() -> Table<'static, Level0> {
let satp = riscv::register::satp::read();
let paddr = PhysAddr::from_ppn(satp.ppn());
if paddr == PhysAddr(0) {
panic!("get_current_pagetable() could only be called with MMU enabled!");
}
Table::new(mmap_phys_to_virt(paddr))
}

View File

@ -22,6 +22,9 @@ pub trait PhysAddrPage: AddressOps {
/// Almost the same as `paddr_extract_ppn`, but the PPN remains shifted in the address. /// Almost the same as `paddr_extract_ppn`, but the PPN remains shifted in the address.
fn extract_ppn_shifted(&self) -> usize; fn extract_ppn_shifted(&self) -> usize;
/// Converts a Physical Page Number (PPN) into a Physical Address.
fn from_ppn(ppn: usize) -> Self;
/// Converts a PTE into a Physical Address. /// Converts a PTE into a Physical Address.
fn from_pte(pte: usize) -> Self; fn from_pte(pte: usize) -> Self;