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)
|
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) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user