mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-16 14:27:49 +00:00
Modify pointed_frame to return an Option
This commit is contained in:
@@ -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<Frame> {
|
||||
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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -17,7 +17,7 @@ fn translate_page(page: Page) -> Option<Frame> {
|
||||
.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<Frame> {
|
||||
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<Frame> {
|
||||
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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user