From 05f9327272cd2dd74bbe810a30283f223cd2ec6e Mon Sep 17 00:00:00 2001 From: Yuhao Zhou Date: Fri, 5 Apr 2019 12:38:26 +0800 Subject: [PATCH] Update mips paging.rs. --- kernel/src/arch/mipsel/interrupt.rs | 4 +- kernel/src/arch/mipsel/mod.rs | 2 +- kernel/src/arch/mipsel/paging.rs | 158 ++++++---------------------- 3 files changed, 36 insertions(+), 128 deletions(-) diff --git a/kernel/src/arch/mipsel/interrupt.rs b/kernel/src/arch/mipsel/interrupt.rs index f6bea8a6..2d356b09 100644 --- a/kernel/src/arch/mipsel/interrupt.rs +++ b/kernel/src/arch/mipsel/interrupt.rs @@ -1,5 +1,5 @@ -use mips::interrupts::*; -use mips::registers::*; +use mips::interrupts; +use mips::registers::cp0; use crate::drivers::DRIVERS; pub use self::context::*; use log::*; diff --git a/kernel/src/arch/mipsel/mod.rs b/kernel/src/arch/mipsel/mod.rs index bb3d87f3..f2f5dd24 100644 --- a/kernel/src/arch/mipsel/mod.rs +++ b/kernel/src/arch/mipsel/mod.rs @@ -10,7 +10,7 @@ pub mod syscall; pub mod rand; use log::*; -use mips::registers; +use mips::registers::cp0; use mips::instructions; extern "C" { diff --git a/kernel/src/arch/mipsel/paging.rs b/kernel/src/arch/mipsel/paging.rs index a392865a..79318ecb 100644 --- a/kernel/src/arch/mipsel/paging.rs +++ b/kernel/src/arch/mipsel/paging.rs @@ -1,19 +1,15 @@ -use crate::consts::RECURSIVE_INDEX; // Depends on kernel use crate::memory::{active_table, alloc_frame, dealloc_frame}; -use riscv::addr::*; -use riscv::asm::{sfence_vma, sfence_vma_all}; -use riscv::paging::{Mapper, PageTable as RvPageTable, PageTableEntry, PageTableFlags as EF, RecursivePageTable, PageTableType}; -use riscv::paging::{FrameAllocator, FrameDeallocator}; -use riscv::register::satp; +use mips::addr::*; +use mips::tlb::*; +use mips::paging::{Mapper, PageTable as MIPSPageTable, PageTableEntry, PageTableFlags as EF, TwoLevelPageTable}; +use mips::paging::{FrameAllocator, FrameDeallocator}; use rcore_memory::paging::*; use log::*; #[cfg(target_arch = "riscv32")] use crate::consts::KERNEL_P2_INDEX; -#[cfg(target_arch = "riscv64")] -use crate::consts::KERNEL_P4_INDEX; -pub struct ActivePageTable(RecursivePageTable<'static>, PageEntry); +pub struct ActivePageTable(TwoLevelPageTable<'static>, PageEntry); /// PageTableEntry: the contents of this entry. /// Page: this entry is the pte of page `Page`. @@ -22,9 +18,8 @@ pub struct PageEntry(&'static mut PageTableEntry, Page); impl PageTable for ActivePageTable { fn map(&mut self, addr: usize, target: usize) -> &mut Entry { - // use riscv::paging:Mapper::map_to, // map the 4K `page` to the 4K `frame` with `flags` - let flags = EF::VALID | EF::READABLE | EF::WRITABLE; + let flags = EF::VALID | EF::WRITABLE | EF::CACHEABLE; let page = Page::of_addr(VirtAddr::new(addr)); let frame = Frame::of_addr(PhysAddr::new(target)); // map the page to the frame using FrameAllocatorForRiscv @@ -54,41 +49,14 @@ impl PageTable for ActivePageTable { impl PageTableExt for ActivePageTable {} /// The virtual address of root page table -#[cfg(target_arch = "riscv32")] -const ROOT_PAGE_TABLE: *mut RvPageTable = - ((RECURSIVE_INDEX << 12 << 10) | - ((RECURSIVE_INDEX+1) << 12)) as *mut RvPageTable; -#[cfg(all(target_arch = "riscv64", feature = "sv39"))] -const ROOT_PAGE_TABLE: *mut RvPageTable = - ((0xFFFF_0000_0000_0000) | - (0o777 << 12 << 9 << 9 << 9) | - (RECURSIVE_INDEX << 12 << 9 << 9) | - (RECURSIVE_INDEX << 12 << 9) | - ((RECURSIVE_INDEX+1) << 12)) as *mut RvPageTable; -#[cfg(all(target_arch = "riscv64", not(feature = "sv39")))] -const ROOT_PAGE_TABLE: *mut RvPageTable = - ((0xFFFF_0000_0000_0000) | - (RECURSIVE_INDEX << 12 << 9 << 9 << 9) | - (RECURSIVE_INDEX << 12 << 9 << 9) | - (RECURSIVE_INDEX << 12 << 9) | - ((RECURSIVE_INDEX+1) << 12)) as *mut RvPageTable; +static ROOT_PAGE_TABLE_BUFFER: MIPSPageTable = ::core::mem::uninitialized(); +static mut root_page_table_ptr: usize = + &ROOT_PAGE_TABLE_BUFFER as *const MIPSPageTable as usize; impl ActivePageTable { - #[cfg(target_arch = "riscv32")] pub unsafe fn new() -> Self { ActivePageTable( - RecursivePageTable::new(&mut *ROOT_PAGE_TABLE).unwrap(), - ::core::mem::uninitialized() - ) - } - #[cfg(target_arch = "riscv64")] - pub unsafe fn new() -> Self { - #[cfg(feature = "sv39")] - let type_ = PageTableType::Sv39; - #[cfg(not(feature = "sv39"))] - let type_ = PageTableType::Sv48; - ActivePageTable( - RecursivePageTable::new(&mut *ROOT_PAGE_TABLE, type_).unwrap(), + TwoLevelPageTable::new(&mut ROOT_PAGE_TABLE_BUFFER), ::core::mem::uninitialized() ) } @@ -97,36 +65,32 @@ impl ActivePageTable { /// implementation for the Entry trait in /crate/memory/src/paging/mod.rs impl Entry for PageEntry { fn update(&mut self) { - unsafe { sfence_vma(0, self.1.start_address().as_usize()); } + unsafe { clear_all_tlb(); } } fn accessed(&self) -> bool { self.0.flags().contains(EF::ACCESSED) } fn dirty(&self) -> bool { self.0.flags().contains(EF::DIRTY) } fn writable(&self) -> bool { self.0.flags().contains(EF::WRITABLE) } - fn present(&self) -> bool { self.0.flags().contains(EF::VALID | EF::READABLE) } + fn present(&self) -> bool { self.0.flags().contains(EF::VALID) } fn clear_accessed(&mut self) { self.0.flags_mut().remove(EF::ACCESSED); } fn clear_dirty(&mut self) { self.0.flags_mut().remove(EF::DIRTY); } fn set_writable(&mut self, value: bool) { self.0.flags_mut().set(EF::WRITABLE, value); } - fn set_present(&mut self, value: bool) { self.0.flags_mut().set(EF::VALID | EF::READABLE, value); } + fn set_present(&mut self, value: bool) { self.0.flags_mut().set(EF::VALID, value); } fn target(&self) -> usize { self.0.addr().as_usize() } fn set_target(&mut self, target: usize) { let flags = self.0.flags(); let frame = Frame::of_addr(PhysAddr::new(target)); self.0.set(frame, flags); } - fn writable_shared(&self) -> bool { self.0.flags().contains(EF::RESERVED1) } - fn readonly_shared(&self) -> bool { self.0.flags().contains(EF::RESERVED2) } - fn set_shared(&mut self, writable: bool) { - let flags = self.0.flags_mut(); - flags.set(EF::RESERVED1, writable); - flags.set(EF::RESERVED2, !writable); - } - fn clear_shared(&mut self) { self.0.flags_mut().remove(EF::RESERVED1 | EF::RESERVED2); } + fn writable_shared(&self) -> bool { false } + fn readonly_shared(&self) -> bool { false } + fn set_shared(&mut self, writable: bool) { } + fn clear_shared(&mut self) { } fn swapped(&self) -> bool { self.0.flags().contains(EF::RESERVED1) } fn set_swapped(&mut self, value: bool) { self.0.flags_mut().set(EF::RESERVED1, value); } - fn user(&self) -> bool { self.0.flags().contains(EF::USER) } - fn set_user(&mut self, value: bool) { self.0.flags_mut().set(EF::USER, value); } - fn execute(&self) -> bool { self.0.flags().contains(EF::EXECUTABLE) } - fn set_execute(&mut self, value: bool) { self.0.flags_mut().set(EF::EXECUTABLE, value); } + fn user(&self) -> bool { true } + fn set_user(&mut self, value: bool) { } + fn execute(&self) -> bool { true } + fn set_execute(&mut self, value: bool) { } fn mmio(&self) -> u8 { 0 } fn set_mmio(&mut self, _value: u8) { } } @@ -142,93 +106,37 @@ impl InactivePageTable for InactivePageTable0 { fn new_bare() -> Self { let target = alloc_frame().expect("failed to allocate frame"); let frame = Frame::of_addr(PhysAddr::new(target)); - active_table().with_temporary_map(target, |_, table: &mut RvPageTable| { + active_table().with_temporary_map(target, |_, table: &mut MIPSPageTable| { table.zero(); - table.set_recursive(RECURSIVE_INDEX, frame.clone()); }); InactivePageTable0 { root_frame: frame } } - #[cfg(target_arch = "riscv32")] - fn map_kernel(&mut self) { - let table = unsafe { &mut *ROOT_PAGE_TABLE }; - extern { - fn start(); - fn end(); - } - let mut entrys: [PageTableEntry; 16] = unsafe { core::mem::uninitialized() }; - let entry_start = start as usize >> 22; - let entry_end = (end as usize >> 22) + 1; - let entry_count = entry_end - entry_start; - for i in 0..entry_count { - entrys[i] = table[entry_start + i]; - } + fn map_kernel(&mut self) { /* nothing to do */ } - self.edit(|_| { - // NOTE: 'table' now refers to new page table - for i in 0..entry_count { - table[entry_start + i] = entrys[i]; - } - }); - } - - #[cfg(target_arch = "riscv64")] - fn map_kernel(&mut self) { - let table = unsafe { &mut *ROOT_PAGE_TABLE }; - let e1 = table[KERNEL_P4_INDEX]; - assert!(!e1.is_unused()); - - self.edit(|_| { - table[KERNEL_P4_INDEX] = e1; - }); - } - - #[cfg(target_arch = "riscv32")] fn token(&self) -> usize { - self.root_frame.number() | (1 << 31) // as satp - } - #[cfg(target_arch = "riscv64")] - fn token(&self) -> usize { - use bit_field::BitField; - let mut satp = self.root_frame.number(); - satp.set_bits(44..60, 0); // AS is 0 - #[cfg(feature = "sv39")] - satp.set_bits(60..64, satp::Mode::Sv39 as usize); - #[cfg(not(feature = "sv39"))] - satp.set_bits(60..64, satp::Mode::Sv48 as usize); - satp + self.root_frame.to_kernel_unmapped().as_usize() } unsafe fn set_token(token: usize) { - asm!("csrw satp, $0" :: "r"(token) :: "volatile"); + root_page_table_ptr = token; } fn active_token() -> usize { - satp::read().bits() + root_page_table_ptr } fn flush_tlb() { - unsafe { sfence_vma_all(); } + unsafe { clear_all_tlb(); } } fn edit(&mut self, f: impl FnOnce(&mut Self::Active) -> T) -> T { - let target = satp::read().frame().start_address().as_usize(); - active_table().with_temporary_map(target, |active_table, root_table: &mut RvPageTable| { - let backup = root_table[RECURSIVE_INDEX].clone(); - - // overwrite recursive mapping - root_table[RECURSIVE_INDEX].set(self.root_frame.clone(), EF::VALID); - unsafe { sfence_vma_all(); } - - // execute f in the new context - let ret = f(active_table); - - // restore recursive mapping to original p2 table - root_table[RECURSIVE_INDEX] = backup; - unsafe { sfence_vma_all(); } - - ret - }) + let pt: *MIPSPageTable = self.token() as *MIPSPageTable; + let active = ActivePageTable( + TwoLevelPageTable::new(&mut *pt), + ::core::mem::uninitialized() + ); + f(&mut active) } }