Skip to content

Migrating to OpenSBI 0.9 with SBI spec 0.2 #72

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
36 changes: 27 additions & 9 deletions kernel/src/arch/riscv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -33,21 +42,24 @@ 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);
}

unsafe {
memory::clear_bss();
}

info!(
"Hello RISCV! in hart {}, device tree @ {:#x}",
hartid, device_tree_vaddr
);

crate::logging::init();

unsafe {
trapframe::init();
}
Expand All @@ -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();
}

Expand All @@ -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;
Expand Down
100 changes: 89 additions & 11 deletions kernel/src/arch/riscv/sbi.rs
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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,
Expand All @@ -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.
Binary file added tools/opensbi/fw_jump.elf
Binary file not shown.