diff --git a/crate/riscv b/crate/riscv index a1c8988..71d108e 160000 --- a/crate/riscv +++ b/crate/riscv @@ -1 +1 @@ -Subproject commit a1c8988d371710186398376d69da57221231b110 +Subproject commit 71d108e50cfa006464782a725621ae760f69f90f diff --git a/kernel/Makefile b/kernel/Makefile index 2ca538a..16d20f9 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -164,7 +164,7 @@ else --disable-fp-emulation \ --host=riscv32-unknown-elf \ --with-payload=$(abspath $(kernel)) && \ - make && \ + make -j32 && \ cp bbl ../../kernel/$@ endif else ifeq ($(arch), aarch64) diff --git a/kernel/src/arch/riscv32/paging.rs b/kernel/src/arch/riscv32/paging.rs index abe95e7..9d6d9ff 100644 --- a/kernel/src/arch/riscv32/paging.rs +++ b/kernel/src/arch/riscv32/paging.rs @@ -40,8 +40,7 @@ impl PageTable for ActivePageTable { // map the page to the frame using FrameAllocatorForRiscv // we may need frame allocator to alloc frame for new page table(first/second) info!("ActivePageTable: calling RecursivePageTable::map_to, va={:x}, pa={:x}, flags={:?}", page.start_address().as_usize(), frame.start_address().as_usize(), flags); - self.0.map_to(page, frame, flags, &mut FrameAllocatorForRiscv) - .unwrap().flush(); + self.0.map_to(page, frame, flags, &mut FrameAllocatorForRiscv).unwrap().flush(); self.get_entry(addr).expect("fail to get entry") } @@ -88,50 +87,16 @@ impl PageTable for ActivePageTable { #[cfg(target_arch = "riscv64")] fn get_entry(&mut self, vaddr: usize) -> Option<&mut PageEntry> { let vaddr = VirtAddr::new(vaddr); - let root_table: &RvPageTable = unsafe { &*ROOT_PAGE_TABLE }; + let page = Page::of_addr(vaddr); - let p3_table = if ! root_table[vaddr.p4_index()].flags().contains(EF::VALID) { - return None - } else { - let p3_table = unsafe { &mut *(Page::from_page_table_indices( - self.0.recursive_index, - self.0.recursive_index, - self.0.recursive_index, - vaddr.p4_index()).start_address().as_usize() as *mut RvPageTable) }; - p3_table - }; - - let p2_table = if ! p3_table[vaddr.p3_index()].flags().contains(EF::VALID) { - return None - } else { - let p2_table = unsafe { &mut *(Page::from_page_table_indices( - self.0.recursive_index, - self.0.recursive_index, - vaddr.p4_index(), - vaddr.p3_index()).start_address().as_usize() as *mut RvPageTable) }; - p2_table - }; - - let p1_table = if ! p2_table[vaddr.p2_index()].flags().contains(EF::VALID) { - return None - } else { - let p1_table = unsafe { &mut *(Page::from_page_table_indices( - self.0.recursive_index, - vaddr.p4_index(), - vaddr.p3_index(), - vaddr.p2_index()).start_address().as_usize() as *mut RvPageTable) }; - p1_table - }; + if ! self.0.is_mapped( + vaddr.p4_index(), vaddr.p3_index(), vaddr.p2_index(), vaddr.p1_index()) { + return None; + } - let page = Page::of_addr(vaddr); - // ??? - self.0.translate_page(page); - let entry_va = VirtAddr::from_page_table_indices(RECURSIVE_INDEX, - vaddr.p4_index(), - vaddr.p3_index(), - vaddr.p2_index(), - vaddr.p1_index() << 3); - unsafe { Some(&mut *(entry_va.as_usize() as *mut PageEntry)) } + let entry = edit_entry_of(&page, |entry| *entry); + self.1 = PageEntry(entry, page); + Some(&mut self.1) } @@ -145,7 +110,9 @@ impl PageTable for ActivePageTable { */ fn get_page_slice_mut<'a, 'b>(&'a mut self, addr: usize) -> &'b mut [u8] { use core::slice; - unsafe { slice::from_raw_parts_mut((addr & !(PAGE_SIZE - 1)) as *mut u8, PAGE_SIZE) } + unsafe { + slice::from_raw_parts_mut((addr & !(PAGE_SIZE - 1)) as *mut u8, PAGE_SIZE) + } } /* @@ -173,16 +140,64 @@ impl PageTable for ActivePageTable { #[cfg(target_arch = "riscv32")] fn edit_entry_of(page: &Page, f: impl FnOnce(&mut PageTableEntry) -> T) -> T { - let p2_flags = unsafe { (*ROOT_PAGE_TABLE)[page.p2_index()].flags_mut() }; + let p2_table = unsafe { ROOT_PAGE_TABLE.as_mut().unwrap() }; + let p1_table = unsafe { + &mut *(Page::from_page_table_indices(RECURSIVE_INDEX, page.p2_index()). + start_address().as_usize() as *mut RvPageTable) + }; + let p2_flags = p2_table[page.p2_index()].flags_mut(); + p2_flags.insert(EF::READABLE | EF::WRITABLE); - let entry_addr = (RECURSIVE_INDEX << 22) | (page.p2_index() << 12) | (page.p1_index() << 2); - let entry = unsafe { &mut *(entry_addr as *mut PageTableEntry) }; - let ret = f(entry); + let ret = f(&mut p1_table[page.p1_index()]); p2_flags.remove(EF::READABLE | EF::WRITABLE); + + ret +} + +// TODO: better the gofy design +#[cfg(target_arch = "riscv64")] +fn edit_entry_of(page: &Page, f: impl FnOnce(&mut PageTableEntry) -> T) -> T { + let p4_table = unsafe { ROOT_PAGE_TABLE.as_mut().unwrap() }; + let p3_table = unsafe { + &mut *(Page::from_page_table_indices( + RECURSIVE_INDEX, RECURSIVE_INDEX, RECURSIVE_INDEX, + page.p4_index()).start_address().as_usize() as *mut RvPageTable) + }; + let p2_table = unsafe { + &mut *(Page::from_page_table_indices( + RECURSIVE_INDEX, RECURSIVE_INDEX, page.p4_index(), + page.p3_index()).start_address().as_usize() as *mut RvPageTable) + }; + let p1_table = unsafe { + &mut *(Page::from_page_table_indices( + RECURSIVE_INDEX, page.p4_index(), page.p3_index(), + page.p2_index()).start_address().as_usize() as *mut RvPageTable) + }; + let p4_flags = p4_table[page.p4_index()].flags_mut(); + let p3_flags = p3_table[page.p3_index()].flags_mut(); + let p2_flags = p2_table[page.p2_index()].flags_mut(); + + p4_flags.insert(EF::READABLE | EF::WRITABLE) ; sfence_vma_all(); + p3_flags.insert(EF::READABLE | EF::WRITABLE) ; sfence_vma_all(); + p4_flags.remove(EF::READABLE | EF::WRITABLE) ; sfence_vma_all(); + p2_flags.insert(EF::READABLE | EF::WRITABLE) ; sfence_vma_all(); + p4_flags.insert(EF::READABLE | EF::WRITABLE) ; sfence_vma_all(); + p3_flags.remove(EF::READABLE | EF::WRITABLE) ; sfence_vma_all(); + p4_flags.remove(EF::READABLE | EF::WRITABLE) ; sfence_vma_all(); + let ret = f(&mut p1_table[page.p1_index()]) ; + p4_flags.insert(EF::READABLE | EF::WRITABLE) ; sfence_vma_all(); + p3_flags.insert(EF::READABLE | EF::WRITABLE) ; sfence_vma_all(); + p4_flags.remove(EF::READABLE | EF::WRITABLE) ; sfence_vma_all(); + p2_flags.remove(EF::READABLE | EF::WRITABLE) ; sfence_vma_all(); + p4_flags.insert(EF::READABLE | EF::WRITABLE) ; sfence_vma_all(); + p3_flags.remove(EF::READABLE | EF::WRITABLE) ; sfence_vma_all(); + p4_flags.remove(EF::READABLE | EF::WRITABLE) ; sfence_vma_all(); + ret } + // define the ROOT_PAGE_TABLE, and the virtual address of it? #[cfg(target_arch = "riscv32")] const ROOT_PAGE_TABLE: *mut RvPageTable = @@ -221,10 +236,10 @@ impl ActivePageTable { info!("translate page begin, self at {:x}, page: {:x} ({:o}, {:o}, {:o}, {:o})", (self.0.root_table as *const _ as usize), - page.start_address().as_usize(), - page.p4_index(), - page.p3_index(), - page.p2_index(), + page.start_address().as_usize(), + page.p4_index(), + page.p3_index(), + page.p2_index(), page.p1_index() ); info!("self info: recursive_index={:x}", self.0.recursive_index); @@ -268,6 +283,7 @@ impl ActivePageTable { impl Entry for PageEntry { #[cfg(target_arch = "riscv64")] fn update(&mut self) { + assert!(false, "can't update"); let mut addr: usize = (self as *const _ as usize) << 9; if (addr & 0x7000_0000_0000 != 0) { addr |= 0xFFFF_0000_0000_0000; @@ -360,7 +376,7 @@ impl InactivePageTable for InactivePageTable0 { * @param: * f: a function to do something with the temporary modified activate page table * @brief: - * temporarily make current `active_table`'s recursive entry point to + * temporarily make current `active_table`'s recursive entry point to * `this` inactive table, so we can modify this inactive page table. */ fn edit(&mut self, f: impl FnOnce(&mut Self::Active)) {