blob: e3673f73872c7e6ca4992e1c9009a25d6fd51054 [file] [log] [blame]
// 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));
}
}