diff --git a/library/stdarch/crates/std_detect/src/detect/os/aarch64.rs b/library/stdarch/crates/std_detect/src/detect/os/aarch64.rs index 7f860f44ebe1..5790f016834c 100644 --- a/library/stdarch/crates/std_detect/src/detect/os/aarch64.rs +++ b/library/stdarch/crates/std_detect/src/detect/os/aarch64.rs @@ -15,6 +15,7 @@ //! //! - [Zircon implementation](https://fuchsia.googlesource.com/zircon/+/master/kernel/arch/arm64/feature.cpp) //! - [Linux documentation](https://www.kernel.org/doc/Documentation/arm64/cpu-feature-registers.txt) +//! - [ARM documentation](https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers?lang=en) use crate::detect::{cache, Feature}; use core::arch::asm; @@ -43,6 +44,16 @@ pub(crate) fn detect_features() -> cache::Initializer { ); } + // ID_AA64MMFR2_EL1 - AArch64 Memory Model Feature Register 2 + let aa64mmfr2: u64; + unsafe { + asm!( + "mrs {}, ID_AA64MMFR2_EL1", + out(reg) aa64mmfr2, + options(pure, nomem, preserves_flags, nostack) + ); + } + // ID_AA64PFR0_EL1 - Processor Feature Register 0 let aa64pfr0: u64; unsafe { @@ -53,12 +64,13 @@ pub(crate) fn detect_features() -> cache::Initializer { ); } - parse_system_registers(aa64isar0, aa64isar1, Some(aa64pfr0)) + parse_system_registers(aa64isar0, aa64isar1, aa64mmfr2, Some(aa64pfr0)) } pub(crate) fn parse_system_registers( aa64isar0: u64, aa64isar1: u64, + aa64mmfr2: u64, aa64pfr0: Option, ) -> cache::Initializer { let mut value = cache::Initializer::default(); @@ -72,7 +84,7 @@ pub(crate) fn parse_system_registers( // ID_AA64ISAR0_EL1 - Instruction Set Attribute Register 0 enable_feature(Feature::pmull, bits_shift(aa64isar0, 7, 4) >= 2); enable_feature(Feature::tme, bits_shift(aa64isar0, 27, 24) == 1); - enable_feature(Feature::lse, bits_shift(aa64isar0, 23, 20) >= 1); + enable_feature(Feature::lse, bits_shift(aa64isar0, 23, 20) >= 2); enable_feature(Feature::crc, bits_shift(aa64isar0, 19, 16) >= 1); // ID_AA64PFR0_EL1 - Processor Feature Register 0 @@ -99,13 +111,16 @@ pub(crate) fn parse_system_registers( enable_feature(Feature::sve, asimd && bits_shift(aa64pfr0, 35, 32) >= 1); } - // ID_AA64PFR0_EL1 - Processor Feature Register 0 + // ID_AA64ISAR1_EL1 - Instruction Set Attribute Register 1 // Check for either APA or API field enable_feature(Feature::paca, bits_shift(aa64isar1, 11, 4) >= 1); enable_feature(Feature::rcpc, bits_shift(aa64isar1, 23, 20) >= 1); // Check for either GPA or GPI field enable_feature(Feature::pacg, bits_shift(aa64isar1, 31, 24) >= 1); + // ID_AA64MMFR2_EL1 - AArch64 Memory Model Feature Register 2 + enable_feature(Feature::lse2, bits_shift(aa64mmfr2, 35, 32) >= 1); + value } diff --git a/library/stdarch/crates/std_detect/src/detect/os/openbsd/aarch64.rs b/library/stdarch/crates/std_detect/src/detect/os/openbsd/aarch64.rs index 068dcba7db76..cfe4ad10ad64 100644 --- a/library/stdarch/crates/std_detect/src/detect/os/openbsd/aarch64.rs +++ b/library/stdarch/crates/std_detect/src/detect/os/openbsd/aarch64.rs @@ -7,13 +7,11 @@ use crate::detect::cache; use core::{mem::MaybeUninit, ptr}; -// Defined in sys/sysctl.h. -// https://github.com/openbsd/src/blob/72ccc03bd11da614f31f7ff76e3f6fce99bc1c79/sys/sys/sysctl.h#L82 -const CTL_MACHDEP: libc::c_int = 7; // Defined in machine/cpu.h. // https://github.com/openbsd/src/blob/72ccc03bd11da614f31f7ff76e3f6fce99bc1c79/sys/arch/arm64/include/cpu.h#L25-L40 const CPU_ID_AA64ISAR0: libc::c_int = 2; const CPU_ID_AA64ISAR1: libc::c_int = 3; +const CPU_ID_AA64MMFR2: libc::c_int = 7; const CPU_ID_AA64PFR0: libc::c_int = 8; /// Try to read the features from the system registers. @@ -24,13 +22,14 @@ pub(crate) fn detect_features() -> cache::Initializer { // https://github.com/openbsd/src/commit/c7654cd65262d532212f65123ee3905ba200365c // sysctl returns an unsupported error if operation is not supported, // so we can safely use this function on older versions of OpenBSD. - let aa64isar0 = sysctl64(&[CTL_MACHDEP, CPU_ID_AA64ISAR0]).unwrap_or(0); - let aa64isar1 = sysctl64(&[CTL_MACHDEP, CPU_ID_AA64ISAR1]).unwrap_or(0); + let aa64isar0 = sysctl64(&[libc::CTL_MACHDEP, CPU_ID_AA64ISAR0]).unwrap_or(0); + let aa64isar1 = sysctl64(&[libc::CTL_MACHDEP, CPU_ID_AA64ISAR1]).unwrap_or(0); + let aa64mmfr2 = sysctl64(&[libc::CTL_MACHDEP, CPU_ID_AA64MMFR2]).unwrap_or(0); // Do not use unwrap_or(0) because in fp and asimd fields, 0 indicates that // the feature is available. - let aa64pfr0 = sysctl64(&[CTL_MACHDEP, CPU_ID_AA64PFR0]); + let aa64pfr0 = sysctl64(&[libc::CTL_MACHDEP, CPU_ID_AA64PFR0]); - super::aarch64::parse_system_registers(aa64isar0, aa64isar1, aa64pfr0) + super::aarch64::parse_system_registers(aa64isar0, aa64isar1, aa64mmfr2, aa64pfr0) } #[inline] diff --git a/library/stdarch/crates/std_detect/tests/cpu-detection.rs b/library/stdarch/crates/std_detect/tests/cpu-detection.rs index ec0875a355ed..4fa1b717c8e1 100644 --- a/library/stdarch/crates/std_detect/tests/cpu-detection.rs +++ b/library/stdarch/crates/std_detect/tests/cpu-detection.rs @@ -110,6 +110,7 @@ fn aarch64_bsd() { println!("sve: {:?}", is_aarch64_feature_detected!("sve")); println!("crc: {:?}", is_aarch64_feature_detected!("crc")); println!("lse: {:?}", is_aarch64_feature_detected!("lse")); + println!("lse2: {:?}", is_aarch64_feature_detected!("lse2")); println!("rdm: {:?}", is_aarch64_feature_detected!("rdm")); println!("rcpc: {:?}", is_aarch64_feature_detected!("rcpc")); println!("dotprod: {:?}", is_aarch64_feature_detected!("dotprod"));