sbi/
system_reset.rs

1// SPDX-License-Identifier: MPL-2.0
2// SPDX-FileCopyrightText: 2022 repnop
3//
4// This Source Code Form is subject to the terms of the Mozilla Public License,
5// v. 2.0. If a copy of the MPL was not distributed with this file, You can
6// obtain one at https://mozilla.org/MPL/2.0/.
7
8use crate::{ecall2, RestrictedRange, SbiError};
9
10/// System reset extension ID
11pub const EXTENSION_ID: usize = 0x53525354;
12
13/// The type of reset to perform
14#[derive(Debug, Clone, Copy)]
15#[non_exhaustive]
16pub enum ResetType {
17    /// Shutdown the system
18    Shutdown,
19    /// Power off all hardware and perform a cold boot
20    ColdReboot,
21    /// Reset processors and some hardware
22    WarmReboot,
23    /// Platform specific reset type
24    PlatformSpecific(RestrictedRange<0xF0000000, 0xFFFFFFFF>),
25}
26
27impl From<ResetType> for u32 {
28    fn from(value: ResetType) -> Self {
29        match value {
30            ResetType::Shutdown => 0,
31            ResetType::ColdReboot => 1,
32            ResetType::WarmReboot => 2,
33            ResetType::PlatformSpecific(n) => n.0,
34        }
35    }
36}
37
38/// The reason for performing the reset
39#[derive(Debug, Clone, Copy)]
40#[non_exhaustive]
41pub enum ResetReason {
42    /// No reason for reset
43    NoReason,
44    /// System failure
45    SystemFailure,
46    /// SBI implementation specific reset reason
47    SbiSpecific(RestrictedRange<0xE0000000, 0xEFFFFFFF>),
48    /// Platform specific reset reason
49    PlatformSpecific(RestrictedRange<0xF0000000, 0xFFFFFFFF>),
50}
51
52impl From<ResetReason> for u32 {
53    fn from(value: ResetReason) -> Self {
54        match value {
55            ResetReason::NoReason => 0,
56            ResetReason::SystemFailure => 1,
57            ResetReason::SbiSpecific(n) => n.0,
58            ResetReason::PlatformSpecific(n) => n.0,
59        }
60    }
61}
62
63/// Attempt to reset the system in the provided method, with a reason for the
64/// reset.
65///
66/// ### Possible errors
67///
68/// [`SbiError::NOT_SUPPORTED`]: The [`ResetType`] is valid but not implemented.
69///
70/// [`SbiError::FAILED`]: The system reset request failed for an unknown reason.
71pub fn system_reset(
72    kind: ResetType,
73    reason: ResetReason,
74) -> Result<core::convert::Infallible, SbiError> {
75    match unsafe {
76        ecall2(
77            u32::from(kind) as usize,
78            u32::from(reason) as usize,
79            EXTENSION_ID,
80            0,
81        )
82    } {
83        Ok(_) => unreachable!("SBI returned `Ok` after a system reset call"),
84        Err(e) => Err(e),
85    }
86}