@ -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] | |||||
} | |||||
} |