Move PageSize to a mod and implement it for phys frames and virt pages
This commit is contained in:
parent
1eed756d04
commit
d278383184
nucleus/src/arch/aarch64/memory
|
@ -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 {
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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> {
|
||||
|
|
Loading…
Reference in New Issue