diff --git a/src/memory/paging/mod.rs b/src/memory/paging/mod.rs index f977b513..c991fba5 100644 --- a/src/memory/paging/mod.rs +++ b/src/memory/paging/mod.rs @@ -57,61 +57,59 @@ impl RecursivePageTable { fn p4_mut(&mut self) -> &mut Table { unsafe { self.p4.get_mut() } } -} -pub unsafe fn translate(virtual_address: VirtualAddress) -> Option { - let offset = virtual_address % PAGE_SIZE; - translate_page(Page::containing_address(virtual_address)) - .map(|frame| frame.number * PAGE_SIZE + offset) -} + pub fn translate(&self, virtual_address: VirtualAddress) -> Option { + let offset = virtual_address % PAGE_SIZE; + self.translate_page(Page::containing_address(virtual_address)) + .map(|frame| frame.number * PAGE_SIZE + offset) + } -unsafe fn translate_page(page: Page) -> Option { + fn translate_page(&self, page: Page) -> Option { + let p3 = self.p4().next_table(page.p4_index()); - let p3 = unsafe { &*table::P4 }.next_table(page.p4_index()); - - let huge_page = || { - p3.and_then(|p3| { - let p3_entry = &p3[page.p3_index()]; - // 1GiB page? - if let Some(start_frame) = p3_entry.pointed_frame() { - if p3_entry.flags().contains(HUGE_PAGE) { - // address must be 1GiB aligned - assert!(start_frame.number % (ENTRY_COUNT * ENTRY_COUNT) == 0); - return Some(Frame { - number: start_frame.number + page.p2_index() * ENTRY_COUNT + - page.p1_index(), - }); - } - } - if let Some(p2) = p3.next_table(page.p3_index()) { - let p2_entry = &p2[page.p2_index()]; - // 2MiB page? - if let Some(start_frame) = p2_entry.pointed_frame() { - if p2_entry.flags().contains(HUGE_PAGE) { - // address must be 2MiB aligned - assert!(start_frame.number % ENTRY_COUNT == 0); - return Some(Frame { number: start_frame.number + page.p1_index() }); + let huge_page = || { + p3.and_then(|p3| { + let p3_entry = &p3[page.p3_index()]; + // 1GiB page? + if let Some(start_frame) = p3_entry.pointed_frame() { + if p3_entry.flags().contains(HUGE_PAGE) { + // address must be 1GiB aligned + assert!(start_frame.number % (ENTRY_COUNT * ENTRY_COUNT) == 0); + return Some(Frame { + number: start_frame.number + page.p2_index() * ENTRY_COUNT + + page.p1_index(), + }); } } - } - None - }) - }; + if let Some(p2) = p3.next_table(page.p3_index()) { + let p2_entry = &p2[page.p2_index()]; + // 2MiB page? + if let Some(start_frame) = p2_entry.pointed_frame() { + if p2_entry.flags().contains(HUGE_PAGE) { + // address must be 2MiB aligned + assert!(start_frame.number % ENTRY_COUNT == 0); + return Some(Frame { number: start_frame.number + page.p1_index() }); + } + } + } + None + }) + }; - p3.and_then(|p3| p3.next_table(page.p3_index())) - .and_then(|p2| p2.next_table(page.p2_index())) - .and_then(|p1| p1[page.p1_index()].pointed_frame()) - .or_else(huge_page) -} - -pub unsafe fn map_to(page: Page, frame: Frame, flags: EntryFlags, allocator: &mut A) - where A: FrameAllocator -{ - let p4 = unsafe { &mut *table::P4 }; - let mut p3 = p4.next_table_create(page.p4_index(), allocator); - let mut p2 = p3.next_table_create(page.p3_index(), allocator); - let mut p1 = p2.next_table_create(page.p2_index(), allocator); - - assert!(p1[page.p1_index()].is_unused()); - p1[page.p1_index()].set(frame, flags | PRESENT); + p3.and_then(|p3| p3.next_table(page.p3_index())) + .and_then(|p2| p2.next_table(page.p2_index())) + .and_then(|p1| p1[page.p1_index()].pointed_frame()) + .or_else(huge_page) + } + + pub fn map_to(&mut self, page: Page, frame: Frame, flags: EntryFlags, allocator: &mut A) + where A: FrameAllocator + { + let mut p3 = self.p4_mut().next_table_create(page.p4_index(), allocator); + let mut p2 = p3.next_table_create(page.p3_index(), allocator); + let mut p1 = p2.next_table_create(page.p2_index(), allocator); + + assert!(p1[page.p1_index()].is_unused()); + p1[page.p1_index()].set(frame, flags | PRESENT); + } }