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::system_off) function is implemented approximately as:
11 //!
12 //! ```
13 //! use psci::{
14 //! error::Error,
15 //! smccc::{error::success_or_error_32, smc32},
16 //! PSCI_SYSTEM_OFF,
17 //! };
18 //!
19 //! pub fn system_off() -> Result<(), Error> {
20 //! success_or_error_32(smc32(PSCI_SYSTEM_OFF, [0; 7])[0])
21 //! }
22 //! ```
23
24 /// A value commonly returned to indicate a successful SMCCC call.
25 pub const SUCCESS: i32 = 0;
26
27 /// Converts the given value (returned from an HVC32 or SMC32 call) either to `Ok(())` if it is
28 /// equal to [`SUCCESS`], or else an error of the given type.
success_or_error_32<E: From<i32>>(value: u32) -> Result<(), E>29 pub fn success_or_error_32<E: From<i32>>(value: u32) -> Result<(), E> {
30 let value = value as i32;
31 if value == SUCCESS {
32 Ok(())
33 } else {
34 Err(value.into())
35 }
36 }
37
38 /// Converts the given value (returned from an HVC64 or SMC64 call) either to `Ok(())` if it is
39 /// equal to [`SUCCESS`], or else an error of the given type.
success_or_error_64<E: From<i64>>(value: u64) -> Result<(), E>40 pub fn success_or_error_64<E: From<i64>>(value: u64) -> Result<(), E> {
41 let value = value as i64;
42 if value == SUCCESS.into() {
43 Ok(())
44 } else {
45 Err(value.into())
46 }
47 }
48
49 /// Returns `Ok(value)` if the given value has its high bit unset (i.e. would be positive when
50 /// treated as a signed value), or an error of the given type if the high bit is set.
51 ///
52 /// This is intended to be used with the return value of [`hvc32`](super::hvc32) or
53 /// [`smc32`](super::smc32).
positive_or_error_32<E: From<i32>>(value: u32) -> Result<u32, E>54 pub fn positive_or_error_32<E: From<i32>>(value: u32) -> Result<u32, E> {
55 let signed = value as i32;
56 if signed < 0 {
57 Err(signed.into())
58 } else {
59 Ok(value)
60 }
61 }
62
63 /// Returns `Ok(value)` if the given value has its high bit unset (i.e. would be positive when
64 /// treated as a signed value), or an error of the given type if the high bit is set.
65 ///
66 /// This is intended to be used with the return value of [`hvc64`](super::hvc64) or
67 /// [`smc64`](super::smc64).
positive_or_error_64<E: From<i64>>(value: u64) -> Result<u64, E>68 pub fn positive_or_error_64<E: From<i64>>(value: u64) -> Result<u64, E> {
69 let signed = value as i64;
70 if signed < 0 {
71 Err(signed.into())
72 } else {
73 Ok(value)
74 }
75 }
76