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"] [submodule "user"]
path = user path = user
url = https://github.com/rcore-os/rcore-user.git url = https://github.com/rcore-os/rcore-user.git

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

@ -124,7 +124,8 @@ endif
else ifeq ($(arch), riscv32) else ifeq ($(arch), riscv32)
qemu_opts += \ qemu_opts += \
-machine virt \ -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 \ -drive file=$(SFSIMG),format=qcow2,id=sfs \
-device virtio-blk-device,drive=sfs -device virtio-blk-device,drive=sfs
qemu_net_opts += \ qemu_net_opts += \
@ -132,11 +133,19 @@ qemu_net_opts += \
-device virtio-net-device,netdev=net0 -device virtio-net-device,netdev=net0
else ifeq ($(arch), riscv64) 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 += \ qemu_opts += \
-machine virt \ -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 \ -drive file=$(SFSIMG),format=qcow2,id=sfs \
-device virtio-blk-device,drive=sfs -device virtio-blk-device,drive=sfs
endif
qemu_net_opts += \ qemu_net_opts += \
-netdev type=tap,id=net0,script=no,downscript=no \ -netdev type=tap,id=net0,script=no,downscript=no \
-device virtio-net-device,netdev=net0 -device virtio-net-device,netdev=net0
@ -297,28 +306,8 @@ ifeq ($(need_bootloader), true)
endif endif
$(kernel_img): kernel $(bootloader) $(kernel_img): kernel $(bootloader)
ifeq ($(arch), riscv32) ifeq ($(arch), $(filter $(arch), riscv32 riscv64))
@mkdir -p target/$(target)/bbl && \ @$(objcopy) $(kernel) --strip-all -O binary $@
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 $@)
else ifeq ($(arch), aarch64) else ifeq ($(arch), aarch64)
ifneq ($(u_boot), ) ifneq ($(u_boot), )
@cp $(u_boot) $@ @cp $(u_boot) $@
@ -335,13 +324,7 @@ kernel: $(dtb)
ifeq ($(arch), x86_64) ifeq ($(arch), x86_64)
@bootimage build $(build_args) @bootimage build $(build_args)
@mv target/x86_64/bootimage.bin $(bootimage) @mv target/x86_64/bootimage.bin $(bootimage)
else ifeq ($(arch), riscv32) 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
@cargo xbuild $(build_args)
else ifeq ($(arch), riscv64)
@cp src/arch/riscv32/board/u540/linker.ld src/arch/riscv32/boot/linker64.ld
@-patch -p0 -N -b \ @-patch -p0 -N -b \
$(shell rustc --print sysroot)/lib/rustlib/src/rust/src/libcore/sync/atomic.rs \ $(shell rustc --print sysroot)/lib/rustlib/src/rust/src/libcore/sync/atomic.rs \
src/arch/riscv32/atomic.patch 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() { pub unsafe fn init_external_interrupt() {
const HART1_S_MODE_INTERRUPT_ENABLES: *mut u64 = (KERNEL_OFFSET + 0x0C00_2100) as *mut u64; const HART1_S_MODE_INTERRUPT_ENABLES: *mut u64 = (KERNEL_OFFSET + 0x0C00_2100) as *mut u64;
const SERIAL: u64 = 4; 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 /// 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 = const HART1_S_MODE_INTERRUPT_CLAIM_COMPLETE: *mut u32 =
(KERNEL_OFFSET + 0x0C20_2004) as *mut u32; (KERNEL_OFFSET + 0x0C20_2004) as *mut u32;
// claim // claim
let source = HART1_S_MODE_INTERRUPT_CLAIM_COMPLETE.read(); let source = HART1_S_MODE_INTERRUPT_CLAIM_COMPLETE.read_volatile();
// complete // 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) OUTPUT_ARCH(riscv)
ENTRY(_start) ENTRY(_start)
BASE_ADDRESS = 0xC0020000; BASE_ADDRESS = 0xC0400000;
SECTIONS SECTIONS
{ {

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

@ -22,17 +22,11 @@ pub const KERNEL_P2_INDEX: usize = (KERNEL_OFFSET >> 12 >> 10) & 0x3ff;
#[cfg(target_arch = "riscv64")] #[cfg(target_arch = "riscv64")]
pub const KERNEL_P4_INDEX: usize = (KERNEL_OFFSET >> 12 >> 9 >> 9 >> 9) & 0o777; 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; pub const MEMORY_OFFSET: usize = 0x8000_0000;
// TODO: get memory end from device tree
#[cfg(target_arch = "riscv32")] pub const MEMORY_END: usize = 0x8800_0000;
pub const MEMORY_END: usize = 0x8100_0000;
#[cfg(target_arch = "riscv64")]
pub const MEMORY_END: usize = 0x8100_0000;
// FIXME: rv64 `sh` and `ls` will crash if stack top > 0x80000000 ??? // 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_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) { pub unsafe fn set_cpu_id(cpu_id: usize) {
asm!("mv gp, $0" : : "r"(cpu_id)); 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); 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() { pub fn halt() {
unsafe { riscv::asm::wfi() } unsafe { riscv::asm::wfi() }
} }

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

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

@ -198,7 +198,7 @@ impl InactivePageTable for InactivePageTable0 {
fn start(); fn start();
fn end(); 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_start = start as usize >> 22;
let entry_end = (end as usize >> 22) + 1; let entry_end = (end as usize >> 22) + 1;
let entry_count = entry_end - entry_start; let entry_count = entry_end - entry_start;
@ -299,3 +299,13 @@ impl FrameDeallocator for FrameAllocatorForRiscv {
dealloc_frame(frame.start_address().as_usize()); 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 //! Port from sbi.h
#![allow(dead_code)]
#[inline(always)] #[inline(always)]
fn sbi_call(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize { fn sbi_call(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize {

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

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