yggdrasil/src/mem/table.rs

70 lines
2.2 KiB
Rust

//! Virtual memory table interface
use core::ops::{Deref, DerefMut};
use abi::error::Error;
use bitflags::bitflags;
// TODO EXECUTABLE
bitflags! {
/// Describes how a page translation mapping should behave
#[derive(Clone, Copy)]
pub struct MapAttributes: u64 {
/// The data mapped can be read by the user process
const USER_READ = 1 << 0;
/// The data mapped can be written to by the user process
const USER_WRITE = 1 << 1;
/// The mapping is not global across the address spaces
const NON_GLOBAL = 1 << 2;
}
}
/// Interface for non-terminal tables to retrieve the next level of address translation tables
pub trait NextPageTable {
/// Type for the next-level page table
type NextLevel;
type TableRef: Deref<Target = Self::NextLevel>;
type TableRefMut: DerefMut<Target = Self::NextLevel>;
/// Tries looking up a next-level table at given index, allocating and mapping one if it is not
/// present there
fn get_mut_or_alloc(&mut self, index: usize) -> Result<Self::TableRefMut, Error>;
/// Returns a mutable reference to a next-level table at `index`, if present
fn get_mut(&mut self, index: usize) -> Option<Self::TableRefMut>;
fn get(&self, index: usize) -> Option<Self::TableRef>;
}
/// Interface for a single level of address translation
#[const_trait]
pub trait EntryLevel: Copy {
const SHIFT: usize;
const SIZE: usize = 1 << Self::SHIFT;
/// Returns the index into a page table for a given address
#[inline]
fn index(addr: usize) -> usize {
(addr >> Self::SHIFT) & 0x1FF
}
/// Returns the offset of an address from the page start at current level
#[inline]
fn page_offset(addr: usize) -> usize {
addr & (Self::SIZE - 1)
}
#[inline]
fn align_up(addr: usize) -> usize {
(addr + Self::SIZE - 1) & !(Self::SIZE - 1)
}
#[inline]
fn page_count(addr: usize) -> usize {
(addr + Self::SIZE - 1) / Self::SIZE
}
}
/// Tag trait to mark that the page table level may point to a next-level table
pub trait NonTerminalEntryLevel: EntryLevel {
/// Tag type of the level this entry level may point to
type NextLevel: EntryLevel;
}