Modify pointed_frame to return an Option

This commit is contained in:
Philipp Oppermann
2015-12-04 13:11:18 +01:00
parent 2d9b619587
commit 7e5da6c897
3 changed files with 16 additions and 11 deletions

View File

@@ -15,8 +15,12 @@ impl Entry {
EntryFlags::from_bits_truncate(self.0) EntryFlags::from_bits_truncate(self.0)
} }
pub fn pointed_frame(&self) -> Frame { pub fn pointed_frame(&self) -> Option<Frame> {
Frame { number: ((self.0 & 0x000fffff_fffff000) >> 12) as usize } 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) { pub fn set(&mut self, frame: Frame, flags: EntryFlags) {

View File

@@ -69,7 +69,7 @@ impl Lock {
.and_then(|p3| { .and_then(|p3| {
// 1GiB page? // 1GiB page?
if p3[page.p3_index()].flags().contains(HUGE_PAGE | PRESENT) { 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 // address must be 1GiB aligned
assert!(start_frame_number % (ENTRY_COUNT * ENTRY_COUNT) == 0); assert!(start_frame_number % (ENTRY_COUNT * ENTRY_COUNT) == 0);
return Some(start_frame_number + page.p2_index() * ENTRY_COUNT + 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()) { if let Some(p2) = p3.next_table(page.p3_index()) {
// 2MiB page? // 2MiB page?
if p2[page.p2_index()].flags().contains(HUGE_PAGE | PRESENT) { 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 // address must be 2MiB aligned
assert!(start_frame_number % ENTRY_COUNT == 0); assert!(start_frame_number % ENTRY_COUNT == 0);
return Some(start_frame_number + page.p1_index()); return Some(start_frame_number + page.p1_index());
@@ -92,7 +95,7 @@ impl Lock {
p4.next_table(page.p4_index()) p4.next_table(page.p4_index())
.and_then(|p3| p3.next_table(page.p3_index())) .and_then(|p3| p3.next_table(page.p3_index()))
.and_then(|p2| p2.next_table(page.p2_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) .or_else(huge_page)
} }
@@ -133,9 +136,7 @@ impl Lock {
.and_then(|p3| p3.next_table_mut(page.p3_index())) .and_then(|p3| p3.next_table_mut(page.p3_index()))
.and_then(|p2| p2.next_table_mut(page.p2_index())) .and_then(|p2| p2.next_table_mut(page.p2_index()))
.unwrap(); .unwrap();
let frame = p1[page.p1_index()].pointed_frame().unwrap();
assert!(!p1[page.p1_index()].flags().contains(PRESENT));
let frame = p1[page.p1_index()].pointed_frame();
p1[page.p1_index()].set_unused(); p1[page.p1_index()].set_unused();
unsafe { tlb::flush(page.start_address()) }; unsafe { tlb::flush(page.start_address()) };
// TODO free p(1,2,3) table if empty // TODO free p(1,2,3) table if empty

View File

@@ -17,7 +17,7 @@ fn translate_page(page: Page) -> Option<Frame> {
.and_then(|p3| { .and_then(|p3| {
// 1GiB page? // 1GiB page?
if p3[page.p3_index()].flags().contains(HUGE_PAGE | PRESENT) { 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 // address must be 1GiB aligned
assert!(start_frame_number % (ENTRY_COUNT * ENTRY_COUNT) == 0); assert!(start_frame_number % (ENTRY_COUNT * ENTRY_COUNT) == 0);
return Some(start_frame_number + page.p2_index() * ENTRY_COUNT + page.p1_index()); return Some(start_frame_number + page.p2_index() * ENTRY_COUNT + page.p1_index());
@@ -25,7 +25,7 @@ fn translate_page(page: Page) -> Option<Frame> {
if let Some(p2) = p3.next_table(page.p3_index()) { if let Some(p2) = p3.next_table(page.p3_index()) {
// 2MiB page? // 2MiB page?
if p2[page.p2_index()].flags().contains(HUGE_PAGE | PRESENT) { 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 // address must be 2MiB aligned
assert!(start_frame_number % ENTRY_COUNT == 0); assert!(start_frame_number % ENTRY_COUNT == 0);
return Some(start_frame_number + page.p1_index()); return Some(start_frame_number + page.p1_index());
@@ -39,6 +39,6 @@ fn translate_page(page: Page) -> Option<Frame> {
p4.next_table(page.p4_index()) p4.next_table(page.p4_index())
.and_then(|p3| p3.next_table(page.p3_index())) .and_then(|p3| p3.next_table(page.p3_index()))
.and_then(|p2| p2.next_table(page.p2_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) .or_else(huge_page)
} }