@ -0,0 +1,49 @@ | |||
use arch::x86_64::memory::Frame; | |||
pub struct Entry(u64); | |||
impl Entry { | |||
pub fn is_unused(&self) -> bool { | |||
self.0 == 0 | |||
} | |||
pub fn set_unused(&mut self) { | |||
self.0 = 0; | |||
} | |||
pub fn flags(&self) -> EntryFlags { | |||
EntryFlags::from_bits_truncate(self.0) | |||
} | |||
pub fn pointed_frame(&self) -> Option<Frame> { | |||
if self.flags().contains(PRESENT) { | |||
Some(Frame::containing_address( | |||
self.0 as usize & 0x000fffff_fffff000 | |||
)) | |||
} else { | |||
None | |||
} | |||
} | |||
pub fn set(&mut self, frame: Frame, flags: EntryFlags) { | |||
// Frame physical address must be page-aligned and smaller than 2^52 | |||
assert!(frame.start_address() & !0x000fffff_fffff000 == 0); | |||
self.0 = (frame.start_address() as u64) | flags.bits(); | |||
} | |||
} | |||
bitflags! { | |||
pub struct EntryFlags: u64 { | |||
const PRESENT = 1 << 0; | |||
const WRITABLE = 1 << 1; | |||
const USER_ACCESSIBLE = 1 << 2; | |||
const WRITE_THROUGH = 1 << 3; | |||
const NO_CACHE = 1 << 4; | |||
const ACCESSED = 1 << 5; | |||
const DIRTY = 1 << 6; | |||
const HUGE_PAGE = 1 << 7; | |||
const GLOBAL = 1 << 8; | |||
const NO_EXECUTE = 1 << 63; | |||
} | |||
} |
@ -0,0 +1,21 @@ | |||
//! Paging subsystem. | |||
//! | |||
//! Extremely ripped off from Phil Oppermann's tutorials, because I don't feel like writing | |||
//! a paging system off the top of my head today. | |||
use super::PAGE_SIZE; | |||
mod entry; | |||
mod table; | |||
/// Upper bound on entries per page table | |||
const ENTRY_COUNT: usize = 512; | |||
/// Helper type aliases used to make function signatures more expressive | |||
pub type PhysicalAddress = usize; | |||
pub type VirtualAddress = usize; | |||
/// A representation of a virtual page | |||
pub struct Page { | |||
index: usize, | |||
} |
@ -0,0 +1,29 @@ | |||
use core::ops::{Index, IndexMut}; | |||
use super::entry::*; | |||
use super::ENTRY_COUNT; | |||
pub struct Table { | |||
entries: [Entry; ENTRY_COUNT], | |||
} | |||
impl Table { | |||
pub fn zero(&mut self) { | |||
for entry in self.entries.iter_mut() { | |||
entry.set_unused(); | |||
} | |||
} | |||
} | |||
impl Index<usize> for Table { | |||
type Output = Entry; | |||
fn index(&self, index: usize) -> &Entry { | |||
&self.entries[index] | |||
} | |||
} | |||
impl IndexMut<usize> for Table { | |||
fn index_mut(&mut self, index: usize) -> &mut Entry { | |||
&mut self.entries[index] | |||
} | |||
} |