diff --git a/src/arch/aarch64.rs b/src/arch/aarch64.rs index f9896e3879..3f5305a5d3 100644 --- a/src/arch/aarch64.rs +++ b/src/arch/aarch64.rs @@ -84,6 +84,19 @@ impl Arch for AArch64Arch { //TODO: Does this need to be called? Self::invalidate_all(); } + + fn virt_is_valid(address: VirtualAddress) -> bool { + // TODO + true + } + fn virt_kind(address: VirtualAddress) -> TableKind { + // TODO: Is this correct? + if address.data() & (1 << 63) == (1 << 63) { + TableKind::Kernel + } else { + TableKind::User + } + } } #[cfg(test)] diff --git a/src/arch/mod.rs b/src/arch/mod.rs index 3c9d0e0c31..a24eae36e0 100644 --- a/src/arch/mod.rs +++ b/src/arch/mod.rs @@ -3,6 +3,7 @@ use core::ptr; use crate::{ MemoryArea, PhysicalAddress, + TableKind, VirtualAddress, }; @@ -84,4 +85,7 @@ pub trait Arch: Clone + Copy { unsafe fn phys_to_virt(phys: PhysicalAddress) -> VirtualAddress { VirtualAddress::new(phys.data() + Self::PHYS_OFFSET) } + + fn virt_is_valid(address: VirtualAddress) -> bool; + fn virt_kind(address: VirtualAddress) -> TableKind; } diff --git a/src/arch/riscv64/sv39.rs b/src/arch/riscv64/sv39.rs index e8cb7cd8f4..ced17ecb0d 100644 --- a/src/arch/riscv64/sv39.rs +++ b/src/arch/riscv64/sv39.rs @@ -2,6 +2,7 @@ use crate::{ Arch, MemoryArea, PhysicalAddress, + TableKind, VirtualAddress, }; @@ -58,6 +59,13 @@ impl Arch for RiscV64Sv39Arch { (address.data() >> Self::PAGE_SHIFT); // Convert to PPN (TODO: ensure alignment) asm!("csrw satp, {0}", in(reg) satp); } + + fn virt_is_valid(address: VirtualAddress) -> bool { + todo!() + } + fn virt_kind(address: VirtualAddress) -> TableKind { + todo!() + } } #[cfg(test)] diff --git a/src/arch/riscv64/sv48.rs b/src/arch/riscv64/sv48.rs index f49076cc66..f26aeb7216 100644 --- a/src/arch/riscv64/sv48.rs +++ b/src/arch/riscv64/sv48.rs @@ -2,6 +2,7 @@ use crate::{ Arch, MemoryArea, PhysicalAddress, + TableKind, VirtualAddress, }; @@ -58,6 +59,12 @@ impl Arch for RiscV64Sv48Arch { (address.data() >> Self::PAGE_SHIFT); // Convert to PPN (TODO: ensure alignment) asm!("csrw satp, {0}", in(reg) satp); } + fn virt_is_valid(address: VirtualAddress) -> bool { + todo!() + } + fn virt_kind(address: VirtualAddress) -> TableKind { + todo!() + } } #[cfg(test)] diff --git a/src/arch/x86_64.rs b/src/arch/x86_64.rs index 3b0a2572da..ead8013100 100644 --- a/src/arch/x86_64.rs +++ b/src/arch/x86_64.rs @@ -2,6 +2,7 @@ use crate::{ Arch, MemoryArea, PhysicalAddress, + TableKind, VirtualAddress, }; @@ -47,12 +48,37 @@ impl Arch for X8664Arch { unsafe fn set_table(address: PhysicalAddress) { asm!("mov cr3, {0}", in(reg) address.data()); } + + fn virt_is_valid(address: VirtualAddress) -> bool { + // On x86_64, an address is valid if and only if it is canonical. It may still point to + // unmapped memory, but will always be valid once translated via the page table has + // suceeded. + address.is_canonical() + } + fn virt_kind(address: VirtualAddress) -> TableKind { + if address.data() & (1 << 48) == (1 << 48) { + TableKind::Kernel + } else { + TableKind::User + } + } +} + +impl VirtualAddress { + #[cfg(any(doc, target_arch = "x86_64"))] + #[doc(cfg(target_arch = "x86_64"))] + pub fn is_canonical(self) -> bool { + let masked = self.data() & 0xFFFF_8000_0000_0000; + // TODO: 5-level paging + masked == 0xFFFF_8000_0000_0000 + || masked == 0 + } } #[cfg(test)] mod tests { use crate::Arch; - use super::X8664Arch; + use super::{VirtualAddress, X8664Arch}; #[test] fn constants() { @@ -72,4 +98,21 @@ mod tests { assert_eq!(X8664Arch::PHYS_OFFSET, 0xFFFF_8000_0000_0000); } + #[test] + fn is_canonical() { + fn yes(address: usize) { + assert!(VirtualAddress::new(address).is_canonical()); + } + fn no(address: usize) { + assert!(!VirtualAddress::new(address).is_canonical()); + } + + yes(0xFFFF_8000_1337_1337); + yes(0xFFFF_FFFF_FFFF_FFFF); + yes(0x0000_0000_0000_0042); + yes(0x0000_7FFF_FFFF_FFFF); + no(0x1337_0000_0000_0000); + no(0x1337_8000_0000_0000); + no(0x0000_8000_0000_0000); + } } diff --git a/src/lib.rs b/src/lib.rs index 487e089e88..58d27a564b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ #![cfg_attr(not(feature = "std"), no_std)] -#![feature(asm)] +#![feature(asm, doc_cfg)] pub use crate::{ allocator::*,