1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-22 08:06:17 +04:00

Merge pull request #72 from gjz010/riscvsbi2

Migrating to OpenSBI 0.9 with SBI spec 0.2
This commit is contained in:
Chen 2021-03-03 18:39:22 +08:00 committed by GitHub
commit fe7fd0283a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 117 additions and 21 deletions

View File

@ -128,7 +128,7 @@ else
qemu_opts += \
-machine virt \
-serial mon:stdio \
-bios default \
-bios ../tools/opensbi/fw_jump.elf \
-device loader,addr=0x80200000,file=$(kernel_img) \
-drive file=$(USER_QCOW2),format=qcow2,id=sfs \
-device virtio-blk-device,drive=sfs \

View File

@ -22,9 +22,18 @@ pub mod syscall;
pub mod timer;
use crate::memory::phys_to_virt;
use core::sync::atomic::{AtomicBool, Ordering};
use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use riscv::register::sie;
fn start_all_harts() {
// simply wake up the first 64 harts.
use sbi::sbi_hart_start;
for i in 0..64 {
let ret = sbi_hart_start(i, 0x80200000usize, i);
info!("Start {}: {:?}", i, ret);
}
}
#[no_mangle]
pub extern "C" fn rust_main(hartid: usize, device_tree_paddr: usize) -> ! {
let device_tree_vaddr = phys_to_virt(device_tree_paddr);
@ -33,7 +42,15 @@ pub extern "C" fn rust_main(hartid: usize, device_tree_paddr: usize) -> ! {
cpu::set_cpu_id(hartid);
}
if hartid != BOOT_HART_ID {
if FIRST_HART
.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
.is_ok()
{
LOTTERY_HART_ID.store(hartid, Ordering::SeqCst);
start_all_harts();
}
let main_hart = LOTTERY_HART_ID.load(Ordering::SeqCst);
if hartid != main_hart {
while !AP_CAN_INIT.load(Ordering::Relaxed) {}
others_main(hartid);
}
@ -41,13 +58,8 @@ pub extern "C" fn rust_main(hartid: usize, device_tree_paddr: usize) -> ! {
unsafe {
memory::clear_bss();
}
info!(
"Hello RISCV! in hart {}, device tree @ {:#x}",
hartid, device_tree_vaddr
);
crate::logging::init();
unsafe {
trapframe::init();
}
@ -60,8 +72,12 @@ pub extern "C" fn rust_main(hartid: usize, device_tree_paddr: usize) -> ! {
board::init_external_interrupt();
}
crate::process::init();
info!(
"Hello RISCV! in hart {}, device tree @ {:#x}",
hartid, device_tree_vaddr
);
AP_CAN_INIT.store(true, Ordering::Relaxed);
crate::kmain();
}
@ -76,6 +92,8 @@ fn others_main(hartid: usize) -> ! {
}
static AP_CAN_INIT: AtomicBool = AtomicBool::new(false);
static FIRST_HART: AtomicBool = AtomicBool::new(false);
static LOTTERY_HART_ID: AtomicUsize = AtomicUsize::new(0);
#[cfg(not(feature = "board_u540"))]
const BOOT_HART_ID: usize = 0;

View File

@ -1,8 +1,85 @@
//! Port from sbi.h
#![allow(dead_code)]
#[derive(Clone, Copy, Debug)]
pub struct SBIRet {
error: isize,
value: usize,
}
#[derive(Clone, Copy, Debug)]
pub struct SBICall {
eid: usize,
fid: usize,
}
#[inline(always)]
fn sbi_call(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize {
fn sbi_call(which: SBICall, arg0: usize, arg1: usize, arg2: usize) -> SBIRet {
let ret1;
let ret2;
unsafe {
llvm_asm!("ecall"
: "={x10}" (ret1), "={x11}"(ret2)
: "{x10}" (arg0), "{x11}" (arg1), "{x12}" (arg2), "{x17}" (which.eid), "{x16}" (which.fid)
: "memory"
: "volatile");
}
SBIRet {
error: ret1,
value: ret2,
}
}
pub fn sbi_hart_start(hartid: usize, start_addr: usize, opaque: usize) -> SBIRet {
sbi_call(
SBICall {
eid: SBI_EID_HSM,
fid: SBI_FID_HSM_START,
},
hartid,
start_addr as usize,
opaque,
)
}
pub fn sbi_hart_stop() -> ! {
sbi_call(
SBICall {
eid: SBI_EID_HSM,
fid: SBI_FID_HSM_STOP,
},
0,
0,
0,
);
unreachable!();
}
pub fn sbi_hart_get_status(hartid: usize) -> SBIRet {
sbi_call(
SBICall {
eid: SBI_EID_HSM,
fid: SBI_FID_HSM_START,
},
hartid,
0,
0,
)
}
const SBI_SUCCESS: isize = 0;
const SBI_ERR_FAILED: isize = -1;
const SBI_ERR_NOT_SUPPORTED: isize = -2;
const SBI_ERR_INVALID_PARAM: isize = -3;
const SBI_ERR_DENIED: isize = -4;
const SBI_ERR_INVALID_ADDRESS: isize = -5;
const SBI_ERR_ALREADY_AVAILABLE: isize = -6;
const SBI_EID_HSM: usize = 0x48534D;
const SBI_FID_HSM_START: usize = 0;
const SBI_FID_HSM_STOP: usize = 1;
const SBI_FID_HSM_STATUS: usize = 2;
/// Legacy calls.
#[inline(always)]
fn sbi_call_legacy(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize {
let ret;
unsafe {
llvm_asm!("ecall"
@ -15,48 +92,48 @@ fn sbi_call(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize {
}
pub fn console_putchar(ch: usize) {
sbi_call(SBI_CONSOLE_PUTCHAR, ch, 0, 0);
sbi_call_legacy(SBI_CONSOLE_PUTCHAR, ch, 0, 0);
}
pub fn console_getchar() -> usize {
sbi_call(SBI_CONSOLE_GETCHAR, 0, 0, 0)
sbi_call_legacy(SBI_CONSOLE_GETCHAR, 0, 0, 0)
}
pub fn shutdown() -> ! {
sbi_call(SBI_SHUTDOWN, 0, 0, 0);
sbi_call_legacy(SBI_SHUTDOWN, 0, 0, 0);
unreachable!()
}
pub fn set_timer(stime_value: u64) {
#[cfg(target_pointer_width = "32")]
sbi_call(
sbi_call_legacy(
SBI_SET_TIMER,
stime_value as usize,
(stime_value >> 32) as usize,
0,
);
#[cfg(target_pointer_width = "64")]
sbi_call(SBI_SET_TIMER, stime_value as usize, 0, 0);
sbi_call_legacy(SBI_SET_TIMER, stime_value as usize, 0, 0);
}
pub fn clear_ipi() {
sbi_call(SBI_CLEAR_IPI, 0, 0, 0);
sbi_call_legacy(SBI_CLEAR_IPI, 0, 0, 0);
}
pub fn send_ipi(hart_mask: usize) {
sbi_call(SBI_SEND_IPI, &hart_mask as *const _ as usize, 0, 0);
sbi_call_legacy(SBI_SEND_IPI, &hart_mask as *const _ as usize, 0, 0);
}
pub fn remote_fence_i(hart_mask: usize) {
sbi_call(SBI_REMOTE_FENCE_I, &hart_mask as *const _ as usize, 0, 0);
sbi_call_legacy(SBI_REMOTE_FENCE_I, &hart_mask as *const _ as usize, 0, 0);
}
pub fn remote_sfence_vma(hart_mask: usize, _start: usize, _size: usize) {
sbi_call(SBI_REMOTE_SFENCE_VMA, &hart_mask as *const _ as usize, 0, 0);
sbi_call_legacy(SBI_REMOTE_SFENCE_VMA, &hart_mask as *const _ as usize, 0, 0);
}
pub fn remote_sfence_vma_asid(hart_mask: usize, _start: usize, _size: usize, _asid: usize) {
sbi_call(
sbi_call_legacy(
SBI_REMOTE_SFENCE_VMA_ASID,
&hart_mask as *const _ as usize,
0,
@ -73,3 +150,4 @@ const SBI_REMOTE_FENCE_I: usize = 5;
const SBI_REMOTE_SFENCE_VMA: usize = 6;
const SBI_REMOTE_SFENCE_VMA_ASID: usize = 7;
const SBI_SHUTDOWN: usize = 8;
// Legacy calls end.

BIN
tools/opensbi/fw_jump.elf Executable file

Binary file not shown.