#![no_std]
#![deny(warnings, missing_docs)]
#[cfg(all(feature = "nobios", target_arch = "riscv64"))]
pub mod msbi;
#[cfg(all(feature = "nobios", target_arch = "riscv64"))]
core::arch::global_asm!(include_str!("m_entry.asm"));
const SBI_CONSOLE_PUTCHAR: usize = 1;
const SBI_CONSOLE_GETCHAR: usize = 2;
const SBI_EXT_TIMER: usize = 0x54494D45;
const SBI_EXT_SRST: usize = 0x53525354;
#[cfg(all(target_arch = "riscv64", not(feature = "nobios")))]
#[inline(always)]
fn sbi_call(eid: usize, fid: usize, arg0: usize, arg1: usize, arg2: usize) -> usize {
let ret;
unsafe {
core::arch::asm!(
"ecall",
inlateout("x10") arg0 => ret,
in("x11") arg1,
in("x12") arg2,
in("x16") fid,
in("x17") eid,
);
}
ret
}
#[cfg(all(target_arch = "riscv64", feature = "nobios"))]
#[inline(always)]
fn sbi_call(eid: usize, fid: usize, arg0: usize, arg1: usize, arg2: usize) -> usize {
let ret1: isize;
let ret2: usize;
unsafe {
core::arch::asm!(
"ecall",
inlateout("x10") arg0 => ret1,
inlateout("x11") arg1 => ret2,
in("x12") arg2,
in("x16") fid,
in("x17") eid
);
}
if ret1 < 0 {
panic!("SBI call failed: {}", ret1);
}
ret2
}
#[cfg(not(target_arch = "riscv64"))]
#[inline(always)]
fn sbi_call(_eid: usize, _fid: usize, _arg0: usize, _arg1: usize, _arg2: usize) -> usize {
unimplemented!("SBI calls are only supported on riscv64")
}
pub fn set_timer(timer: u64) {
sbi_call(SBI_EXT_TIMER, 0, timer as usize, 0, 0);
}
pub fn console_putchar(c: u8) {
sbi_call(SBI_CONSOLE_PUTCHAR, 0, c as usize, 0, 0);
}
pub fn console_getchar() -> usize {
sbi_call(SBI_CONSOLE_GETCHAR, 0, 0, 0, 0)
}
pub fn shutdown(failure: bool) -> ! {
if failure {
sbi_call(SBI_EXT_SRST, 0, 1, 0, 0);
} else {
sbi_call(SBI_EXT_SRST, 0, 0, 0, 0);
}
panic!("It should shutdown!");
}