From 7e5da6c8973ce1f0608853c0af78abd8ac85a325 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 4 Dec 2015 13:11:18 +0100 Subject: [PATCH] Modify `pointed_frame` to return an Option --- src/memory/paging/entry.rs | 8 ++++++-- src/memory/paging/lock.rs | 13 +++++++------ src/memory/paging/translate.rs | 6 +++--- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/memory/paging/entry.rs b/src/memory/paging/entry.rs index 585d06a6..7c739e07 100644 --- a/src/memory/paging/entry.rs +++ b/src/memory/paging/entry.rs @@ -15,8 +15,12 @@ impl Entry { EntryFlags::from_bits_truncate(self.0) } - pub fn pointed_frame(&self) -> Frame { - Frame { number: ((self.0 & 0x000fffff_fffff000) >> 12) as usize } + pub fn pointed_frame(&self) -> Option { + if self.flags().contains(PRESENT) { + Some(Frame { number: ((self.0 & 0x000fffff_fffff000) >> 12) as usize }) + } else { + None + } } pub fn set(&mut self, frame: Frame, flags: EntryFlags) { diff --git a/src/memory/paging/lock.rs b/src/memory/paging/lock.rs index f3fd5837..9a3b6e96 100644 --- a/src/memory/paging/lock.rs +++ b/src/memory/paging/lock.rs @@ -69,7 +69,7 @@ impl Lock { .and_then(|p3| { // 1GiB page? if p3[page.p3_index()].flags().contains(HUGE_PAGE | PRESENT) { - let start_frame_number = p3[page.p3_index()].pointed_frame().number; + let start_frame_number = p3[page.p3_index()].pointed_frame().unwrap().number; // address must be 1GiB aligned assert!(start_frame_number % (ENTRY_COUNT * ENTRY_COUNT) == 0); return Some(start_frame_number + page.p2_index() * ENTRY_COUNT + @@ -78,7 +78,10 @@ impl Lock { if let Some(p2) = p3.next_table(page.p3_index()) { // 2MiB page? if p2[page.p2_index()].flags().contains(HUGE_PAGE | PRESENT) { - let start_frame_number = p2[page.p2_index()].pointed_frame().number; + let start_frame_number = p2[page.p2_index()] + .pointed_frame() + .unwrap() + .number; // address must be 2MiB aligned assert!(start_frame_number % ENTRY_COUNT == 0); return Some(start_frame_number + page.p1_index()); @@ -92,7 +95,7 @@ impl Lock { p4.next_table(page.p4_index()) .and_then(|p3| p3.next_table(page.p3_index())) .and_then(|p2| p2.next_table(page.p2_index())) - .map(|p1| p1[page.p1_index()].pointed_frame()) + .and_then(|p1| p1[page.p1_index()].pointed_frame()) .or_else(huge_page) } @@ -133,9 +136,7 @@ impl Lock { .and_then(|p3| p3.next_table_mut(page.p3_index())) .and_then(|p2| p2.next_table_mut(page.p2_index())) .unwrap(); - - assert!(!p1[page.p1_index()].flags().contains(PRESENT)); - let frame = p1[page.p1_index()].pointed_frame(); + let frame = p1[page.p1_index()].pointed_frame().unwrap(); p1[page.p1_index()].set_unused(); unsafe { tlb::flush(page.start_address()) }; // TODO free p(1,2,3) table if empty diff --git a/src/memory/paging/translate.rs b/src/memory/paging/translate.rs index 78bc84a2..97d8b58d 100644 --- a/src/memory/paging/translate.rs +++ b/src/memory/paging/translate.rs @@ -17,7 +17,7 @@ fn translate_page(page: Page) -> Option { .and_then(|p3| { // 1GiB page? if p3[page.p3_index()].flags().contains(HUGE_PAGE | PRESENT) { - let start_frame_number = p3[page.p3_index()].pointed_frame().number; + let start_frame_number = p3[page.p3_index()].pointed_frame().unwrap().number; // address must be 1GiB aligned assert!(start_frame_number % (ENTRY_COUNT * ENTRY_COUNT) == 0); return Some(start_frame_number + page.p2_index() * ENTRY_COUNT + page.p1_index()); @@ -25,7 +25,7 @@ fn translate_page(page: Page) -> Option { if let Some(p2) = p3.next_table(page.p3_index()) { // 2MiB page? if p2[page.p2_index()].flags().contains(HUGE_PAGE | PRESENT) { - let start_frame_number = p2[page.p2_index()].pointed_frame().number; + let start_frame_number = p2[page.p2_index()].pointed_frame().unwrap().number; // address must be 2MiB aligned assert!(start_frame_number % ENTRY_COUNT == 0); return Some(start_frame_number + page.p1_index()); @@ -39,6 +39,6 @@ fn translate_page(page: Page) -> Option { p4.next_table(page.p4_index()) .and_then(|p3| p3.next_table(page.p3_index())) .and_then(|p2| p2.next_table(page.p2_index())) - .map(|p1| p1[page.p1_index()].pointed_frame()) + .and_then(|p1| p1[page.p1_index()].pointed_frame()) .or_else(huge_page) }