use crate::binary::sbi_call_2;
use sbi_spec::{
binary::SbiRet,
srst::{
EID_SRST, RESET_REASON_NO_REASON, RESET_REASON_SYSTEM_FAILURE, RESET_TYPE_COLD_REBOOT,
RESET_TYPE_SHUTDOWN, RESET_TYPE_WARM_REBOOT, SYSTEM_RESET,
},
};
#[inline]
#[doc(alias = "sbi_system_reset")]
pub fn system_reset<T, R>(reset_type: T, reset_reason: R) -> SbiRet
where
T: ResetType,
R: ResetReason,
{
sbi_call_2(
EID_SRST,
SYSTEM_RESET,
reset_type.raw() as _,
reset_reason.raw() as _,
)
}
pub trait ResetType {
fn raw(&self) -> u32;
}
#[cfg(feature = "integer-impls")]
impl ResetType for u32 {
#[inline]
fn raw(&self) -> u32 {
*self
}
}
#[cfg(feature = "integer-impls")]
impl ResetType for i32 {
#[inline]
fn raw(&self) -> u32 {
u32::from_ne_bytes(i32::to_ne_bytes(*self))
}
}
pub trait ResetReason {
fn raw(&self) -> u32;
}
#[cfg(feature = "integer-impls")]
impl ResetReason for u32 {
#[inline]
fn raw(&self) -> u32 {
*self
}
}
#[cfg(feature = "integer-impls")]
impl ResetReason for i32 {
#[inline]
fn raw(&self) -> u32 {
u32::from_ne_bytes(i32::to_ne_bytes(*self))
}
}
macro_rules! define_reset_param {
($($struct:ident($value:expr): $trait:ident #[$doc:meta])*) => {
$(
#[derive(Clone, Copy, Debug)]
#[$doc]
pub struct $struct;
impl $trait for $struct {
#[inline]
fn raw(&self) -> u32 {
$value
}
}
)*
};
}
define_reset_param! {
Shutdown(RESET_TYPE_SHUTDOWN): ResetType ColdReboot(RESET_TYPE_COLD_REBOOT): ResetType WarmReboot(RESET_TYPE_WARM_REBOOT): ResetType NoReason(RESET_REASON_NO_REASON): ResetReason SystemFailure(RESET_REASON_SYSTEM_FAILURE): ResetReason }