aboutsummaryrefslogtreecommitdiff
path: root/src/arch.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch.rs')
-rw-r--r--src/arch.rs88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/arch.rs b/src/arch.rs
new file mode 100644
index 0000000..e3673f7
--- /dev/null
+++ b/src/arch.rs
@@ -0,0 +1,88 @@
+// Copyright 2023 the authors.
+// This project is dual-licensed under Apache 2.0 and MIT terms.
+// See LICENSE-APACHE and LICENSE-MIT for details.
+
+//! Standard Arm architecture calls.
+
+mod calls;
+pub mod error;
+
+pub use calls::{
+ arch_workaround_1, arch_workaround_2, arch_workaround_3, features, soc_id, version,
+};
+use core::fmt::{self, Debug, Display, Formatter};
+pub use error::Error;
+
+pub const SMCCC_VERSION: u32 = 0x8000_0000;
+pub const SMCCC_ARCH_FEATURES: u32 = 0x8000_0001;
+pub const SMCCC_ARCH_SOC_ID: u32 = 0x8000_0002;
+pub const SMCCC_ARCH_WORKAROUND_1: u32 = 0x8000_8000;
+pub const SMCCC_ARCH_WORKAROUND_2: u32 = 0x8000_7FFF;
+pub const SMCCC_ARCH_WORKAROUND_3: u32 = 0x8000_3FFF;
+
+/// A version of the SMC Calling Convention.
+#[derive(Copy, Clone, Eq, Ord, PartialEq, PartialOrd)]
+pub struct Version {
+ pub major: u16,
+ pub minor: u16,
+}
+
+impl Display for Version {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(f, "{}.{}", self.major, self.minor)
+ }
+}
+
+impl Debug for Version {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ Display::fmt(self, f)
+ }
+}
+
+impl TryFrom<i32> for Version {
+ type Error = Error;
+
+ fn try_from(value: i32) -> Result<Self, Error> {
+ if value < 0 {
+ Err(value.into())
+ } else {
+ Ok(Self {
+ major: (value >> 16) as u16,
+ minor: value as u16,
+ })
+ }
+ }
+}
+
+impl From<Version> for u32 {
+ fn from(version: Version) -> Self {
+ u32::from(version.major) << 16 | u32::from(version.minor)
+ }
+}
+
+#[derive(Copy, Clone, Eq, Ord, PartialEq, PartialOrd)]
+#[repr(u32)]
+pub enum SocIdType {
+ /// The SoC version.
+ Version,
+ /// The SoC revision.
+ Revision,
+}
+
+impl From<SocIdType> for u32 {
+ fn from(id_type: SocIdType) -> Self {
+ id_type as Self
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn convert_version() {
+ let version = Version { major: 1, minor: 2 };
+ assert_eq!(u32::from(version), 0x0001_0002);
+ assert_eq!(0x0001_0002.try_into(), Ok(version));
+ }
+}