From 8e2ee50f66c171c2aa592193b051d4987139585c Mon Sep 17 00:00:00 2001 From: Erin Date: Sun, 4 Jun 2017 11:45:26 -0500 Subject: [PATCH] Preliminary data structures required for a page table manager --- src/arch/x86_64/memory/paging/entry.rs | 49 ++++++++++++++++++++++++++++++++++ src/arch/x86_64/memory/paging/mod.rs | 21 +++++++++++++++ src/arch/x86_64/memory/paging/table.rs | 29 ++++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 src/arch/x86_64/memory/paging/entry.rs create mode 100644 src/arch/x86_64/memory/paging/mod.rs create mode 100644 src/arch/x86_64/memory/paging/table.rs diff --git a/src/arch/x86_64/memory/paging/entry.rs b/src/arch/x86_64/memory/paging/entry.rs new file mode 100644 index 0000000..e2c8f9b --- /dev/null +++ b/src/arch/x86_64/memory/paging/entry.rs @@ -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 { + 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; + } +} diff --git a/src/arch/x86_64/memory/paging/mod.rs b/src/arch/x86_64/memory/paging/mod.rs new file mode 100644 index 0000000..cd4078e --- /dev/null +++ b/src/arch/x86_64/memory/paging/mod.rs @@ -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, +} diff --git a/src/arch/x86_64/memory/paging/table.rs b/src/arch/x86_64/memory/paging/table.rs new file mode 100644 index 0000000..b5ec2d5 --- /dev/null +++ b/src/arch/x86_64/memory/paging/table.rs @@ -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 for Table { + type Output = Entry; + + fn index(&self, index: usize) -> &Entry { + &self.entries[index] + } +} + +impl IndexMut for Table { + fn index_mut(&mut self, index: usize) -> &mut Entry { + &mut self.entries[index] + } +}