diff --git a/crate/memory/src/no_mmu.rs b/crate/memory/src/no_mmu.rs index 1fe2123..8d2f966 100644 --- a/crate/memory/src/no_mmu.rs +++ b/crate/memory/src/no_mmu.rs @@ -3,7 +3,7 @@ use alloc::alloc::{Layout, GlobalAlloc}; use core::marker::PhantomData; pub trait NoMMUSupport { - type Alloc: GlobalAlloc; + type Alloc: GlobalAlloc + 'static; fn allocator() -> &'static Self::Alloc; } diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index 1d428c4..9f3cb58 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -307,7 +307,7 @@ dependencies = [ [[package]] name = "riscv" version = "0.3.0" -source = "git+https://github.com/riscv-and-rust-and-decaf/riscv#f7bea54d7f254b63b5a6130285ab421c23d2f3bd" +source = "git+https://github.com/riscv-and-rust-and-decaf/riscv#f6f475e35b36717cf4455e298e4468773a57eb84" dependencies = [ "bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/kernel/build-rv64 b/kernel/build-rv64 index bde489c..eb91e79 100755 --- a/kernel/build-rv64 +++ b/kernel/build-rv64 @@ -553,7 +553,7 @@ fi CNAME=riscv if ! [[ -f ${OUTDIR}/${CNAME}.o ]] then -rustc --crate-name riscv $CARGO_PATH/git/checkouts/riscv-1e845b622ce46f1d/f7bea54*/src/lib.rs \ +rustc --crate-name riscv $CARGO_PATH/git/checkouts/riscv-1e845b622ce46f1d/f6f475e*/src/lib.rs \ --color always --crate-type lib --emit=metadata,llvm-bc \ -C opt-level=1 \ -C debuginfo=2 \ diff --git a/kernel/src/arch/riscv32/board/u540/linker.ld b/kernel/src/arch/riscv32/board/u540/linker.ld index 454effa..6bbe85b 100644 --- a/kernel/src/arch/riscv32/board/u540/linker.ld +++ b/kernel/src/arch/riscv32/board/u540/linker.ld @@ -6,7 +6,7 @@ OUTPUT_ARCH(riscv) ENTRY(_start) -BASE_ADDRESS = 0xffffffff80020000; +BASE_ADDRESS = 0xffffffffc0020000; SECTIONS { diff --git a/kernel/src/arch/riscv32/boot/linker.ld b/kernel/src/arch/riscv32/boot/linker.ld index d51cbe8..bc3ba7f 100644 --- a/kernel/src/arch/riscv32/boot/linker.ld +++ b/kernel/src/arch/riscv32/boot/linker.ld @@ -6,11 +6,11 @@ OUTPUT_ARCH(riscv) ENTRY(_start) -BASE_ADDRESS = 0x80020000; +BASE_ADDRESS = 0xC0020000; SECTIONS { - . = 0x80000000; + . = 0xC0000000; .boot : { KEEP(*(.text.boot)) } diff --git a/kernel/src/arch/riscv32/boot/linker64.ld b/kernel/src/arch/riscv32/boot/linker64.ld index 454effa..6bbe85b 100644 --- a/kernel/src/arch/riscv32/boot/linker64.ld +++ b/kernel/src/arch/riscv32/boot/linker64.ld @@ -6,7 +6,7 @@ OUTPUT_ARCH(riscv) ENTRY(_start) -BASE_ADDRESS = 0xffffffff80020000; +BASE_ADDRESS = 0xffffffffc0020000; SECTIONS { diff --git a/kernel/src/arch/riscv32/compiler_rt.rs b/kernel/src/arch/riscv32/compiler_rt.rs index 9da2d8a..b49a3ce 100644 --- a/kernel/src/arch/riscv32/compiler_rt.rs +++ b/kernel/src/arch/riscv32/compiler_rt.rs @@ -4,5 +4,5 @@ #[no_mangle] pub extern fn abort() { - loop {} + panic!("abort"); } diff --git a/kernel/src/arch/riscv32/consts.rs b/kernel/src/arch/riscv32/consts.rs index 6a8728d..54b776e 100644 --- a/kernel/src/arch/riscv32/consts.rs +++ b/kernel/src/arch/riscv32/consts.rs @@ -1,25 +1,26 @@ // Physical address available on THINPAD: // [0x80000000, 0x80800000] #[cfg(target_arch = "riscv32")] -pub const RECURSIVE_INDEX: usize = 0x3fe; +pub const RECURSIVE_INDEX: usize = 0x3fd; #[cfg(target_arch = "riscv64")] -pub const RECURSIVE_INDEX: usize = 0x1fd; +pub const RECURSIVE_INDEX: usize = 0o774; // Under riscv64, upon booting, paging is enabled by bbl and // root_table[0777] maps to p3_table, -// and p3_table[0776] maps to gigapage 8000_0000H, +// and p3_table[0777] maps to gigapage 8000_0000H, // so 0xFFFF_FFFF_8000_0000 maps to 0x8000_0000 -// root_table[0775] points to root_table itself as page table -// root_table[0776] points to root_table itself as leaf page +// root_table[0774] points to root_table itself as page table +// root_table[0775] points to root_table itself as leaf page +// root_table[0776] points to a temp page table as leaf page #[cfg(target_arch = "riscv32")] -pub const KERN_VA_BASE: usize = 0; +pub const KERN_VA_BASE: usize = 0xC000_0000; #[cfg(target_arch = "riscv64")] -pub const KERN_VA_BASE: usize = 0xFFFF_FFFF_0000_0000; +pub const KERN_VA_BASE: usize = 0xFFFF_FFFF_C000_0000; #[cfg(target_arch = "riscv32")] -pub const KERNEL_P2_INDEX: usize = 0x8000_0000 >> 12 >> 10; +pub const KERNEL_P2_INDEX: usize = (KERN_VA_BASE >> 12 >> 10) & 0x3ff; #[cfg(target_arch = "riscv64")] -pub const KERNEL_P4_INDEX: usize = 0x0000_FFFF_8000_0000 >> 12 >> 9 >> 9 >> 9; +pub const KERNEL_P4_INDEX: usize = (KERN_VA_BASE >> 12 >> 9 >> 9 >> 9) & 0o777; #[cfg(feature = "board_k210")] pub const KERNEL_HEAP_SIZE: usize = 0x0010_0000; @@ -40,8 +41,9 @@ pub const MEMORY_END: usize = 0x4060_0000; #[cfg(all(target_arch = "riscv64", not(feature = "board_k210")))] pub const MEMORY_END: usize = 0x8100_0000; -pub const USER_STACK_OFFSET: usize = 0x70000000; +// FIXME: rv64 `sh` and `ls` will crash if stack top > 0x80000000 ??? +pub const USER_STACK_OFFSET: usize = 0x80000000 - USER_STACK_SIZE; pub const USER_STACK_SIZE: usize = 0x10000; -pub const USER32_STACK_OFFSET: usize = USER_STACK_OFFSET; +pub const USER32_STACK_OFFSET: usize = 0xC0000000 - USER_STACK_SIZE; pub const MAX_DTB_SIZE: usize = 0x2000; \ No newline at end of file diff --git a/kernel/src/arch/riscv32/memory.rs b/kernel/src/arch/riscv32/memory.rs index d71de6d..cb1d1cb 100644 --- a/kernel/src/arch/riscv32/memory.rs +++ b/kernel/src/arch/riscv32/memory.rs @@ -36,7 +36,7 @@ pub fn init(dtb: usize) { pub fn init_other() { unsafe { sstatus::set_sum(); // Allow user memory access - asm!("csrw 0x180, $0; sfence.vma" :: "r"(SATP) :: "volatile"); + asm!("csrw satp, $0; sfence.vma" :: "r"(SATP) :: "volatile"); } } @@ -49,7 +49,7 @@ fn init_frame_allocator() { use core::ops::Range; let mut ba = FRAME_ALLOCATOR.lock(); - let range = to_range((end as usize) - KERN_VA_BASE + PAGE_SIZE, MEMORY_END); + let range = to_range((end as usize) - KERN_VA_BASE + MEMORY_OFFSET + PAGE_SIZE, MEMORY_END); ba.insert(range); /* @@ -72,7 +72,7 @@ fn init_frame_allocator() { /// Remap the kernel memory address with 4K page recorded in p1 page table #[cfg(not(feature = "no_mmu"))] fn remap_the_kernel(dtb: usize) { - let offset = -(super::consts::KERN_VA_BASE as isize); + let offset = -(KERN_VA_BASE as isize - MEMORY_OFFSET as isize); let mut ms = MemorySet::new_bare(); ms.push(stext as usize, etext as usize, Linear::new(offset, MemoryAttr::default().execute().readonly()), "text"); ms.push(sdata as usize, edata as usize, Linear::new(offset, MemoryAttr::default()), "data"); diff --git a/kernel/src/arch/riscv32/paging.rs b/kernel/src/arch/riscv32/paging.rs index 595a6af..adf71ad 100644 --- a/kernel/src/arch/riscv32/paging.rs +++ b/kernel/src/arch/riscv32/paging.rs @@ -17,18 +17,10 @@ pub struct ActivePageTable(RecursivePageTable<'static>, PageEntry); /// PageTableEntry: the contents of this entry. /// Page: this entry is the pte of page `Page`. -pub struct PageEntry(PageTableEntry, Page); +pub struct PageEntry(&'static mut PageTableEntry, Page); impl PageTable for ActivePageTable { - /* - * @param: - * addr: the virtual addr to be matched - * target: the physical addr to be matched with addr - * @brief: - * map the virtual address 'addr' to the physical address 'target' in pagetable. - * @retval: - * the matched PageEntry - */ + 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` @@ -41,128 +33,31 @@ impl PageTable for ActivePageTable { self.get_entry(addr).expect("fail to get entry") } - /* - * @param: - * addr: virtual address of which the mapped physical frame should be unmapped - * @bridf: - ^ unmap the virtual addresses' mapped physical frame - */ fn unmap(&mut self, addr: usize) { let page = Page::of_addr(VirtAddr::new(addr)); let (_, flush) = self.0.unmap(page).unwrap(); flush.flush(); } - /* - * @param: - * addr: input virtual address - * @brief: - * get the pageEntry of 'addr' - * @retval: - * a mutable PageEntry reference of 'addr' - */ - #[cfg(target_arch = "riscv32")] fn get_entry(&mut self, vaddr: usize) -> Option<&mut Entry> { - let p2_table = unsafe { ROOT_PAGE_TABLE.as_mut().unwrap() }; let page = Page::of_addr(VirtAddr::new(vaddr)); - if !p2_table[page.p2_index()].flags().contains(EF::VALID) { - return None; + if let Ok(e) = self.0.ref_entry(page.clone()) { + let e = unsafe { &mut *(e as *mut PageTableEntry) }; + self.1 = PageEntry(e, page); + Some(&mut self.1 as &mut Entry) + } else { + None } - let entry = edit_entry_of(&page, |entry| *entry); - self.1 = PageEntry(entry, page); - Some(&mut self.1) - } - - /* - * @param: - * addr: input virtual address - * @brief: - * get the pageEntry of 'addr' - * @retval: - * a mutable PageEntry reference of 'addr' - */ - #[cfg(target_arch = "riscv64")] - fn get_entry(&mut self, vaddr: usize) -> Option<&mut Entry> { - let vaddr = VirtAddr::new(vaddr); - let page = Page::of_addr(vaddr); - - if ! self.0.is_mapped( - vaddr.p4_index(), vaddr.p3_index(), vaddr.p2_index(), vaddr.p1_index()) { - return None; - } - - let entry = edit_entry_of(&page, |entry| *entry); - self.1 = PageEntry(entry, page); - Some(&mut self.1) } } impl PageTableExt for ActivePageTable {} -#[cfg(target_arch = "riscv32")] -fn edit_entry_of(page: &Page, f: impl FnOnce(&mut PageTableEntry) -> T) -> T { - 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 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 = - (((RECURSIVE_INDEX << 10) | (RECURSIVE_INDEX + 1)) << 12) as *mut RvPageTable; + ((RECURSIVE_INDEX << 12 << 10) | + ((RECURSIVE_INDEX+1) << 12)) as *mut RvPageTable; #[cfg(target_arch = "riscv64")] const ROOT_PAGE_TABLE: *mut RvPageTable = ((0xFFFF_0000_0000_0000) | @@ -175,7 +70,7 @@ impl ActivePageTable { pub unsafe fn new() -> Self { ActivePageTable( RecursivePageTable::new(&mut *ROOT_PAGE_TABLE).unwrap(), - ::core::mem::zeroed() + ::core::mem::uninitialized() ) } } @@ -183,7 +78,6 @@ impl ActivePageTable { /// implementation for the Entry trait in /crate/memory/src/paging/mod.rs impl Entry for PageEntry { fn update(&mut self) { - edit_entry_of(&self.1, |entry| *entry = self.0); sfence_vma(0, self.1.start_address()); } fn accessed(&self) -> bool { self.0.flags().contains(EF::ACCESSED) } @@ -288,7 +182,7 @@ impl InactivePageTable for InactivePageTable0 { } unsafe fn set_token(token: usize) { - asm!("csrw 0x180, $0" :: "r"(token) :: "volatile"); + asm!("csrw satp, $0" :: "r"(token) :: "volatile"); } fn active_token() -> usize { diff --git a/riscv-pk b/riscv-pk index f4ec45a..e309fff 160000 --- a/riscv-pk +++ b/riscv-pk @@ -1 +1 @@ -Subproject commit f4ec45a908005331149af5816247dcb89fbd4654 +Subproject commit e309fff977870e7596f87788c891dfd393fd5296