Merge branch 'dev' of github.com:rcore-os/rCore into dev

master
chyyuu 6 years ago
commit 3eddda4000

3
.gitmodules vendored

@ -1,6 +1,3 @@
[submodule "riscv-pk"]
path = riscv-pk
url = https://github.com/rcore-os/riscv-pk.git
[submodule "user"]
path = user
url = https://github.com/rcore-os/rcore-user.git

@ -19,6 +19,7 @@ authors = [
]
[features]
default = ["sv39"]
# Page table sv39 or sv48 (for riscv64)
sv39 = []
board_u540 = ["sv39", "link_user"]

@ -124,7 +124,8 @@ endif
else ifeq ($(arch), riscv32)
qemu_opts += \
-machine virt \
-kernel $(kernel_img) \
-kernel ../tools/opensbi/virt_rv32.elf \
-device loader,addr=0x80400000,file=$(kernel_img) \
-drive file=$(SFSIMG),format=qcow2,id=sfs \
-device virtio-blk-device,drive=sfs
qemu_net_opts += \
@ -132,11 +133,19 @@ qemu_net_opts += \
-device virtio-net-device,netdev=net0
else ifeq ($(arch), riscv64)
ifeq ($(board), u540)
qemu_opts += \
-machine virt \
-kernel ../tools/opensbi/fu540.elf \
-device loader,addr=0x80200000,file=$(kernel_img)
else
qemu_opts += \
-machine virt \
-kernel $(kernel_img) \
-kernel ../tools/opensbi/virt_rv64.elf \
-device loader,addr=0x80200000,file=$(kernel_img) \
-drive file=$(SFSIMG),format=qcow2,id=sfs \
-device virtio-blk-device,drive=sfs
endif
qemu_net_opts += \
-netdev type=tap,id=net0,script=no,downscript=no \
-device virtio-net-device,netdev=net0
@ -297,28 +306,8 @@ ifeq ($(need_bootloader), true)
endif
$(kernel_img): kernel $(bootloader)
ifeq ($(arch), riscv32)
@mkdir -p target/$(target)/bbl && \
cd target/$(target)/bbl && \
$(bbl_path)/configure \
$(riscv_pk_args) \
--with-arch=rv32imac \
--disable-fp-emulation \
--host=riscv64-unknown-elf \
--with-payload=$(abspath $(kernel)) && \
make -j && \
cp bbl $(abspath $@)
else ifeq ($(arch), riscv64)
@mkdir -p target/$(target)/bbl && \
cd target/$(target)/bbl && \
$(bbl_path)/configure \
$(riscv_pk_args) \
--with-arch=rv64imac \
--disable-fp-emulation \
--host=riscv64-unknown-elf \
--with-payload=$(abspath $(kernel)) && \
make -j && \
cp bbl $(abspath $@)
ifeq ($(arch), $(filter $(arch), riscv32 riscv64))
@$(objcopy) $(kernel) --strip-all -O binary $@
else ifeq ($(arch), aarch64)
ifneq ($(u_boot), )
@cp $(u_boot) $@
@ -335,13 +324,7 @@ kernel: $(dtb)
ifeq ($(arch), x86_64)
@bootimage build $(build_args)
@mv target/x86_64/bootimage.bin $(bootimage)
else ifeq ($(arch), riscv32)
@-patch -p0 -N -b \
$(shell rustc --print sysroot)/lib/rustlib/src/rust/src/libcore/sync/atomic.rs \
src/arch/riscv32/atomic.patch
@cargo xbuild $(build_args)
else ifeq ($(arch), riscv64)
@cp src/arch/riscv32/board/u540/linker.ld src/arch/riscv32/boot/linker64.ld
else ifeq ($(arch), $(filter $(arch), riscv32 riscv64))
@-patch -p0 -N -b \
$(shell rustc --print sysroot)/lib/rustlib/src/rust/src/libcore/sync/atomic.rs \
src/arch/riscv32/atomic.patch

