Add arch functions for checking canonical addrs.
This commit is contained in:
@@ -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)]
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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
@@ -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
@@ -1,5 +1,5 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![feature(asm)]
|
||||
#![feature(asm, doc_cfg)]
|
||||
|
||||
pub use crate::{
|
||||
allocator::*,
|
||||
|
||||
Reference in New Issue
Block a user