mod base;
mod ipi;
mod legacy;
mod timer;
pub const EXTENSION_BASE: usize = 0x10;
pub const EXTENSION_TIMER: usize = 0x54494D45;
pub const EXTENSION_IPI: usize = 0x735049;
const LEGACY_SET_TIMER: usize = 0x0;
const LEGACY_CONSOLE_PUTCHAR: usize = 0x01;
const LEGACY_CONSOLE_GETCHAR: usize = 0x02;
const LEGACY_SEND_IPI: usize = 0x04;
const LEGACY_SHUTDOWN: usize = 0x08;
#[inline]
pub fn handle_ecall(extension: usize, function: usize, param: [usize; 4]) -> SbiRet {
match extension {
EXTENSION_BASE => base::handle_ecall_base(function, param[0]),
EXTENSION_TIMER => match () {
#[cfg(target_pointer_width = "64")]
() => timer::handle_ecall_timer_64(function, param[0]),
#[cfg(target_pointer_width = "32")]
() => timer::handle_ecall_timer_32(function, param[0], param[1]),
},
EXTENSION_IPI => ipi::handle_ecall_ipi(function, param[0], param[1]),
LEGACY_SET_TIMER => match () {
#[cfg(target_pointer_width = "64")]
() => legacy::set_timer_64(param[0]),
#[cfg(target_pointer_width = "32")]
() => legacy::set_timer_32(param[0], param[1]),
}
.legacy_void(param[0], param[1]),
LEGACY_CONSOLE_PUTCHAR => legacy::console_putchar(param[0]).legacy_void(param[0], param[1]),
LEGACY_CONSOLE_GETCHAR => legacy::console_getchar().legacy_return(param[1]),
LEGACY_SEND_IPI => legacy::send_ipi(param[0]).legacy_void(param[0], param[1]),
LEGACY_SHUTDOWN => legacy::shutdown().legacy_void(param[0], param[1]),
_ => SbiRet::not_supported(),
}
}
#[repr(C)]
pub struct SbiRet {
pub error: usize,
pub value: usize,
}
const SBI_SUCCESS: usize = 0;
const SBI_ERR_NOT_SUPPORTED: usize = usize::from_ne_bytes(isize::to_ne_bytes(-2));
impl SbiRet {
pub(crate) fn ok(value: usize) -> SbiRet {
SbiRet {
error: SBI_SUCCESS,
value,
}
}
pub(crate) fn not_supported() -> SbiRet {
SbiRet {
error: SBI_ERR_NOT_SUPPORTED,
value: 0,
}
}
pub(crate) fn legacy_ok(legacy_value: usize) -> SbiRet {
SbiRet {
error: legacy_value,
value: 0,
}
}
pub(crate) fn legacy_void(self, a0: usize, a1: usize) -> SbiRet {
SbiRet {
error: a0,
value: a1,
}
}
pub(crate) fn legacy_return(self, a1: usize) -> SbiRet {
SbiRet {
error: self.error,
value: a1,
}
}
}