1 // Copyright 2022 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 //! PSCI error codes.
6 
7 pub use crate::error::SUCCESS;
8 use core::fmt::{self, Display, Formatter};
9 
10 pub const NOT_SUPPORTED: i32 = -1;
11 pub const INVALID_PARAMETERS: i32 = -2;
12 pub const DENIED: i32 = -3;
13 pub const ALREADY_ON: i32 = -4;
14 pub const ON_PENDING: i32 = -5;
15 pub const INTERNAL_FAILURE: i32 = -6;
16 pub const NOT_PRESENT: i32 = -7;
17 pub const DISABLED: i32 = -8;
18 pub const INVALID_ADDRESS: i32 = -9;
19 
20 /// Standard PSCI errors.
21 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
22 pub enum Error {
23     /// PSCI call not supported.
24     NotSupported,
25     /// Invalid parameters to PSCI call.
26     InvalidParameters,
27     /// PSCI call denied.
28     Denied,
29     /// Core already on.
30     AlreadyOn,
31     /// Core already being turned on.
32     OnPending,
33     /// Internal failure in PSCI call.
34     InternalFailure,
35     /// Trusted OS not present on target core.
36     NotPresent,
37     /// Core disabled.
38     Disabled,
39     /// Invalid address passed to PSCI call.
40     InvalidAddress,
41     /// An unexpected return value from a PSCI function.
42     Unknown(i64),
43 }
44 
45 impl From<Error> for i64 {
from(error: Error) -> i6446     fn from(error: Error) -> i64 {
47         match error {
48             Error::NotSupported => NOT_SUPPORTED.into(),
49             Error::InvalidParameters => INVALID_PARAMETERS.into(),
50             Error::Denied => DENIED.into(),
51             Error::AlreadyOn => ALREADY_ON.into(),
52             Error::OnPending => ON_PENDING.into(),
53             Error::InternalFailure => INTERNAL_FAILURE.into(),
54             Error::NotPresent => NOT_PRESENT.into(),
55             Error::Disabled => DISABLED.into(),
56             Error::InvalidAddress => INVALID_ADDRESS.into(),
57             Error::Unknown(value) => value,
58         }
59     }
60 }
61 
62 impl From<i32> for Error {
from(value: i32) -> Self63     fn from(value: i32) -> Self {
64         match value {
65             NOT_SUPPORTED => Error::NotSupported,
66             INVALID_PARAMETERS => Error::InvalidParameters,
67             DENIED => Error::Denied,
68             ALREADY_ON => Error::AlreadyOn,
69             ON_PENDING => Error::OnPending,
70             INTERNAL_FAILURE => Error::InternalFailure,
71             NOT_PRESENT => Error::NotPresent,
72             DISABLED => Error::Disabled,
73             INVALID_ADDRESS => Error::InvalidAddress,
74             _ => Error::Unknown(value.into()),
75         }
76     }
77 }
78 
79 impl From<i64> for Error {
from(value: i64) -> Self80     fn from(value: i64) -> Self {
81         if let Ok(value) = i32::try_from(value) {
82             value.into()
83         } else {
84             Error::Unknown(value)
85         }
86     }
87 }
88 
89 impl Display for Error {
fmt(&self, f: &mut Formatter) -> fmt::Result90     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
91         match self {
92             Self::NotSupported => write!(f, "PSCI call not supported"),
93             Self::InvalidParameters => write!(f, "Invalid parameters to PSCI call"),
94             Self::Denied => write!(f, "PSCI call denied"),
95             Self::AlreadyOn => write!(f, "Core already on"),
96             Self::OnPending => write!(f, "Core already being turned on"),
97             Self::InternalFailure => write!(f, "Internal failure in PSCI call"),
98             Self::NotPresent => write!(f, "Trusted OS not present on target core"),
99             Self::Disabled => write!(f, "Core disabled"),
100             Self::InvalidAddress => write!(f, "Invalid address passed to PSCI call"),
101             Self::Unknown(e) => write!(f, "Unknown PSCI return value {} ({0:#x})", e),
102         }
103     }
104 }
105