Add arch functions for checking canonical addrs.

This commit is contained in:
4lDO2
2021-07-08 13:27:08 +02:00
parent c66956ca2a
commit 32caee3095
6 changed files with 77 additions and 2 deletions
+13
View File
@@ -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)]
+4
View File
@@ -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;
}
+8
View File
@@ -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)]
+7
View File
@@ -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)]
+44 -1
View File
@@ -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);
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![feature(asm)]
#![feature(asm, doc_cfg)]
pub use crate::{
allocator::*,