@ -1,49 +0,0 @@
/* Copy from bbl-ucore : https://ring00.github.io/bbl-ucore */
/* Simple linker script for the ucore kernel.
See the GNU ld 'info' manual ("info ld") to learn the syntax. */
OUTPUT_ARCH(riscv)
ENTRY(_start)
BASE_ADDRESS = 0xffffffffc0020000;
SECTIONS
{
/* Load the kernel at this address: "." means the current address */
. = BASE_ADDRESS;
start = .;
.text : {
stext = .;
*(.text.entry)
*(.text .text.*)
. = ALIGN(4K);
etext = .;
}
.rodata : {
srodata = .;
*(.rodata .rodata.*)
. = ALIGN(4K);
erodata = .;
}
.data : {
sdata = .;
*(.data .data.*)
edata = .;
}
.stack : {
*(.bss.stack)
}
.bss : {
sbss = .;
*(.bss .bss.*)
ebss = .;
}
PROVIDE(end = .);
}

@ -4,7 +4,7 @@ use super::consts::KERNEL_OFFSET;
pub unsafe fn init_external_interrupt() {
const HART1_S_MODE_INTERRUPT_ENABLES: *mut u64 = (KERNEL_OFFSET + 0x0C00_2100) as *mut u64;
const SERIAL: u64 = 4;
HART1_S_MODE_INTERRUPT_ENABLES.write(1 << SERIAL);
HART1_S_MODE_INTERRUPT_ENABLES.write_volatile(1 << SERIAL);
}
/// Claim and complete external interrupt by reading and writing to
@ -13,7 +13,14 @@ pub unsafe fn handle_external_interrupt() {
const HART1_S_MODE_INTERRUPT_CLAIM_COMPLETE: *mut u32 =
(KERNEL_OFFSET + 0x0C20_2004) as *mut u32;
// claim
let source = HART1_S_MODE_INTERRUPT_CLAIM_COMPLETE.read();
let source = HART1_S_MODE_INTERRUPT_CLAIM_COMPLETE.read_volatile();
// complete
HART1_S_MODE_INTERRUPT_CLAIM_COMPLETE.write(source);
HART1_S_MODE_INTERRUPT_CLAIM_COMPLETE.write_volatile(source);
}
pub unsafe fn enable_serial_interrupt() {
const SERIAL_BASE: *mut u8 = (KERNEL_OFFSET + 0x10010000) as *mut u8;
const UART_REG_IE: usize = 4;
const UART_RXWM: u8 = 0x2;
SERIAL_BASE.add(UART_REG_IE).write_volatile(UART_RXWM);
}

@ -0,0 +1,18 @@
use super::consts::KERNEL_OFFSET;
/// Mask all external interrupt except serial.
pub unsafe fn init_external_interrupt() {
// By default:
// riscv-pk (bbl) enables all S-Mode IRQs (ref: machine/minit.c)
// OpenSBI v0.3 disables all IRQs (ref: platform/common/irqchip/plic.c)
const HART0_S_MODE_INTERRUPT_ENABLES: *mut u32 = (KERNEL_OFFSET + 0x0C00_2080) as *mut u32;
const SERIAL: u32 = 0xa;
HART0_S_MODE_INTERRUPT_ENABLES.write_volatile(1 << SERIAL);
}
pub unsafe fn enable_serial_interrupt() {
const UART16550: *mut u8 = (KERNEL_OFFSET + 0x10000000) as *mut u8;
UART16550.add(4).write_volatile(0x0B);
UART16550.add(1).write_volatile(0x01);
}

@ -1,19 +0,0 @@
.section .text.entry
.globl _start
_start:
add t0, a0, 1
slli t0, t0, 16
lui sp, %hi(bootstack)
addi sp, sp, %lo(bootstack)
add sp, sp, t0
call rust_main
.section .bss.stack
.align 12 #PGSHIFT
.global bootstack
bootstack:
.space 4096 * 16 * 8
.global bootstacktop
bootstacktop:

