• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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