1 // Copyright 2023 the authors.
2 // This project is dual-licensed under Apache 2.0 and MIT terms.
3 // See LICENSE-APACHE and LICENSE-MIT for details.
4
5 //! Utility functions for error handling.
6 //!
7 //! These functions can be combined with the appropriate HVC or SMC functions to wrap calls which
8 //! return a single value where negative values indicate an error.
9 //!
10 //! For example, the [`system_off`](crate::psci::system_off) function is implemented approximately
11 //! as:
12 //!
13 //! ```
14 //! # #[cfg(target_arch = "aarch64")]
15 //! use smccc::{
16 //! error::success_or_error_32,
17 //! psci::{error::Error, PSCI_SYSTEM_OFF},
18 //! smc32,
19 //! };
20 //!
21 //! # #[cfg(target_arch = "aarch64")]
22 //! pub fn system_off() -> Result<(), Error> {
23 //! success_or_error_32(smc32(PSCI_SYSTEM_OFF, [0; 7])[0])
24 //! }
25 //! ```
26
27 /// A value commonly returned to indicate a successful SMCCC call.
28 pub const SUCCESS: i32 = 0;
29
30 /// Converts the given value (returned from an HVC32 or SMC32 call) either to `Ok(())` if it is
31 /// equal to [`SUCCESS`], or else an error of the given type.
success_or_error_32<E: From<i32>>(value: u32) -> Result<(), E>32 pub fn success_or_error_32<E: From<i32>>(value: u32) -> Result<(), E> {
33 let value = value as i32;
34 if value == SUCCESS {
35 Ok(())
36 } else {
37 Err(value.into())
38 }
39 }
40
41 /// Converts the given value (returned from an HVC64 or SMC64 call) either to `Ok(())` if it is
42 /// equal to [`SUCCESS`], or else an error of the given type.
success_or_error_64<E: From<i64>>(value: u64) -> Result<(), E>43 pub fn success_or_error_64<E: From<i64>>(value: u64) -> Result<(), E> {
44 let value = value as i64;
45 if value == SUCCESS.into() {
46 Ok(())
47 } else {
48 Err(value.into())
49 }
50 }
51
52 /// Returns `Ok(value)` if the given value has its high bit unset (i.e. would be positive when
53 /// treated as a signed value), or an error of the given type if the high bit is set.
54 ///
55 /// This is intended to be used with the return value of [`hvc32`](super::hvc32) or
56 /// [`smc32`](super::smc32).
positive_or_error_32<E: From<i32>>(value: u32) -> Result<u32, E>57 pub fn positive_or_error_32<E: From<i32>>(value: u32) -> Result<u32, E> {
58 let signed = value as i32;
59 if signed < 0 {
60 Err(signed.into())
61 } else {
62 Ok(value)
63 }
64 }
65
66 /// Returns `Ok(value)` if the given value has its high bit unset (i.e. would be positive when
67 /// treated as a signed value), or an error of the given type if the high bit is set.
68 ///
69 /// This is intended to be used with the return value of [`hvc64`](super::hvc64) or
70 /// [`smc64`](super::smc64).
positive_or_error_64<E: From<i64>>(value: u64) -> Result<u64, E>71 pub fn positive_or_error_64<E: From<i64>>(value: u64) -> Result<u64, E> {
72 let signed = value as i64;
73 if signed < 0 {
74 Err(signed.into())
75 } else {
76 Ok(value)
77 }
78 }
79