Move PageSize to a mod and implement it for phys frames and virt pages

This commit is contained in:
Berkus Decker 2021-02-26 00:19:11 +02:00
parent 1eed756d04
commit d278383184
6 changed files with 101 additions and 71 deletions

View File

@ -4,30 +4,6 @@
// Page 2068 actual page descriptor formats
/// A standard 16KiB page.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Size16KiB {}
impl PageSize for Size16KiB {
const SIZE: u64 = 16384;
const SIZE_AS_DEBUG_STR: &'static str = "16KiB";
const SHIFT: usize = 14;
const MASK: u64 = 0x3fff;
}
impl NotGiantPageSize for Size16KiB {}
/// A “giant” 1GiB page.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Size1GiB {}
impl PageSize for Size1GiB {
const SIZE: u64 = Size2MiB::SIZE * NUM_ENTRIES_4KIB;
const SIZE_AS_DEBUG_STR: &'static str = "1GiB";
const SHIFT: usize = 59; // @todo
const MASK: u64 = 0xfffaaaaa; // @todo
}
/// Errors from mapping layer
#[derive(Debug, Snafu)]
pub enum TranslationError {

View File

@ -93,50 +93,6 @@ fn into_mmu_attributes(
desc
}
/// Trait for abstracting over the possible page sizes, 4KiB, 16KiB, 2MiB, 1GiB.
pub trait PageSize: Copy + Eq + PartialOrd + Ord {
/// The page size in bytes.
const SIZE: u64;
/// A string representation of the page size for debug output.
const SIZE_AS_DEBUG_STR: &'static str;
/// The page shift in bits.
const SHIFT: usize;
/// The page mask in bits.
const MASK: u64;
}
/// This trait is implemented for 4KiB, 16KiB, and 2MiB pages, but not for 1GiB pages.
pub trait NotGiantPageSize: PageSize {} // @todo doesn't have to be pub??
/// A standard 4KiB page.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Size4KiB {}
impl PageSize for Size4KiB {
const SIZE: u64 = 4096;
const SIZE_AS_DEBUG_STR: &'static str = "4KiB";
const SHIFT: usize = 12;
const MASK: u64 = 0xfff;
}
impl NotGiantPageSize for Size4KiB {}
/// A “huge” 2MiB page.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Size2MiB {}
impl PageSize for Size2MiB {
const SIZE: u64 = Size4KiB::SIZE * NUM_ENTRIES_4KIB;
const SIZE_AS_DEBUG_STR: &'static str = "2MiB";
const SHIFT: usize = 21;
const MASK: u64 = 0x1fffff;
}
impl NotGiantPageSize for Size2MiB {}
/// Type-safe enum wrapper covering Table<L>'s 64-bit entries.
#[derive(Clone)]
// #[repr(transparent)]

View File

@ -13,6 +13,7 @@ use {
mod addr;
// pub mod mmu;
mod features;
mod page_size;
mod phys_frame;
mod virt_page;
@ -26,6 +27,7 @@ pub use mmu2::*;
pub use addr::PhysAddr;
pub use addr::VirtAddr;
pub use page_size::PageSize;
pub use phys_frame::PhysFrame;
use mmu_experimental::PhysFrame;

View File

@ -0,0 +1,68 @@
/// Trait for abstracting over the possible page sizes, 4KiB, 16KiB, 2MiB, 1GiB.
pub trait PageSize: Copy + PartialEq + Eq + PartialOrd + Ord {
/// The page size in bytes.
const SIZE: usize;
/// A string representation of the page size for debug output.
const SIZE_AS_DEBUG_STR: &'static str;
/// The page shift in bits.
const SHIFT: usize;
/// The page mask in bits.
const MASK: u64;
}
/// This trait is implemented for 4KiB, 16KiB, and 2MiB pages, but not for 1GiB pages.
pub trait NotGiantPageSize: PageSize {} // @todo doesn't have to be pub??
/// A standard 4KiB page.
#[derive(Debug, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Size4KiB {}
impl PageSize for Size4KiB {
const SIZE: usize = 4 * 1024;
const SIZE_AS_DEBUG_STR: &'static str = "4KiB";
const SHIFT: usize = 12;
const MASK: u64 = 0xfff;
}
impl NotGiantPageSize for Size4KiB {}
/// A standard 16KiB page.
/// Currently unused.
#[derive(Debug, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Size16KiB {}
impl PageSize for Size16KiB {
const SIZE: usize = 16 * 1024;
const SIZE_AS_DEBUG_STR: &'static str = "16KiB";
const SHIFT: usize = 14;
const MASK: u64 = 0x3fff;
}
impl NotGiantPageSize for Size16KiB {}
/// A “huge” 2MiB page.
#[derive(Debug, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Size2MiB {}
impl PageSize for Size2MiB {
const SIZE: usize = 2 * 1024 * 1024;
const SIZE_AS_DEBUG_STR: &'static str = "2MiB";
const SHIFT: usize = 21;
const MASK: u64 = 0x1f_ffff;
}
impl NotGiantPageSize for Size2MiB {}
/// A “giant” 1GiB page.
#[derive(Debug, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Size1GiB {}
impl PageSize for Size1GiB {
const SIZE: usize = 1024 * 1024 * 1024;
const SIZE_AS_DEBUG_STR: &'static str = "1GiB";
const SHIFT: usize = 30;
const MASK: u64 = 0x3fff_ffff;
}

View File

@ -1,6 +1,18 @@
// Verbatim from https://github.com/rust-osdev/x86_64/blob/aa9ae54657beb87c2a491f2ab2140b2332afa6ba/src/structures/paging/frame.rs
// Abstractions for default-sized and huge physical memory frames.
use {
crate::memory::{
page_size::{PageSize, Size4KiB},
PhysAddr,
},
core::{
fmt,
marker::PhantomData,
ops::{Add, AddAssign, Sub, SubAssign},
},
};
/// A physical memory frame.
/// Frame is an addressable unit of the physical address space.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
@ -47,7 +59,7 @@ impl<S: PageSize> PhysFrame<S> {
}
/// Returns the size the frame (4KB, 2MB or 1GB).
pub fn size(&self) -> u64 {
pub fn size(&self) -> usize {
S::SIZE
}

View File

@ -3,6 +3,18 @@
// x86_64 page level numbering: P4 -> P3 -> P2 -> P1
// armv8a page level numbering: L0 -> L1 -> L2 -> L3
use {
crate::memory::{
page_size::{NotGiantPageSize, PageSize, Size1GiB, Size2MiB, Size4KiB},
VirtAddr,
},
core::{
fmt,
marker::PhantomData,
ops::{Add, AddAssign, Sub, SubAssign},
},
ux::u9,
};
/// A virtual memory page.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
@ -14,7 +26,7 @@ pub struct Page<S: PageSize = Size4KiB> {
impl<S: PageSize> Page<S> {
/// The page size in bytes.
pub const SIZE: u64 = S::SIZE;
pub const SIZE: usize = S::SIZE;
/// Returns the page that starts at the given virtual address.
///
@ -40,7 +52,7 @@ impl<S: PageSize> Page<S> {
}
/// Returns the size the page (4KB, 2MB or 1GB).
pub const fn size(&self) -> u64 {
pub const fn size(&self) -> usize {
S::SIZE
}
@ -174,6 +186,10 @@ impl<S: PageSize> PageRange<S> {
pub fn is_empty(&self) -> bool {
self.start >= self.end
}
pub fn num_pages(&self) -> usize {
(self.end - self.start) as usize / S::SIZE
}
}
impl<S: PageSize> Iterator for PageRange<S> {