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