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