@ -0,0 +1,55 @@
.section .text.entry
.globl _start
_start:
# a0 == hartid
# pc == 0x80200000
# sp == 0x800xxxxx
# 1. set sp
# sp = bootstack + (hartid + 1) * 0x10000
add t0, a0, 1
slli t0, t0, 16
lui sp, %hi(bootstack)
add sp, sp, t0
# 2. enable paging
# satp = (1 << 31) | PPN(boot_page_table_sv32)
lui t0, %hi(boot_page_table_sv32)
li t1, 0xc0000000 - 0x80000000
sub t0, t0, t1
srli t0, t0, 12
li t1, 1 << 31
or t0, t0, t1
csrw satp, t0
sfence.vma
# 3. jump to rust_main (absolute address)
lui t0, %hi(rust_main)
addi t0, t0, %lo(rust_main)
jr t0
.section .bss.stack
.align 12 # page align
.global bootstack
bootstack:
.space 4096 * 16 * 8
.global bootstacktop
bootstacktop:
.section .data
.align 12 # page align
boot_page_table_sv32:
# NOTE: assume kernel image < 16M
# 0x80000000 -> 0x80000000 (4M * 4)
# 0xc0000000 -> 0x80000000 (4M * 4)
.zero 4 * 512
.word (0x80000 << 10) | 0xcf # VRWXAD
.word (0x80400 << 10) | 0xcf # VRWXAD
.word (0x80800 << 10) | 0xcf # VRWXAD
.word (0x80c00 << 10) | 0xcf # VRWXAD
.zero 4 * 252
.word (0x80000 << 10) | 0xcf # VRWXAD
.word (0x80400 << 10) | 0xcf # VRWXAD
.word (0x80800 << 10) | 0xcf # VRWXAD
.word (0x80c00 << 10) | 0xcf # VRWXAD
.zero 4 * 252

@ -0,0 +1,48 @@
.section .text.entry
.globl _start
_start:
# a0 == hartid
# pc == 0x80200000
# sp == 0x800xxxxx
# 1. set sp
# sp = bootstack + (hartid + 1) * 0x10000
add t0, a0, 1
slli t0, t0, 16
lui sp, %hi(bootstack)
add sp, sp, t0
# 2. enable paging
# satp = (8 << 60) | PPN(boot_page_table_sv39)
lui t0, %hi(boot_page_table_sv39)
li t1, 0xffffffffc0000000 - 0x80000000
sub t0, t0, t1
srli t0, t0, 12
li t1, 8 << 60
or t0, t0, t1
csrw satp, t0
sfence.vma
# 3. jump to rust_main (absolute address)
lui t0, %hi(rust_main)
addi t0, t0, %lo(rust_main)
jr t0
.section .bss.stack
.align 12 # page align
.global bootstack
bootstack:
.space 4096 * 16 * 8
.global bootstacktop
bootstacktop:
.section .data
.align 12 # page align
boot_page_table_sv39:
# 0x00000000_80000000 -> 0x80000000 (1G)
# 0xffffffff_c0000000 -> 0x80000000 (1G)
.quad 0
.quad 0
.quad (0x80000 << 10) | 0xcf # VRWXAD
.zero 8 * 508
.quad (0x80000 << 10) | 0xcf # VRWXAD

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

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

@ -22,17 +22,11 @@ pub const KERNEL_P2_INDEX: usize = (KERNEL_OFFSET >> 12 >> 10) & 0x3ff;
#[cfg(target_arch = "riscv64")]
pub const KERNEL_P4_INDEX: usize = (KERNEL_OFFSET >> 12 >> 9 >> 9 >> 9) & 0o777;
pub const KERNEL_HEAP_SIZE: usize = 0x00a0_0000;
pub const KERNEL_HEAP_SIZE: usize = 0x0080_0000;
#[cfg(target_arch = "riscv32")]
pub const MEMORY_OFFSET: usize = 0x8000_0000;
#[cfg(target_arch = "riscv64")]
pub const MEMORY_OFFSET: usize = 0x8000_0000;
#[cfg(target_arch = "riscv32")]
pub const MEMORY_END: usize = 0x8100_0000;
#[cfg(target_arch = "riscv64")]
pub const MEMORY_END: usize = 0x8100_0000;
// TODO: get memory end from device tree
pub const MEMORY_END: usize = 0x8800_0000;
// FIXME: rv64 `sh` and `ls` will crash if stack top > 0x80000000 ???
pub const USER_STACK_OFFSET: usize = 0x80000000 - USER_STACK_SIZE;

