From 39dab16baa71db297676a623cf4c103bcad8c1d8 Mon Sep 17 00:00:00 2001 From: Paul Pan Date: Sat, 15 Jun 2024 19:58:41 +0800 Subject: [PATCH] feat: arch: riscv: allow to get current pagetable --- kernel/src/arch/riscv/vspace/addr/mod.rs | 6 ++++++ kernel/src/arch/riscv/vspace/addr/sv39.rs | 4 ++++ kernel/src/arch/riscv/vspace/utils.rs | 9 +++++++++ kernel/src/vspace/addr.rs | 3 +++ 4 files changed, 22 insertions(+) diff --git a/kernel/src/arch/riscv/vspace/addr/mod.rs b/kernel/src/arch/riscv/vspace/addr/mod.rs index 9e9e74e..4d94d0f 100644 --- a/kernel/src/arch/riscv/vspace/addr/mod.rs +++ b/kernel/src/arch/riscv/vspace/addr/mod.rs @@ -38,6 +38,12 @@ trait GenericPhysAddrPage: AddressOps { 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 { let addr = ((pte & Self::PTE_PPN_MASK) >> Self::PPN_OFFSET) << Self::PG_OFFSET; let bits = Self::PPN_BITS + Self::PG_OFFSET; diff --git a/kernel/src/arch/riscv/vspace/addr/sv39.rs b/kernel/src/arch/riscv/vspace/addr/sv39.rs index a16f1db..f1588d8 100644 --- a/kernel/src/arch/riscv/vspace/addr/sv39.rs +++ b/kernel/src/arch/riscv/vspace/addr/sv39.rs @@ -21,6 +21,10 @@ impl PhysAddrPage for PhysAddr { GenericPhysAddrPage::extract_ppn_shifted(self) } + fn from_ppn(ppn: usize) -> PhysAddr { + PhysAddr::from(::from_ppn(ppn)) + } + fn from_pte(pte: usize) -> PhysAddr { PhysAddr::from(::from_pte(pte)) } diff --git a/kernel/src/arch/riscv/vspace/utils.rs b/kernel/src/arch/riscv/vspace/utils.rs index afb61dd..3f5eca4 100644 --- a/kernel/src/arch/riscv/vspace/utils.rs +++ b/kernel/src/arch/riscv/vspace/utils.rs @@ -100,3 +100,12 @@ pub unsafe fn install_pagetable(addr: PhysAddr) { riscv::register::satp::set(page_table_mode(), 0, addr.extract_ppn()); 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)) +} diff --git a/kernel/src/vspace/addr.rs b/kernel/src/vspace/addr.rs index 1cd6382..96f4b2e 100644 --- a/kernel/src/vspace/addr.rs +++ b/kernel/src/vspace/addr.rs @@ -22,6 +22,9 @@ pub trait PhysAddrPage: AddressOps { /// Almost the same as `paddr_extract_ppn`, but the PPN remains shifted in the address. 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. fn from_pte(pte: usize) -> Self;