Skip to content

Commit

Permalink
Refactor to integer with access methods
Browse files Browse the repository at this point in the history
Signed-off-by: Marcus Weiner <[email protected]>
  • Loading branch information
mraerino committed Sep 10, 2023
1 parent f072d8f commit 9b59755
Showing 1 changed file with 27 additions and 42 deletions.
69 changes: 27 additions & 42 deletions riscv64/src/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,61 +16,46 @@ bitflags! {
}
}

#[derive(Clone, Copy, Debug)]
struct SizedInteger<const N: usize>(u64);
/// Used as an index for PPN and VPN
pub enum PageNumberSegment {
_0,
_1,
_2,
}

#[derive(Debug)]
pub struct NumberTooLarge;
pub struct PageTableEntry(u64);

impl<const N: usize> TryFrom<u64> for SizedInteger<N> {
type Error = NumberTooLarge;
impl PageTableEntry {
pub unsafe fn write_to(&self, addr: u64) {
unsafe { write_volatile(addr as *mut u64, self.0) }
}

fn try_from(value: u64) -> Result<Self, Self::Error> {
if (value.leading_zeros() as usize) < 64 - N {
return Err(NumberTooLarge);
pub fn ppn(&self, i: PageNumberSegment) -> u64 {
use PageNumberSegment::*;
match i {
_0 => self.0.get_bits(10..=18),
_1 => self.0.get_bits(19..=27),
_2 => self.0.get_bits(28..=53),
}
Ok(Self(value))
}
}

impl<const N: usize> From<SizedInteger<N>> for u64 {
fn from(value: SizedInteger<N>) -> Self {
value.0
pub fn flags(&self) -> PageTableFlags {
let bits = self.0.get_bits(0..=7) as u8;
// safe to unwrap since all bits of a u8 are defined flags
PageTableFlags::from_bits(bits).unwrap()
}
}

#[derive(Debug)]
pub struct PageTableEntry {
ppn2: SizedInteger<26>,
ppn1: SizedInteger<9>,
ppn0: SizedInteger<9>,
flags: PageTableFlags,
}

impl PageTableEntry {
pub fn serialize(&self) -> u64 {
let mut out = 0u64;
out.set_bits(0..=7, self.flags.bits() as _);
out.set_bits(10..=18, self.ppn0.into());
out.set_bits(19..=27, self.ppn1.into());
out.set_bits(28..=53, self.ppn2.into());
out
}

pub unsafe fn write_to(&self, addr: u64) {
unsafe { write_volatile(addr as *mut u64, self.serialize()) }
impl From<u64> for PageTableEntry {
fn from(value: u64) -> Self {
Self(value)
}
}

impl From<u64> for PageTableEntry {
fn from(value: u64) -> Self {
let flags = PageTableFlags::from_bits(value.get_bits(0..=7) as _).unwrap();
Self {
ppn2: value.get_bits(28..=53).try_into().unwrap(),
ppn1: value.get_bits(19..=27).try_into().unwrap(),
ppn0: value.get_bits(10..=18).try_into().unwrap(),
flags,
}
impl From<PageTableEntry> for u64 {
fn from(value: PageTableEntry) -> Self {
value.0
}
}

Expand Down

0 comments on commit 9b59755

Please sign in to comment.