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)
}