[WIP] Initial rv64 sv39 support

master
Jiajie Chen 6 years ago
parent 0d801eceb5
commit 26e47fc36f

2
kernel/Cargo.lock generated

@ -450,7 +450,7 @@ dependencies = [
[[package]]
name = "riscv"
version = "0.5.0"
source = "git+https://github.com/rcore-os/riscv#58b3c27b455bed03547cb6112a2f1479e4f4f5ee"
source = "git+https://github.com/rcore-os/riscv#8e25d63d123773145911f4a1f718fc1bc73d80c6"
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)",

@ -1,5 +1,8 @@
// Linear mapping
#[cfg(target_arch = "riscv32")]
pub const PHYSICAL_MEMORY_OFFSET: usize = 0x4000_0000;
#[cfg(target_arch = "riscv64")]
pub const PHYSICAL_MEMORY_OFFSET: usize = 0xFFFF_FFFF_4000_0000;
#[cfg(target_arch = "riscv32")]
pub const KERNEL_OFFSET: usize = 0xC000_0000;

@ -17,11 +17,6 @@ pub fn init(dtb: usize) {
// initialize heap and Frame allocator
init_frame_allocator();
init_heap();
// remap the kernel use 4K page
#[cfg(target_arch = "riscv64")]
unsafe {
super::paging::setup_recursive_mapping();
}
remap_the_kernel(dtb);
}
@ -55,7 +50,6 @@ fn init_frame_allocator() {
}
/// Remap the kernel memory address with 4K page recorded in p1 page table
#[cfg(target_arch = "riscv32")]
fn remap_the_kernel(_dtb: usize) {
let mut ms = MemorySet::new();
unsafe {
@ -68,133 +62,6 @@ fn remap_the_kernel(_dtb: usize) {
info!("remap kernel end");
}
/// Remap the kernel memory address with 4K page recorded in p1 page table
#[cfg(target_arch = "riscv64")]
fn remap_the_kernel(dtb: usize) {
let offset = -(KERNEL_OFFSET as isize - MEMORY_OFFSET as isize);
let mut ms = MemorySet::new_bare();
ms.push(
stext as usize,
etext as usize,
MemoryAttr::default().execute().readonly(),
Linear::new(offset),
"text",
);
ms.push(
sdata as usize,
edata as usize,
MemoryAttr::default(),
Linear::new(offset),
"data",
);
ms.push(
srodata as usize,
erodata as usize,
MemoryAttr::default().readonly(),
Linear::new(offset),
"rodata",
);
ms.push(
bootstack as usize,
bootstacktop as usize,
MemoryAttr::default(),
Linear::new(offset),
"stack",
);
ms.push(
sbss as usize,
ebss as usize,
MemoryAttr::default(),
Linear::new(offset),
"bss",
);
// dtb on rocket chip is embedded into kernel
#[cfg(not(feature = "board_rocket_chip"))]
ms.push(
dtb,
dtb + super::consts::MAX_DTB_SIZE,
MemoryAttr::default().readonly(),
Linear::new(offset),
"dts",
);
// map PLIC for HiFiveU & VirtIO
let offset = -(KERNEL_OFFSET as isize);
ms.push(
KERNEL_OFFSET + 0x0C00_2000,
KERNEL_OFFSET + 0x0C00_2000 + PAGE_SIZE,
MemoryAttr::default(),
Linear::new(offset),
"plic0",
);
ms.push(
KERNEL_OFFSET + 0x0C20_2000,
KERNEL_OFFSET + 0x0C20_2000 + PAGE_SIZE,
MemoryAttr::default(),
Linear::new(offset),
"plic1",
);
// map UART for HiFiveU
ms.push(
KERNEL_OFFSET + 0x10010000,
KERNEL_OFFSET + 0x10010000 + PAGE_SIZE,
MemoryAttr::default(),
Linear::new(offset),
"uart",
);
// map UART for VirtIO
ms.push(
KERNEL_OFFSET + 0x10000000,
KERNEL_OFFSET + 0x10000000 + PAGE_SIZE,
MemoryAttr::default(),
Linear::new(offset),
"uart16550",
);
// map PLIC for Rocket Chip
#[cfg(feature = "board_rocket_chip")]
ms.push(
KERNEL_OFFSET + 0x0C20_1000,
KERNEL_OFFSET + 0x0C20_1000 + PAGE_SIZE,
MemoryAttr::default(),
Linear::new(offset),
"plic2",
);
// map UART for Rocket Chip
#[cfg(feature = "board_rocket_chip")]
ms.push(
KERNEL_OFFSET + 0x18000000,
KERNEL_OFFSET + 0x18000000 + PAGE_SIZE,
MemoryAttr::default(),
Linear::new(-(KERNEL_OFFSET as isize + 0x18000000 - 0x60000000)),
"uartlite",
);
// map AXI INTC for Rocket Chip
#[cfg(feature = "board_rocket_chip")]
ms.push(
KERNEL_OFFSET + 0x18100000,
KERNEL_OFFSET + 0x18100000 + PAGE_SIZE,
MemoryAttr::default(),
Linear::new(-(KERNEL_OFFSET as isize + 0x18100000 - 0x61200000)),
"axi_intc",
);
// map AXI4-Stream Data FIFO for Rocket Chip
#[cfg(feature = "board_rocket_chip")]
ms.push(
KERNEL_OFFSET + 0x18200000,
KERNEL_OFFSET + 0x18200000 + PAGE_SIZE,
MemoryAttr::default(),
Linear::new(-(KERNEL_OFFSET as isize + 0x18200000 - 0x64A00000)),
"router",
);
unsafe {
ms.activate();
}
unsafe {
SATP = ms.token();
}
mem::forget(ms);
info!("remap kernel end");
}
// First core stores its SATP here.
// Other cores load it later.
static mut SATP: usize = 0;

@ -1,9 +1,4 @@
use crate::consts::PHYSICAL_MEMORY_OFFSET;
#[cfg(target_arch = "riscv64")]
use crate::consts::RECURSIVE_INDEX;
// Depends on kernel
#[cfg(target_arch = "riscv64")]
use crate::consts::KERNEL_P4_INDEX;
use crate::memory::{alloc_frame, dealloc_frame, phys_to_virt};
use log::*;
use rcore_memory::paging::*;
@ -12,12 +7,19 @@ use riscv::asm::{sfence_vma, sfence_vma_all};
use riscv::paging::{FrameAllocator, FrameDeallocator};
use riscv::paging::{
Mapper, PageTable as RvPageTable, PageTableEntry, PageTableFlags as EF, PageTableType,
RecursivePageTable, TwoLevelPageTable,
RecursivePageTable
};
use riscv::register::satp;
#[cfg(target_arch = "riscv32")]
type TopLevelPageTable<'a> = riscv::paging::Rv32PageTable<'a>;
#[cfg(all(target_arch = "riscv64", feature = "sv39"))]
type TopLevelPageTable<'a> = riscv::paging::Rv39PageTable<'a>;
#[cfg(all(target_arch = "riscv64", not(feature = "sv39")))]
type TopLevelPageTable<'a> = riscv::paging::Rv48PageTable<'a>;
pub struct PageTableImpl {
page_table: TwoLevelPageTable<'static>,
page_table: TopLevelPageTable<'static>,
root_frame: Frame,
entry: PageEntry,
}
@ -151,7 +153,7 @@ impl PageTableImpl {
let frame = Frame::of_ppn(PageTableImpl::active_token() & 0x7fffffff);
let table = frame.as_kernel_mut(PHYSICAL_MEMORY_OFFSET);
PageTableImpl {
page_table: TwoLevelPageTable::new(table, PHYSICAL_MEMORY_OFFSET),
page_table: TopLevelPageTable::new(table, PHYSICAL_MEMORY_OFFSET),
root_frame: frame,
entry: unsafe { core::mem::uninitialized() },
}
@ -167,7 +169,7 @@ impl PageTableExt for PageTableImpl {
table.zero();
PageTableImpl {
page_table: TwoLevelPageTable::new(table, PHYSICAL_MEMORY_OFFSET),
page_table: TopLevelPageTable::new(table, PHYSICAL_MEMORY_OFFSET),
root_frame: frame,
entry: unsafe { core::mem::uninitialized() },
}
@ -178,16 +180,28 @@ impl PageTableExt for PageTableImpl {
let table = unsafe {
&mut *(phys_to_virt(self.root_frame.start_address().as_usize()) as *mut RvPageTable)
};
#[cfg(target_arch = "riscv32")]
for i in 256..1024 {
let flags =
EF::VALID | EF::READABLE | EF::WRITABLE | EF::EXECUTABLE | EF::ACCESSED | EF::DIRTY;
let frame = Frame::of_addr(PhysAddr::new((i << 22) - PHYSICAL_MEMORY_OFFSET));
table[i].set(frame, flags);
}
#[cfg(all(target_arch = "riscv64", feature = "sv39"))]
for i in 509..512 {
let flags =
EF::VALID | EF::READABLE | EF::WRITABLE | EF::EXECUTABLE | EF::ACCESSED | EF::DIRTY;
let frame = Frame::of_addr(PhysAddr::new((0xFFFFFF80_00000000 + (i << 30)) - PHYSICAL_MEMORY_OFFSET));
table[i].set(frame, flags);
}
// TODO: sv48
}
fn token(&self) -> usize {
self.root_frame.number() | (1 << 31)
#[cfg(target_arch = "riscv32")]
return self.root_frame.number() | (1 << 31);
#[cfg(all(target_arch = "riscv64", feature = "sv39"))]
return self.root_frame.number() | (8 << 60);
}
unsafe fn set_token(token: usize) {
@ -203,7 +217,6 @@ impl PageTableExt for PageTableImpl {
}
fn flush_tlb() {
debug!("flushing token {:x}", Self::active_token());
unsafe {
sfence_vma_all();
}

Loading…
Cancel
Save