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 //! Standard Arm architecture calls.
6 
7 mod calls;
8 pub mod error;
9 
10 pub use calls::{
11     arch_workaround_1, arch_workaround_2, arch_workaround_3, features, soc_id, version,
12 };
13 use core::fmt::{self, Debug, Display, Formatter};
14 pub use error::Error;
15 
16 pub const SMCCC_VERSION: u32 = 0x8000_0000;
17 pub const SMCCC_ARCH_FEATURES: u32 = 0x8000_0001;
18 pub const SMCCC_ARCH_SOC_ID: u32 = 0x8000_0002;
19 pub const SMCCC_ARCH_WORKAROUND_1: u32 = 0x8000_8000;
20 pub const SMCCC_ARCH_WORKAROUND_2: u32 = 0x8000_7FFF;
21 pub const SMCCC_ARCH_WORKAROUND_3: u32 = 0x8000_3FFF;
22 
23 /// A version of the SMC Calling Convention.
24 #[derive(Copy, Clone, Eq, Ord, PartialEq, PartialOrd)]
25 pub struct Version {
26     pub major: u16,
27     pub minor: u16,
28 }
29 
30 impl Display for Version {
fmt(&self, f: &mut Formatter) -> fmt::Result31     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
32         write!(f, "{}.{}", self.major, self.minor)
33     }
34 }
35 
36 impl Debug for Version {
fmt(&self, f: &mut Formatter) -> fmt::Result37     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
38         Display::fmt(self, f)
39     }
40 }
41 
42 impl TryFrom<i32> for Version {
43     type Error = Error;
44 
try_from(value: i32) -> Result<Self, Error>45     fn try_from(value: i32) -> Result<Self, Error> {
46         if value < 0 {
47             Err(value.into())
48         } else {
49             Ok(Self {
50                 major: (value >> 16) as u16,
51                 minor: value as u16,
52             })
53         }
54     }
55 }
56 
57 impl From<Version> for u32 {
from(version: Version) -> Self58     fn from(version: Version) -> Self {
59         u32::from(version.major) << 16 | u32::from(version.minor)
60     }
61 }
62 
63 #[derive(Copy, Clone, Eq, Ord, PartialEq, PartialOrd)]
64 #[repr(u32)]
65 pub enum SocIdType {
66     /// The SoC version.
67     Version,
68     /// The SoC revision.
69     Revision,
70 }
71 
72 impl From<SocIdType> for u32 {
from(id_type: SocIdType) -> Self73     fn from(id_type: SocIdType) -> Self {
74         id_type as Self
75     }
76 }
77 
78 #[cfg(test)]
79 mod tests {
80     use super::*;
81 
82     #[test]
convert_version()83     fn convert_version() {
84         let version = Version { major: 1, minor: 2 };
85         assert_eq!(u32::from(version), 0x0001_0002);
86         assert_eq!(0x0001_0002.try_into(), Ok(version));
87     }
88 }
89