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