mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-25 01:16:18 +04:00
Migrating to OpenSBI 0.9 with SBI spec 0.2
This commit is contained in:
parent
1ab076cfe9
commit
f68cd2486e
@ -128,7 +128,7 @@ else
|
|||||||
qemu_opts += \
|
qemu_opts += \
|
||||||
-machine virt \
|
-machine virt \
|
||||||
-serial mon:stdio \
|
-serial mon:stdio \
|
||||||
-bios default \
|
-bios ../tools/opensbi/fw_jump.elf \
|
||||||
-device loader,addr=0x80200000,file=$(kernel_img) \
|
-device loader,addr=0x80200000,file=$(kernel_img) \
|
||||||
-drive file=$(USER_QCOW2),format=qcow2,id=sfs \
|
-drive file=$(USER_QCOW2),format=qcow2,id=sfs \
|
||||||
-device virtio-blk-device,drive=sfs \
|
-device virtio-blk-device,drive=sfs \
|
||||||
|
@ -22,9 +22,18 @@ pub mod syscall;
|
|||||||
pub mod timer;
|
pub mod timer;
|
||||||
|
|
||||||
use crate::memory::phys_to_virt;
|
use crate::memory::phys_to_virt;
|
||||||
use core::sync::atomic::{AtomicBool, Ordering};
|
use core::sync::atomic::{AtomicBool, Ordering, AtomicUsize};
|
||||||
use riscv::register::sie;
|
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]
|
#[no_mangle]
|
||||||
pub extern "C" fn rust_main(hartid: usize, device_tree_paddr: usize) -> ! {
|
pub extern "C" fn rust_main(hartid: usize, device_tree_paddr: usize) -> ! {
|
||||||
let device_tree_vaddr = phys_to_virt(device_tree_paddr);
|
let device_tree_vaddr = phys_to_virt(device_tree_paddr);
|
||||||
@ -33,7 +42,12 @@ pub extern "C" fn rust_main(hartid: usize, device_tree_paddr: usize) -> ! {
|
|||||||
cpu::set_cpu_id(hartid);
|
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) {}
|
while !AP_CAN_INIT.load(Ordering::Relaxed) {}
|
||||||
others_main(hartid);
|
others_main(hartid);
|
||||||
}
|
}
|
||||||
@ -41,13 +55,10 @@ pub extern "C" fn rust_main(hartid: usize, device_tree_paddr: usize) -> ! {
|
|||||||
unsafe {
|
unsafe {
|
||||||
memory::clear_bss();
|
memory::clear_bss();
|
||||||
}
|
}
|
||||||
|
|
||||||
info!(
|
|
||||||
"Hello RISCV! in hart {}, device tree @ {:#x}",
|
|
||||||
hartid, device_tree_vaddr
|
|
||||||
);
|
|
||||||
|
|
||||||
crate::logging::init();
|
crate::logging::init();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
trapframe::init();
|
trapframe::init();
|
||||||
}
|
}
|
||||||
@ -60,8 +71,12 @@ pub extern "C" fn rust_main(hartid: usize, device_tree_paddr: usize) -> ! {
|
|||||||
board::init_external_interrupt();
|
board::init_external_interrupt();
|
||||||
}
|
}
|
||||||
crate::process::init();
|
crate::process::init();
|
||||||
|
info!(
|
||||||
|
"Hello RISCV! in hart {}, device tree @ {:#x}",
|
||||||
|
hartid, device_tree_vaddr
|
||||||
|
);
|
||||||
AP_CAN_INIT.store(true, Ordering::Relaxed);
|
AP_CAN_INIT.store(true, Ordering::Relaxed);
|
||||||
|
|
||||||
crate::kmain();
|
crate::kmain();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,6 +91,8 @@ fn others_main(hartid: usize) -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static AP_CAN_INIT: AtomicBool = AtomicBool::new(false);
|
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"))]
|
#[cfg(not(feature = "board_u540"))]
|
||||||
const BOOT_HART_ID: usize = 0;
|
const BOOT_HART_ID: usize = 0;
|
||||||
|
@ -1,8 +1,64 @@
|
|||||||
//! Port from sbi.h
|
//! Port from sbi.h
|
||||||
#![allow(dead_code)]
|
#![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)]
|
#[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;
|
let ret;
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm_asm!("ecall"
|
llvm_asm!("ecall"
|
||||||
@ -15,48 +71,48 @@ fn sbi_call(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn console_putchar(ch: 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 {
|
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() -> ! {
|
pub fn shutdown() -> ! {
|
||||||
sbi_call(SBI_SHUTDOWN, 0, 0, 0);
|
sbi_call_legacy(SBI_SHUTDOWN, 0, 0, 0);
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_timer(stime_value: u64) {
|
pub fn set_timer(stime_value: u64) {
|
||||||
#[cfg(target_pointer_width = "32")]
|
#[cfg(target_pointer_width = "32")]
|
||||||
sbi_call(
|
sbi_call_legacy(
|
||||||
SBI_SET_TIMER,
|
SBI_SET_TIMER,
|
||||||
stime_value as usize,
|
stime_value as usize,
|
||||||
(stime_value >> 32) as usize,
|
(stime_value >> 32) as usize,
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
#[cfg(target_pointer_width = "64")]
|
#[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() {
|
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) {
|
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) {
|
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) {
|
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) {
|
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,
|
SBI_REMOTE_SFENCE_VMA_ASID,
|
||||||
&hart_mask as *const _ as usize,
|
&hart_mask as *const _ as usize,
|
||||||
0,
|
0,
|
||||||
@ -73,3 +129,4 @@ const SBI_REMOTE_FENCE_I: usize = 5;
|
|||||||
const SBI_REMOTE_SFENCE_VMA: usize = 6;
|
const SBI_REMOTE_SFENCE_VMA: usize = 6;
|
||||||
const SBI_REMOTE_SFENCE_VMA_ASID: usize = 7;
|
const SBI_REMOTE_SFENCE_VMA_ASID: usize = 7;
|
||||||
const SBI_SHUTDOWN: usize = 8;
|
const SBI_SHUTDOWN: usize = 8;
|
||||||
|
// Legacy calls end.
|
||||||
|
BIN
tools/opensbi/fw_jump.elf
Executable file
BIN
tools/opensbi/fw_jump.elf
Executable file
Binary file not shown.
Loading…
Reference in New Issue
Block a user