From 2813cce2a76e25774d3b6740a87e21e8943c14c4 Mon Sep 17 00:00:00 2001 From: Erin Date: Sun, 4 Jun 2017 15:50:51 -0500 Subject: [PATCH] memory::paging::Table: next_table, next_table_create --- src/arch/x86_64/memory/paging/table.rs | 37 ++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/arch/x86_64/memory/paging/table.rs b/src/arch/x86_64/memory/paging/table.rs index a0a58be..517aa3b 100644 --- a/src/arch/x86_64/memory/paging/table.rs +++ b/src/arch/x86_64/memory/paging/table.rs @@ -35,6 +35,43 @@ impl Table where L: TableLevel { } } +impl Table where L: HierarchicalLevel { + fn next_table_address(&self, index: usize) -> Option { + let entry_flags = self[index].flags(); + if entry_flags.contains(PRESENT) && !entry_flags.contains(HUGE_PAGE) { + let table_address = self as *const _ as usize; + Some((table_address << 9) | (index << 12)) + } else { + None + } + } + + pub fn next_table(&self, index: usize) -> Option<&Table> { + self.next_table_address(index) + .map(|addr| unsafe {&*(addr as *const _)}) + } + + pub fn next_table_mut(&self, index: usize) -> Option<&mut Table> { + self.next_table_address(index) + .map(|addr| unsafe {&mut *(addr as *mut _)}) + } + + pub fn next_table_create(&mut self, index: usize, allocator: &mut A) -> &mut Table + where A: FrameAllocator { + if self.next_table(index).is_none() { + assert!(!self.entries[index].flags().contains(HUGE_PAGE), + "Attempted to create a subtable for a hugepage; we do not currently support hugepages."); + let frame = allocator.alloc_frame() + .expect("Attempted to allocate a frame for a subtable, but no frames are available!"); + + self.entries[index].set(frame, PRESENT | WRITABLE); + // Zero the new table + self.next_table_mut(index).unwrap().zero(); + } + + self.next_table_mut(index).unwrap() + } +} impl Index for Table where L: TableLevel { type Output = Entry;