holey-bytes/hbvm/src/mem/softpaged/paging.rs

85 lines
2 KiB
Rust
Raw Normal View History

2023-06-24 17:18:31 -05:00
//! Page table and associated structures implementation
2023-07-20 13:47:50 -05:00
use core::{fmt::Debug, mem::MaybeUninit};
2023-06-24 17:16:14 -05:00
/// Page entry permission
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
#[repr(u8)]
pub enum Permission {
2023-06-24 17:16:14 -05:00
/// No page present
#[default]
Empty,
2023-06-24 17:16:14 -05:00
/// Points to another pagetable
Node,
2023-06-24 17:16:14 -05:00
/// Page is read only
Readonly,
2023-06-24 17:16:14 -05:00
/// Page is readable and writable
Write,
2023-06-24 17:16:14 -05:00
/// Page is readable and executable
Exec,
}
2023-06-24 17:16:14 -05:00
/// Page table entry
#[derive(Clone, Copy, Default, PartialEq, Eq)]
pub struct PtEntry(u64);
impl PtEntry {
2023-06-24 17:16:14 -05:00
/// Create new
2023-07-11 03:33:25 -05:00
///
2023-06-24 17:21:40 -05:00
/// # Safety
/// - `ptr` has to point to valid data and shall not be deallocated
/// troughout the entry lifetime
#[inline]
pub unsafe fn new(ptr: *mut PtPointedData, permission: Permission) -> Self {
Self(ptr as u64 | permission as u64)
}
2023-06-24 17:16:14 -05:00
/// Get permission
#[inline]
pub fn permission(&self) -> Permission {
unsafe { core::mem::transmute(self.0 as u8 & 0b111) }
}
2023-06-24 17:16:14 -05:00
/// Get pointer to the data (leaf) or next page table (node)
#[inline]
pub fn ptr(&self) -> *mut PtPointedData {
(self.0 & !((1 << 12) - 1)) as _
}
}
impl Debug for PtEntry {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("PtEntry")
.field("ptr", &self.ptr())
.field("permission", &self.permission())
.finish()
}
}
2023-06-24 17:16:14 -05:00
/// Page table
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(align(4096))]
2023-07-20 13:47:50 -05:00
pub struct PageTable {
pub childen: u8,
pub table: [PtEntry; 256],
}
impl Default for PageTable {
fn default() -> Self {
2023-06-24 17:16:14 -05:00
// SAFETY: It's fine, zeroed page table entry is valid (= empty)
2023-07-20 13:47:50 -05:00
Self {
childen: 0,
table: unsafe { MaybeUninit::zeroed().assume_init() },
}
}
}
2023-06-24 17:16:14 -05:00
/// Data page table entry can possibly point to
#[derive(Clone, Copy)]
#[repr(C, align(4096))]
pub union PtPointedData {
2023-06-24 17:16:14 -05:00
/// Node - next page table
2023-07-11 03:33:25 -05:00
pub pt: PageTable,
2023-06-24 17:16:14 -05:00
/// Leaf
pub page: u8,
}