use crate::{ecall2, RestrictedRange, SbiError};
pub const EXTENSION_ID: usize = 0x53525354;
#[derive(Debug, Clone, Copy)]
#[non_exhaustive]
pub enum ResetType {
Shutdown,
ColdReboot,
WarmReboot,
PlatformSpecific(RestrictedRange<0xF0000000, 0xFFFFFFFF>),
}
impl From<ResetType> for u32 {
fn from(value: ResetType) -> Self {
match value {
ResetType::Shutdown => 0,
ResetType::ColdReboot => 1,
ResetType::WarmReboot => 2,
ResetType::PlatformSpecific(n) => n.0,
}
}
}
#[derive(Debug, Clone, Copy)]
#[non_exhaustive]
pub enum ResetReason {
NoReason,
SystemFailure,
SbiSpecific(RestrictedRange<0xE0000000, 0xEFFFFFFF>),
PlatformSpecific(RestrictedRange<0xF0000000, 0xFFFFFFFF>),
}
impl From<ResetReason> for u32 {
fn from(value: ResetReason) -> Self {
match value {
ResetReason::NoReason => 0,
ResetReason::SystemFailure => 1,
ResetReason::SbiSpecific(n) => n.0,
ResetReason::PlatformSpecific(n) => n.0,
}
}
}
pub fn system_reset(
kind: ResetType,
reason: ResetReason,
) -> Result<core::convert::Infallible, SbiError> {
match unsafe {
ecall2(
u32::from(kind) as usize,
u32::from(reason) as usize,
EXTENSION_ID,
0,
)
} {
Ok(_) => unreachable!("SBI returned `Ok` after a system reset call"),
Err(e) => Err(e),
}
}