diff --git a/src/memory/paging_old.rs b/src/memory/paging_old.rs deleted file mode 100644 index e2b44a05..00000000 --- a/src/memory/paging_old.rs +++ /dev/null @@ -1,276 +0,0 @@ -use super::{VirtualAddress, Frame, PAGE_SIZE, FrameStack}; -use core::ops::Deref; - -//pub type FrameAllocator = super::FrameStack; -pub type Page = super::Page; - -bitflags! { - flags PageTableFieldFlags: u64 { - const PRESENT = 1 << 0, - const WRITABLE = 1 << 1, - const USER_ACCESSIBLE = 1 << 2, - const WRITE_THROUGH = 1 << 3, - const NO_CACHE = 1 << 4, - const ACCESSED = 1 << 5, - const DIRTY = 1 << 6, - const OTHER1 = 1 << 9, - const OTHER2 = 1 << 10, - const NO_EXECUTE = 1 << 63, - } -} - -pub struct Controller { - allocator: A, -} - -impl Controller where A: FrameStack { - pub unsafe fn new(allocator: A) -> Controller { - Controller { - allocator: allocator, - } - } - - pub fn map_to(&mut self, page: Page, frame:Frame, writable: bool, executable: bool) { - Self::map_to_static(page, frame, writable, executable, &mut self.allocator) - } - - pub fn identity_map(&mut self, page: Page, writable: bool, executable: bool) { - self.map_to(page, Frame{number: page.number}, writable, executable) - } - - pub fn map(&mut self, page: Page, writable: bool, executable: bool) { - let frame = self.allocate_frame(); - self.map_to(page, frame, writable, executable) - } - - pub fn unmap(&mut self, page: Page) -> Frame { - page.unmap() - } - - pub fn begin_new_table(&mut self) { - let new_p4_frame = self.allocate_frame(); - let new_p4_page = &mut PageTablePage(Page{number: new_p4_frame.number}); - unsafe{new_p4_page.zero()}; - new_p4_page.field(511).set(new_p4_frame, PRESENT | WRITABLE); - - let old_p4_page = &mut PageTablePage(Page{number: 0o777_777_777_777}); - old_p4_page.field(511).set(new_p4_frame, PRESENT | WRITABLE); - - Self::flush_tlb(); - } - - pub fn activate_new_table(&mut self) { - unsafe { - let p4_address: u64 = { - let field = *(0xfffffffffffffff8 as *const u64); - field & !0xfff - }; - - asm!("mov cr3, $0" :: "r"(p4_address) :: "intel") - } - } - - pub unsafe fn add_free_frame(&mut self, frame: Frame) { - self.allocator.push(frame, Self::map_to_static) - } - - fn allocate_frame(&mut self) -> Frame { - Self::allocate_frame_static(&mut self.allocator) - } - - fn allocate_frame_static(allocator: &mut A) -> Frame { - let unmap_page = |page: Page| { - page.unmap() - }; - allocator.pop(unmap_page).expect("no more frames available") - } - - fn map_to_static(page: Page, frame: Frame, writable: bool, executable: bool, allocator: &mut A) { - let mut flags = PRESENT; - if writable { - flags = flags | WRITABLE; - } - if !executable { - flags = flags | NO_EXECUTE; - } - - page.map_to(frame, flags, || {Self::allocate_frame_static(allocator)}) - } - - fn flush_tlb() { - unsafe{asm!("mov rax, cr3 - mov cr3, rax" ::: "{rax}" : "intel")} - } -} - -// first allocated address starts on second P4-Page -pub const FIRST_PAGE : Page = Page { - number: 0o_001_000_000_000, -}; - -// a page containing a page table -struct PageTablePage(Page); - -struct PageIter(Page); - -struct PageTableField(*const u64); - -impl Page { - pub fn is_free(&self) -> bool { - let p4_field = self.p4_page().field(self.p4_index()); - let p3_field = self.p3_page().field(self.p3_index()); - let p2_field = self.p2_page().field(self.p2_index()); - let p1_field = self.p1_page().field(self.p1_index()); - p4_field.is_free() || p3_field.is_free() || p2_field.is_free() || p1_field.is_free() - } - - fn from_address(address: &VirtualAddress) -> Page { - Page { - number: address.0 as usize >> 12, - } - } - - pub fn start_address(&self) -> VirtualAddress { - if self.number >= 0o400_000_000_000 { - //sign extension - VirtualAddress(((self.number << 12) | 0o177777_000_000_000_000_0000) as *const u8) - } else { - VirtualAddress((self.number << 12) as *const u8) - } - } - - fn p4_index(&self) -> usize {(self.number >> 27) & 0o777} - fn p3_index(&self) -> usize {(self.number >> 18) & 0o777} - fn p2_index(&self) -> usize {(self.number >> 9) & 0o777} - fn p1_index(&self) -> usize {(self.number >> 0) & 0o777} - - fn p4_page(&self) -> PageTablePage { - PageTablePage(Page { - number: 0o_777_777_777_777, - }) - } - fn p3_page(&self) -> PageTablePage { - PageTablePage(Page { - number: 0o_777_777_777_000 | self.p4_index(), - }) - } - fn p2_page(&self) -> PageTablePage { - PageTablePage(Page { - number: 0o_777_777_000_000 | (self.p4_index() << 9) | self.p3_index(), - }) - } - fn p1_page(&self) -> PageTablePage { - PageTablePage(Page { - number: 0o_777_000_000_000 | (self.p4_index() << 18) | (self.p3_index() << 9) - | self.p2_index(), - }) - } - - fn map_to(&self, frame: Frame, flags: PageTableFieldFlags, mut allocate_frame: F) - where F: FnMut() -> Frame, - { - let p4_field = self.p4_page().field(self.p4_index()); - if p4_field.is_free() { - p4_field.set(allocate_frame(), PRESENT | WRITABLE); - unsafe{self.p3_page().zero()}; - } - let p3_field = self.p3_page().field(self.p3_index()); - if p3_field.is_free() { - p3_field.set(allocate_frame(), PRESENT | WRITABLE); - unsafe{self.p2_page().zero()}; - } - let p2_field = self.p2_page().field(self.p2_index()); - if p2_field.is_free() { - p2_field.set(allocate_frame(), PRESENT | WRITABLE); - unsafe{self.p1_page().zero()}; - } - let p1_field = self.p1_page().field(self.p1_index()); - //TODOassert!(p1_field.is_free()); - p1_field.set(frame, flags); - } - - fn unmap(self) -> Frame { - let p1_field = self.p1_page().field(self.p1_index()); - let frame = p1_field.pointed_frame(); - p1_field.set_free(); - // TODO free p(1,2,3) table if empty - frame - } - - unsafe fn zero(&self) { - let page = self.start_address().0 as *mut [u64; (PAGE_SIZE/64) as usize]; - *page = [0; (PAGE_SIZE/64) as usize]; - } - - pub fn next_pages(self) -> PageIter { - PageIter(self) - } -} - -impl Iterator for PageIter { - type Item = Page; - - fn next(&mut self) -> Option { - self.0.number += 1; - Some(self.0) - } -} - -impl PageTablePage { - fn field(&self, index: usize) -> PageTableField { - //print!("index: {} pointer: {:o}\n", index, self.0.start_address().0 as usize + (index * 8)); - PageTableField((self.0.start_address().0 as usize + (index * 8)) as *const u64) - } -} - -impl Deref for PageTablePage { - type Target = Page; - fn deref(&self) -> &Page { &self.0 } -} - -impl VirtualAddress { - pub fn page(&self) -> Page { - Page::from_address(self) - } - - fn page_offset(&self) -> u32 { - self.0 as u32 & 0xfff - } -} - -impl PageTableField { - fn is(&self, flags: PageTableFieldFlags) -> bool { - PageTableFieldFlags::from_bits_truncate(unsafe{*(self.0)}).contains(flags) - } - - fn add_flag(&self, flags: PageTableFieldFlags) { - unsafe{*(self.0 as *mut u64) |= flags.bits}; - } - - fn remove_flag(&self, flags: PageTableFieldFlags) { - unsafe{*(self.0 as *mut u64) &= !flags.bits}; - } - - fn is_free(&self) -> bool { - //TODO - let f = unsafe{*self.0}; - let free = f == 0; - free - } - - fn set_free(&self) { - //TODO - unsafe{ *(self.0 as *mut _)= 0 }; - } - - fn pointed_frame(&self) -> Frame { - Frame { - number: ((unsafe{(*self.0)} & 0x000fffff_fffff000) >> 12) as usize, - } - } - - fn set(&self, frame: Frame, flags: PageTableFieldFlags) { - let new = (((frame.number as u64) << 12) & 0x000fffff_fffff000) | flags.bits(); - unsafe{*(self.0 as *mut u64) = new}; - } -}