update for new paging mechanism on riscv. move kernel va to 0x(ffffffff)c0000000.

master
WangRunji 6 years ago
parent 1ceb7ae12d
commit fc8888db72

@ -3,7 +3,7 @@ use alloc::alloc::{Layout, GlobalAlloc};
use core::marker::PhantomData; use core::marker::PhantomData;
pub trait NoMMUSupport { pub trait NoMMUSupport {
type Alloc: GlobalAlloc; type Alloc: GlobalAlloc + 'static;
fn allocator() -> &'static Self::Alloc; fn allocator() -> &'static Self::Alloc;
} }

2
kernel/Cargo.lock generated

@ -307,7 +307,7 @@ dependencies = [
[[package]] [[package]]
name = "riscv" name = "riscv"
version = "0.3.0" 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 = [ dependencies = [
"bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",

@ -553,7 +553,7 @@ fi
CNAME=riscv CNAME=riscv
if ! [[ -f ${OUTDIR}/${CNAME}.o ]] if ! [[ -f ${OUTDIR}/${CNAME}.o ]]
then 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 \ --color always --crate-type lib --emit=metadata,llvm-bc \
-C opt-level=1 \ -C opt-level=1 \
-C debuginfo=2 \ -C debuginfo=2 \

@ -6,7 +6,7 @@
OUTPUT_ARCH(riscv) OUTPUT_ARCH(riscv)
ENTRY(_start) ENTRY(_start)
BASE_ADDRESS = 0xffffffff80020000; BASE_ADDRESS = 0xffffffffc0020000;
SECTIONS SECTIONS
{ {

@ -6,11 +6,11 @@
OUTPUT_ARCH(riscv) OUTPUT_ARCH(riscv)
ENTRY(_start) ENTRY(_start)
BASE_ADDRESS = 0x80020000; BASE_ADDRESS = 0xC0020000;
SECTIONS SECTIONS
{ {
. = 0x80000000; . = 0xC0000000;
.boot : { .boot : {
KEEP(*(.text.boot)) KEEP(*(.text.boot))
} }

@ -6,7 +6,7 @@
OUTPUT_ARCH(riscv) OUTPUT_ARCH(riscv)
ENTRY(_start) ENTRY(_start)
BASE_ADDRESS = 0xffffffff80020000; BASE_ADDRESS = 0xffffffffc0020000;
SECTIONS SECTIONS
{ {

@ -4,5 +4,5 @@
#[no_mangle] #[no_mangle]
pub extern fn abort() { pub extern fn abort() {
loop {} panic!("abort");
} }

@ -1,25 +1,26 @@
// Physical address available on THINPAD: // Physical address available on THINPAD:
// [0x80000000, 0x80800000] // [0x80000000, 0x80800000]
#[cfg(target_arch = "riscv32")] #[cfg(target_arch = "riscv32")]
pub const RECURSIVE_INDEX: usize = 0x3fe; pub const RECURSIVE_INDEX: usize = 0x3fd;
#[cfg(target_arch = "riscv64")] #[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 // Under riscv64, upon booting, paging is enabled by bbl and
// root_table[0777] maps to p3_table, // 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 // so 0xFFFF_FFFF_8000_0000 maps to 0x8000_0000
// root_table[0775] points to root_table itself as page table // root_table[0774] points to root_table itself as page table
// root_table[0776] points to root_table itself as leaf page // 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")] #[cfg(target_arch = "riscv32")]
pub const KERN_VA_BASE: usize = 0; pub const KERN_VA_BASE: usize = 0xC000_0000;
#[cfg(target_arch = "riscv64")] #[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")] #[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")] #[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")] #[cfg(feature = "board_k210")]
pub const KERNEL_HEAP_SIZE: usize = 0x0010_0000; 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")))] #[cfg(all(target_arch = "riscv64", not(feature = "board_k210")))]
pub const MEMORY_END: usize = 0x8100_0000; 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 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; pub const MAX_DTB_SIZE: usize = 0x2000;

@ -36,7 +36,7 @@ pub fn init(dtb: usize) {
pub fn init_other() { pub fn init_other() {
unsafe { unsafe {
sstatus::set_sum(); // Allow user memory access 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; use core::ops::Range;
let mut ba = FRAME_ALLOCATOR.lock(); 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); ba.insert(range);
/* /*
@ -72,7 +72,7 @@ fn init_frame_allocator() {
/// Remap the kernel memory address with 4K page recorded in p1 page table /// Remap the kernel memory address with 4K page recorded in p1 page table
#[cfg(not(feature = "no_mmu"))] #[cfg(not(feature = "no_mmu"))]
fn remap_the_kernel(dtb: usize) { 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(); let mut ms = MemorySet::new_bare();
ms.push(stext as usize, etext as usize, Linear::new(offset, MemoryAttr::default().execute().readonly()), "text"); 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"); ms.push(sdata as usize, edata as usize, Linear::new(offset, MemoryAttr::default()), "data");

@ -17,18 +17,10 @@ pub struct ActivePageTable(RecursivePageTable<'static>, PageEntry);
/// PageTableEntry: the contents of this entry. /// PageTableEntry: the contents of this entry.
/// Page: this entry is the pte of page `Page`. /// 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 { 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 { fn map(&mut self, addr: usize, target: usize) -> &mut Entry {
// use riscv::paging:Mapper::map_to, // use riscv::paging:Mapper::map_to,
// map the 4K `page` to the 4K `frame` with `flags` // 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") 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) { fn unmap(&mut self, addr: usize) {
let page = Page::of_addr(VirtAddr::new(addr)); let page = Page::of_addr(VirtAddr::new(addr));
let (_, flush) = self.0.unmap(page).unwrap(); let (_, flush) = self.0.unmap(page).unwrap();
flush.flush(); 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> { 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)); let page = Page::of_addr(VirtAddr::new(vaddr));
if !p2_table[page.p2_index()].flags().contains(EF::VALID) { if let Ok(e) = self.0.ref_entry(page.clone()) {
return None; 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 {} impl PageTableExt for ActivePageTable {}
#[cfg(target_arch = "riscv32")]
fn edit_entry_of<T>(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<T>(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? // define the ROOT_PAGE_TABLE, and the virtual address of it?
#[cfg(target_arch = "riscv32")] #[cfg(target_arch = "riscv32")]
const ROOT_PAGE_TABLE: *mut RvPageTable = 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")] #[cfg(target_arch = "riscv64")]
const ROOT_PAGE_TABLE: *mut RvPageTable = const ROOT_PAGE_TABLE: *mut RvPageTable =
((0xFFFF_0000_0000_0000) | ((0xFFFF_0000_0000_0000) |
@ -175,7 +70,7 @@ impl ActivePageTable {
pub unsafe fn new() -> Self { pub unsafe fn new() -> Self {
ActivePageTable( ActivePageTable(
RecursivePageTable::new(&mut *ROOT_PAGE_TABLE).unwrap(), 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 /// implementation for the Entry trait in /crate/memory/src/paging/mod.rs
impl Entry for PageEntry { impl Entry for PageEntry {
fn update(&mut self) { fn update(&mut self) {
edit_entry_of(&self.1, |entry| *entry = self.0);
sfence_vma(0, self.1.start_address()); sfence_vma(0, self.1.start_address());
} }
fn accessed(&self) -> bool { self.0.flags().contains(EF::ACCESSED) } fn accessed(&self) -> bool { self.0.flags().contains(EF::ACCESSED) }
@ -288,7 +182,7 @@ impl InactivePageTable for InactivePageTable0 {
} }
unsafe fn set_token(token: usize) { unsafe fn set_token(token: usize) {
asm!("csrw 0x180, $0" :: "r"(token) :: "volatile"); asm!("csrw satp, $0" :: "r"(token) :: "volatile");
} }
fn active_token() -> usize { fn active_token() -> usize {

@ -1 +1 @@
Subproject commit f4ec45a908005331149af5816247dcb89fbd4654 Subproject commit e309fff977870e7596f87788c891dfd393fd5296
Loading…
Cancel
Save