From e215f9d62c7b81e97e5cf790edc86784f8011a4a Mon Sep 17 00:00:00 2001 From: Berkus Decker Date: Fri, 26 Feb 2021 00:16:42 +0200 Subject: [PATCH] [wip] add to-kernel-space/from-kernel-space address conversion --- nucleus/src/arch/aarch64/memory/addr/mod.rs | 5 +++++ nucleus/src/arch/aarch64/memory/addr/phys_addr.rs | 12 +++++++++++- nucleus/src/arch/aarch64/memory/addr/virt_addr.rs | 12 +++++++++++- nucleus/src/arch/aarch64/memory/mmu-experimental.rs | 4 ---- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/nucleus/src/arch/aarch64/memory/addr/mod.rs b/nucleus/src/arch/aarch64/memory/addr/mod.rs index 54076b1..3988351 100644 --- a/nucleus/src/arch/aarch64/memory/addr/mod.rs +++ b/nucleus/src/arch/aarch64/memory/addr/mod.rs @@ -10,3 +10,8 @@ mod virt_addr; pub use asid::*; pub use phys_addr::*; pub use virt_addr::*; + +// @todo Check largest VA supported, calculate physical_memory_offset +// @todo Keep in mind amount of physical memory present, the following +// @todo will only work for 1Gb board: +pub const PHYSICAL_MEMORY_OFFSET: u64 = 0xffff_8000_0000_0000; // Last 1GiB of VA space diff --git a/nucleus/src/arch/aarch64/memory/addr/phys_addr.rs b/nucleus/src/arch/aarch64/memory/addr/phys_addr.rs index 4e29e58..fd9afd7 100644 --- a/nucleus/src/arch/aarch64/memory/addr/phys_addr.rs +++ b/nucleus/src/arch/aarch64/memory/addr/phys_addr.rs @@ -4,7 +4,10 @@ */ use { - crate::mm::{align_down, align_up}, + crate::{ + memory::VirtAddr, + mm::{align_down, align_up}, + }, bit_field::BitField, core::{ convert::{From, Into}, @@ -97,6 +100,13 @@ impl PhysAddr { { self.aligned_down(align) == self } + + /// Convert physical memory address into a kernel virtual address. + pub fn user_to_kernel(&self) -> VirtAddr { + use super::PHYSICAL_MEMORY_OFFSET; + assert!(self.0 < !PHYSICAL_MEMORY_OFFSET); // Can't have phys address over 1GiB then + VirtAddr::new(self.0 + PHYSICAL_MEMORY_OFFSET) + } } impl fmt::Debug for PhysAddr { diff --git a/nucleus/src/arch/aarch64/memory/addr/virt_addr.rs b/nucleus/src/arch/aarch64/memory/addr/virt_addr.rs index 4357f68..013f182 100644 --- a/nucleus/src/arch/aarch64/memory/addr/virt_addr.rs +++ b/nucleus/src/arch/aarch64/memory/addr/virt_addr.rs @@ -4,7 +4,10 @@ */ use { - crate::mm::{align_down, align_up}, + crate::{ + memory::PhysAddr, + mm::{align_down, align_up}, + }, bit_field::BitField, core::{ convert::{From, Into, TryInto}, @@ -158,6 +161,13 @@ impl VirtAddr { pub fn l0_index(&self) -> u9 { u9::new(((self.0 >> 12 >> 9 >> 9 >> 9) & 0o777).try_into().unwrap()) } + + /// Convert kernel-space virtual address into a physical memory address. + pub fn kernel_to_user(&self) -> PhysAddr { + use super::PHYSICAL_MEMORY_OFFSET; + assert!(self.0 > PHYSICAL_MEMORY_OFFSET); + PhysAddr::new(self.0 - PHYSICAL_MEMORY_OFFSET) + } } impl fmt::Debug for VirtAddr { diff --git a/nucleus/src/arch/aarch64/memory/mmu-experimental.rs b/nucleus/src/arch/aarch64/memory/mmu-experimental.rs index e970ab6..2f15924 100644 --- a/nucleus/src/arch/aarch64/memory/mmu-experimental.rs +++ b/nucleus/src/arch/aarch64/memory/mmu-experimental.rs @@ -1,7 +1,3 @@ -// Check largest VA supported, calculate physical_memory_offset -// -const PHYSICAL_MEMORY_OFFSET: u64 = 0xffff_8000_0000_0000; // Last 1GiB of VA space - // AArch64: // Table D4-8-2021: check supported granule sizes, select alloc policy based on results. // TTBR_ELx is the pdbr for specific page tables