Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve PageTableIndex and PageOffset. #122

Merged
merged 2 commits into from
Feb 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions src/addr.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use core::convert::{Into, TryInto};
use core::fmt;
use core::ops::{Add, AddAssign, Sub, SubAssign};

Expand Down Expand Up @@ -135,27 +134,27 @@ impl VirtAddr {

/// Returns the 12-bit page offset of this virtual address.
pub fn page_offset(&self) -> PageOffset {
PageOffset::new((self.0 & 0xfff).try_into().unwrap())
PageOffset::new_truncate(self.0 as u16)
}

/// Returns the 9-bit level 1 page table index.
pub fn p1_index(&self) -> PageTableIndex {
PageTableIndex::new(((self.0 >> 12) & 0o777).try_into().unwrap())
PageTableIndex::new_truncate((self.0 >> 12) as u16)
}

/// Returns the 9-bit level 2 page table index.
pub fn p2_index(&self) -> PageTableIndex {
PageTableIndex::new(((self.0 >> 12 >> 9) & 0o777).try_into().unwrap())
PageTableIndex::new_truncate((self.0 >> 12 >> 9) as u16)
}

/// Returns the 9-bit level 3 page table index.
pub fn p3_index(&self) -> PageTableIndex {
PageTableIndex::new(((self.0 >> 12 >> 9 >> 9) & 0o777).try_into().unwrap())
PageTableIndex::new_truncate((self.0 >> 12 >> 9 >> 9) as u16)
}

/// Returns the 9-bit level 4 page table index.
pub fn p4_index(&self) -> PageTableIndex {
PageTableIndex::new(((self.0 >> 12 >> 9 >> 9 >> 9) & 0o777).try_into().unwrap())
PageTableIndex::new_truncate((self.0 >> 12 >> 9 >> 9 >> 9) as u16)
}
}

Expand Down Expand Up @@ -247,6 +246,11 @@ impl PhysAddr {
PhysAddr(addr)
}

/// Creates a new physical address, throwing bits 52..64 away.
pub const fn new_truncate(addr: u64) -> PhysAddr {
PhysAddr(addr % (1 << 52))
}

/// Tries to create a new physical address.
///
/// Fails if any bits in the range 52 to 64 are set.
Expand Down
32 changes: 30 additions & 2 deletions src/structures/paging/page_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,14 +217,16 @@ impl IndexMut<usize> for PageTable {
impl Index<PageTableIndex> for PageTable {
type Output = PageTableEntry;

#[inline]
fn index(&self, index: PageTableIndex) -> &Self::Output {
&self.entries[cast::usize(u16::from(index))]
&self.entries[usize::from(index)]
}
}

impl IndexMut<PageTableIndex> for PageTable {
#[inline]
fn index_mut(&mut self, index: PageTableIndex) -> &mut Self::Output {
&mut self.entries[cast::usize(u16::from(index))]
&mut self.entries[usize::from(index)]
}
}

Expand All @@ -237,6 +239,8 @@ impl fmt::Debug for PageTable {
/// A 9-bit index into a page table.
///
/// Can be used to select one of the 512 entries of a page table.
///
/// Guaranteed to only ever contain 0..512.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct PageTableIndex(u16);

Expand All @@ -246,6 +250,11 @@ impl PageTableIndex {
assert!(usize::from(index) < ENTRY_COUNT);
Self(index)
}

/// Creates a new index from the given `u16`. Throws away bits if the value is >=512.
pub const fn new_truncate(index: u16) -> Self {
Self(index % ENTRY_COUNT as u16)
}
}

impl From<PageTableIndex> for u16 {
Expand All @@ -266,9 +275,17 @@ impl From<PageTableIndex> for u64 {
}
}

impl From<PageTableIndex> for usize {
fn from(index: PageTableIndex) -> Self {
usize::from(index.0)
}
}

/// A 12-bit offset into a 4KiB Page.
///
/// This type is returned by the `VirtAddr::page_offset` method.
///
/// Guaranteed to only ever contain 0..4096.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct PageOffset(u16);

Expand All @@ -278,6 +295,11 @@ impl PageOffset {
assert!(offset < (1 << 12));
Self(offset)
}

/// Creates a new offset from the given `u16`. Throws away bits if the value is >=4096.
pub const fn new_truncate(offset: u16) -> Self {
Self(offset % (1 << 12))
}
}

impl From<PageOffset> for u16 {
Expand All @@ -297,3 +319,9 @@ impl From<PageOffset> for u64 {
u64::from(offset.0)
}
}

impl From<PageOffset> for usize {
fn from(offset: PageOffset) -> Self {
usize::from(offset.0)
}
}