@ -1,8 +1,3 @@
use crate::consts::MAX_CPU_NUM;
use core::ptr::{read_volatile, write_volatile};
static mut STARTED: [bool; MAX_CPU_NUM] = [false; MAX_CPU_NUM];
pub unsafe fn set_cpu_id(cpu_id: usize) {
asm!("mv gp, $0" : : "r"(cpu_id));
}
@ -19,18 +14,6 @@ pub fn send_ipi(cpu_id: usize) {
super::sbi::send_ipi(1 << cpu_id);
}
pub unsafe fn has_started(cpu_id: usize) -> bool {
read_volatile(&STARTED[cpu_id])
}
pub unsafe fn start_others(hart_mask: usize) {
for cpu_id in 0..32 {
if (hart_mask >> cpu_id) & 1 != 0 {
write_volatile(&mut STARTED[cpu_id], true);
}
}
}
pub fn halt() {
unsafe { riscv::asm::wfi() }
}

@ -47,6 +47,3 @@ pub fn getchar_option() -> Option<char> {
pub fn putfmt(fmt: Arguments) {
SerialPort.write_fmt(fmt).unwrap();
}
const TXDATA: *mut u32 = 0x38000000 as *mut u32;
const RXDATA: *mut u32 = 0x38000004 as *mut u32;

@ -8,13 +8,17 @@ use riscv::{addr::*, register::sstatus};
/// Initialize the memory management module
pub fn init(dtb: usize) {
// allow user memory access
unsafe {
sstatus::set_sum();
} // Allow user memory access
// initialize heap and Frame allocator
}
// initialize heap and Frame allocator
init_frame_allocator();
init_heap();
// remap the kernel use 4K page
unsafe {
super::paging::setup_recursive_mapping();
}
remap_the_kernel(dtb);
}
@ -93,7 +97,7 @@ fn remap_the_kernel(dtb: usize) {
Linear::new(offset),
"dts",
);
// map PLIC for HiFiveU
// map PLIC for HiFiveU & VirtIO
let offset = -(KERNEL_OFFSET as isize);
ms.push(
KERNEL_OFFSET + 0x0C00_2000,
@ -109,6 +113,22 @@ fn remap_the_kernel(dtb: usize) {
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",
);
unsafe {
ms.activate();
}

@ -1,6 +1,10 @@
#[cfg(feature = "board_u540")]
#[path = "board/u540/mod.rs"]
mod board;
#[cfg(not(feature = "board_u540"))]
#[path = "board/virt/mod.rs"]
mod board;
pub mod compiler_rt;
pub mod consts;
pub mod cpu;
@ -13,19 +17,24 @@ mod sbi;
pub mod syscall;
pub mod timer;
use self::consts::{KERNEL_OFFSET, MEMORY_OFFSET};
use core::sync::atomic::{AtomicBool, Ordering};
use log::*;
#[no_mangle]
pub extern "C" fn rust_main(hartid: usize, dtb: usize, hart_mask: usize) -> ! {
// An initial recursive page table has been set by BBL (shared by all cores)
pub extern "C" fn rust_main(hartid: usize, device_tree_paddr: usize) -> ! {
let device_tree_vaddr = device_tree_paddr - MEMORY_OFFSET + KERNEL_OFFSET;
unsafe {
cpu::set_cpu_id(hartid);
}
if hartid != BOOT_HART_ID {
while unsafe { !cpu::has_started(hartid) } {}
println!("Hello RISCV! in hart {}, dtb @ {:#x}", hartid, dtb);
while !AP_CAN_INIT.load(Ordering::Relaxed) {}
println!(
"Hello RISCV! in hart {}, device tree @ {:#x}",
hartid, device_tree_vaddr
);
others_main();
//other_main -> !
}
@ -34,24 +43,25 @@ pub extern "C" fn rust_main(hartid: usize, dtb: usize, hart_mask: usize) -> ! {
memory::clear_bss();
}
println!("Hello RISCV! in hart {}, dtb @ {:#x}", hartid, dtb);
println!(
"Hello RISCV! in hart {}, device tree @ {:#x}",
hartid, device_tree_vaddr
);
crate::logging::init();
interrupt::init();
memory::init(dtb);
memory::init(device_tree_vaddr);
timer::init();
// FIXME: init driver on u540
#[cfg(not(feature = "board_u540"))]
crate::drivers::init(dtb);
#[cfg(feature = "board_u540")]
crate::drivers::init(device_tree_vaddr);
unsafe {
board::enable_serial_interrupt();
board::init_external_interrupt();
}
crate::process::init();
unsafe {
cpu::start_others(hart_mask);
}
AP_CAN_INIT.store(true, Ordering::Relaxed);
crate::kmain();
}
@ -62,6 +72,8 @@ fn others_main() -> ! {
crate::kmain();
}
static AP_CAN_INIT: AtomicBool = AtomicBool::new(false);
#[cfg(not(feature = "board_u540"))]
const BOOT_HART_ID: usize = 0;
#[cfg(feature = "board_u540")]
@ -94,6 +106,8 @@ global_asm!(
.endm
"
);
global_asm!(include_str!("boot/entry.asm"));
#[cfg(target_arch = "riscv32")]
global_asm!(include_str!("boot/entry32.asm"));
#[cfg(target_arch = "riscv64")]
global_asm!(include_str!("boot/entry64.asm"));
global_asm!(include_str!("boot/trap.asm"));

@ -198,7 +198,7 @@ impl InactivePageTable for InactivePageTable0 {
fn start();
fn end();
}
let mut entrys: [PageTableEntry; 16] = unsafe { core::mem::uninitialized() };
let mut entrys: [PageTableEntry; 256] = 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;
@ -299,3 +299,13 @@ impl FrameDeallocator for FrameAllocatorForRiscv {
dealloc_frame(frame.start_address().as_usize());
}
}
pub unsafe fn setup_recursive_mapping() {
let frame = satp::read().frame();
let root_page_table = unsafe { &mut *(frame.start_address().as_usize() as *mut RvPageTable) };
root_page_table.set_recursive(RECURSIVE_INDEX, frame);
unsafe {
sfence_vma_all();
}
info!("setup recursive mapping end");
}

@ -1,4 +1,5 @@
//! Port from sbi.h
#![allow(dead_code)]
#[inline(always)]
fn sbi_call(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize {

@ -20,8 +20,6 @@ impl Stdin {
self.pushed.notify_one();
}
pub fn pop(&self) -> char {
// QEMU v3.0 don't support M-mode external interrupt (bug?)
// So we have to use polling.
loop {
let ret = self.buf.lock().pop_front();
match ret {

@ -16,9 +16,9 @@ pub type MemorySet = rcore_memory::memory_set::MemorySet<InactivePageTable0>;
#[cfg(target_arch = "x86_64")]
pub type FrameAlloc = bitmap_allocator::BitAlloc16M;
// RISCV has 8M memory
// RISCV has 1G memory
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
pub type FrameAlloc = bitmap_allocator::BitAlloc4K;
pub type FrameAlloc = bitmap_allocator::BitAlloc1M;
// Raspberry Pi 3 has 1G memory
#[cfg(any(target_arch = "aarch64", target_arch = "mips"))]

@ -1 +0,0 @@
Subproject commit 405ea59dd7dd2762c5883822f21d9995bea32b0c

@ -0,0 +1,9 @@
# OpenSBI
These are binary release of OpenSBI on this [commit](https://github.com/riscv/opensbi/tree/194dbbe5a13dff2255411c26d249f3ad4ef42c0b) at 2019.04.15.
- fu540.elf: opensbi-0.3-rv64-bin/platform/sifive/fu540/firmware/fw_jump.elf
- virt_rv32.elf: opensbi-0.3-rv32-bin/platform/qemu/virt/firmware/fw_jump.elf
- virt_rv64.elf: opensbi-0.3-rv64-bin/platform/qemu/virt/firmware/fw_jump.elf
NOTE: The [official v0.3 release](https://github.com/riscv/opensbi/releases/tag/v0.3) has bug on serial interrupt.

Binary file not shown.

Binary file not shown.

Binary file not shown.
Loading…
Cancel
Save