Skip to content

Commit f2ce94c

Browse files
authored
std_detect: Support run-time detection of FEAT_LSE2 on aarch64 BSD (rust-lang#1379)
1 parent 5b169ef commit f2ce94c

File tree

3 files changed

+25
-10
lines changed

3 files changed

+25
-10
lines changed

crates/std_detect/src/detect/os/aarch64.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
//!
1616
//! - [Zircon implementation](https://fuchsia.googlesource.com/zircon/+/master/kernel/arch/arm64/feature.cpp)
1717
//! - [Linux documentation](https://www.kernel.org/doc/Documentation/arm64/cpu-feature-registers.txt)
18+
//! - [ARM documentation](https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers?lang=en)
1819
1920
use crate::detect::{cache, Feature};
2021
use core::arch::asm;
@@ -43,6 +44,16 @@ pub(crate) fn detect_features() -> cache::Initializer {
4344
);
4445
}
4546

47+
// ID_AA64MMFR2_EL1 - AArch64 Memory Model Feature Register 2
48+
let aa64mmfr2: u64;
49+
unsafe {
50+
asm!(
51+
"mrs {}, ID_AA64MMFR2_EL1",
52+
out(reg) aa64mmfr2,
53+
options(pure, nomem, preserves_flags, nostack)
54+
);
55+
}
56+
4657
// ID_AA64PFR0_EL1 - Processor Feature Register 0
4758
let aa64pfr0: u64;
4859
unsafe {
@@ -53,12 +64,13 @@ pub(crate) fn detect_features() -> cache::Initializer {
5364
);
5465
}
5566

56-
parse_system_registers(aa64isar0, aa64isar1, Some(aa64pfr0))
67+
parse_system_registers(aa64isar0, aa64isar1, aa64mmfr2, Some(aa64pfr0))
5768
}
5869

5970
pub(crate) fn parse_system_registers(
6071
aa64isar0: u64,
6172
aa64isar1: u64,
73+
aa64mmfr2: u64,
6274
aa64pfr0: Option<u64>,
6375
) -> cache::Initializer {
6476
let mut value = cache::Initializer::default();
@@ -72,7 +84,7 @@ pub(crate) fn parse_system_registers(
7284
// ID_AA64ISAR0_EL1 - Instruction Set Attribute Register 0
7385
enable_feature(Feature::pmull, bits_shift(aa64isar0, 7, 4) >= 2);
7486
enable_feature(Feature::tme, bits_shift(aa64isar0, 27, 24) == 1);
75-
enable_feature(Feature::lse, bits_shift(aa64isar0, 23, 20) >= 1);
87+
enable_feature(Feature::lse, bits_shift(aa64isar0, 23, 20) >= 2);
7688
enable_feature(Feature::crc, bits_shift(aa64isar0, 19, 16) >= 1);
7789

7890
// ID_AA64PFR0_EL1 - Processor Feature Register 0
@@ -99,13 +111,16 @@ pub(crate) fn parse_system_registers(
99111
enable_feature(Feature::sve, asimd && bits_shift(aa64pfr0, 35, 32) >= 1);
100112
}
101113

102-
// ID_AA64PFR0_EL1 - Processor Feature Register 0
114+
// ID_AA64ISAR1_EL1 - Instruction Set Attribute Register 1
103115
// Check for either APA or API field
104116
enable_feature(Feature::paca, bits_shift(aa64isar1, 11, 4) >= 1);
105117
enable_feature(Feature::rcpc, bits_shift(aa64isar1, 23, 20) >= 1);
106118
// Check for either GPA or GPI field
107119
enable_feature(Feature::pacg, bits_shift(aa64isar1, 31, 24) >= 1);
108120

121+
// ID_AA64MMFR2_EL1 - AArch64 Memory Model Feature Register 2
122+
enable_feature(Feature::lse2, bits_shift(aa64mmfr2, 35, 32) >= 1);
123+
109124
value
110125
}
111126

crates/std_detect/src/detect/os/openbsd/aarch64.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,11 @@
77
use crate::detect::cache;
88
use core::{mem::MaybeUninit, ptr};
99

10-
// Defined in sys/sysctl.h.
11-
// https://github.com/openbsd/src/blob/72ccc03bd11da614f31f7ff76e3f6fce99bc1c79/sys/sys/sysctl.h#L82
12-
const CTL_MACHDEP: libc::c_int = 7;
1310
// Defined in machine/cpu.h.
1411
// https://github.com/openbsd/src/blob/72ccc03bd11da614f31f7ff76e3f6fce99bc1c79/sys/arch/arm64/include/cpu.h#L25-L40
1512
const CPU_ID_AA64ISAR0: libc::c_int = 2;
1613
const CPU_ID_AA64ISAR1: libc::c_int = 3;
14+
const CPU_ID_AA64MMFR2: libc::c_int = 7;
1715
const CPU_ID_AA64PFR0: libc::c_int = 8;
1816

1917
/// Try to read the features from the system registers.
@@ -24,13 +22,14 @@ pub(crate) fn detect_features() -> cache::Initializer {
2422
// https://github.com/openbsd/src/commit/c7654cd65262d532212f65123ee3905ba200365c
2523
// sysctl returns an unsupported error if operation is not supported,
2624
// so we can safely use this function on older versions of OpenBSD.
27-
let aa64isar0 = sysctl64(&[CTL_MACHDEP, CPU_ID_AA64ISAR0]).unwrap_or(0);
28-
let aa64isar1 = sysctl64(&[CTL_MACHDEP, CPU_ID_AA64ISAR1]).unwrap_or(0);
25+
let aa64isar0 = sysctl64(&[libc::CTL_MACHDEP, CPU_ID_AA64ISAR0]).unwrap_or(0);
26+
let aa64isar1 = sysctl64(&[libc::CTL_MACHDEP, CPU_ID_AA64ISAR1]).unwrap_or(0);
27+
let aa64mmfr2 = sysctl64(&[libc::CTL_MACHDEP, CPU_ID_AA64MMFR2]).unwrap_or(0);
2928
// Do not use unwrap_or(0) because in fp and asimd fields, 0 indicates that
3029
// the feature is available.
31-
let aa64pfr0 = sysctl64(&[CTL_MACHDEP, CPU_ID_AA64PFR0]);
30+
let aa64pfr0 = sysctl64(&[libc::CTL_MACHDEP, CPU_ID_AA64PFR0]);
3231

33-
super::aarch64::parse_system_registers(aa64isar0, aa64isar1, aa64pfr0)
32+
super::aarch64::parse_system_registers(aa64isar0, aa64isar1, aa64mmfr2, aa64pfr0)
3433
}
3534

3635
#[inline]

crates/std_detect/tests/cpu-detection.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ fn aarch64_bsd() {
110110
println!("sve: {:?}", is_aarch64_feature_detected!("sve"));
111111
println!("crc: {:?}", is_aarch64_feature_detected!("crc"));
112112
println!("lse: {:?}", is_aarch64_feature_detected!("lse"));
113+
println!("lse2: {:?}", is_aarch64_feature_detected!("lse2"));
113114
println!("rdm: {:?}", is_aarch64_feature_detected!("rdm"));
114115
println!("rcpc: {:?}", is_aarch64_feature_detected!("rcpc"));
115116
println!("dotprod: {:?}", is_aarch64_feature_detected!("dotprod"));

0 commit comments

Comments
 (0)