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