Skip to content

Commit

Permalink
detect/aa64reg: Next release of OpenBSD no longer always return 0 for…
Browse files Browse the repository at this point in the history
… AA64MMFR2

openbsd/src@e8331b7
  • Loading branch information
taiki-e committed Aug 24, 2024
1 parent f0451c6 commit 4f8c735
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 41 deletions.
2 changes: 1 addition & 1 deletion src/imp/atomic128/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Here is the table of targets that support run-time feature detection and the ins
| aarch64 | android | getauxval | all | Enabled by default |
| aarch64 | freebsd | elf_aux_info | lse, lse2 | Enabled by default |
| aarch64 | netbsd | sysctl | all | Enabled by default |
| aarch64 | openbsd | sysctl | lse | Enabled by default |
| aarch64 | openbsd | sysctl | all | Enabled by default |
| aarch64 | macos | sysctl | all | Currently only used in tests because FEAT_LSE and FEAT_LSE2 are always available at compile-time. |
| aarch64 | windows | IsProcessorFeaturePresent | lse | Enabled by default |
| aarch64 | fuchsia | zx_system_get_features | lse | Enabled by default |
Expand Down
31 changes: 12 additions & 19 deletions src/imp/atomic128/aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,20 +90,13 @@ include!("macros.rs");
#[path = "detect/auxv.rs"]
mod detect;
#[cfg(not(portable_atomic_no_outline_atomics))]
#[cfg_attr(
target_os = "netbsd",
cfg(any(
test,
not(all(
any(target_feature = "lse2", portable_atomic_target_feature = "lse2"),
any(target_feature = "lse", portable_atomic_target_feature = "lse"),
)),
))
)]
#[cfg_attr(
target_os = "openbsd",
cfg(any(test, not(any(target_feature = "lse", portable_atomic_target_feature = "lse"))))
)]
#[cfg(any(
test,
not(all(
any(target_feature = "lse2", portable_atomic_target_feature = "lse2"),
any(target_feature = "lse", portable_atomic_target_feature = "lse"),
)),
))]
#[cfg(any(target_os = "netbsd", target_os = "openbsd"))]
#[path = "detect/aarch64_aa64reg.rs"]
mod detect;
Expand Down Expand Up @@ -198,8 +191,8 @@ macro_rules! debug_assert_lse2 {
target_os = "android",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
// These don't support detection of FEAT_LSE2.
// target_os = "openbsd",
// target_os = "fuchsia",
// target_os = "windows",
),
Expand Down Expand Up @@ -321,8 +314,8 @@ unsafe fn atomic_load(src: *mut u128, order: Ordering) -> u128 {
target_os = "android",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
// These don't support detection of FEAT_LSE2.
// target_os = "openbsd",
// target_os = "fuchsia",
// target_os = "windows",
),
Expand All @@ -348,8 +341,8 @@ unsafe fn atomic_load(src: *mut u128, order: Ordering) -> u128 {
target_os = "android",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
// These don't support detection of FEAT_LSE2.
// target_os = "openbsd",
// target_os = "fuchsia",
// target_os = "windows",
),
Expand Down Expand Up @@ -595,8 +588,8 @@ unsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) {
target_os = "android",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
// These don't support detection of FEAT_LSE2.
// target_os = "openbsd",
// target_os = "fuchsia",
// target_os = "windows",
),
Expand All @@ -622,8 +615,8 @@ unsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) {
target_os = "android",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
// These don't support detection of FEAT_LSE2.
// target_os = "openbsd",
// target_os = "fuchsia",
// target_os = "windows",
),
Expand Down
30 changes: 9 additions & 21 deletions src/imp/atomic128/detect/aarch64_aa64reg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ struct AA64Reg {
aa64isar0: u64,
#[cfg(test)]
aa64isar1: u64,
// OpenBSD has an API to get this, but currently always returns 0.
// https://github.com/openbsd/src/blob/6a233889798dc3ecb18acc52dce1e57862af2957/sys/arch/arm64/arm64/machdep.c#L371-L377
#[cfg_attr(target_os = "openbsd", cfg(test))]
aa64mmfr2: u64,
}

Expand All @@ -49,7 +46,6 @@ fn _detect(info: &mut CpuInfo) {
aa64isar0,
#[cfg(test)]
aa64isar1,
#[cfg_attr(target_os = "openbsd", cfg(test))]
aa64mmfr2,
} = imp::aa64reg();

Expand All @@ -75,15 +71,10 @@ fn _detect(info: &mut CpuInfo) {
info.set(CpuInfo::HAS_RCPC3);
}
}
// OpenBSD has an API to get AA64MMFR2, but currently always returns 0.
// https://github.com/openbsd/src/blob/1847475460684e4251d673e6b1bceb1b38e699c3/sys/arch/arm64/arm64/machdep.c#L367
#[cfg_attr(target_os = "openbsd", cfg(test))]
{
// ID_AA64MMFR2_EL1, AArch64 Memory Model Feature Register 2
// https://developer.arm.com/documentation/ddi0601/2023-06/AArch64-Registers/ID-AA64MMFR2-EL1--AArch64-Memory-Model-Feature-Register-2?lang=en
if extract(aa64mmfr2, 35, 32) >= 1 {
info.set(CpuInfo::HAS_LSE2);
}
// ID_AA64MMFR2_EL1, AArch64 Memory Model Feature Register 2
// https://developer.arm.com/documentation/ddi0601/2023-06/AArch64-Registers/ID-AA64MMFR2-EL1--AArch64-Memory-Model-Feature-Register-2?lang=en
if extract(aa64mmfr2, 35, 32) >= 1 {
info.set(CpuInfo::HAS_LSE2);
}
}

Expand Down Expand Up @@ -266,22 +257,19 @@ mod imp {
pub(crate) use super::super::c_types::{c_int, c_size_t, c_uint, c_void};

// Defined in sys/sysctl.h.
// https://github.com/openbsd/src/blob/72ccc03bd11da614f31f7ff76e3f6fce99bc1c79/sys/sys/sysctl.h#L82
// https://github.com/openbsd/src/blob/ed8f5e8d82ace15e4cefca2c82941b15cb1a7830/sys/sys/sysctl.h#L82
pub(crate) const CTL_MACHDEP: c_int = 7;
// Defined in machine/cpu.h.
// https://github.com/openbsd/src/blob/72ccc03bd11da614f31f7ff76e3f6fce99bc1c79/sys/arch/arm64/include/cpu.h#L25-L40
// https://github.com/openbsd/src/blob/ed8f5e8d82ace15e4cefca2c82941b15cb1a7830/sys/arch/arm64/include/cpu.h#L25-L40
pub(crate) const CPU_ID_AA64ISAR0: c_int = 2;
#[cfg(test)]
pub(crate) const CPU_ID_AA64ISAR1: c_int = 3;
// OpenBSD has an API to get this, but currently always returns 0.
// https://github.com/openbsd/src/blob/6a233889798dc3ecb18acc52dce1e57862af2957/sys/arch/arm64/arm64/machdep.c#L371-L377
#[cfg(test)]
pub(crate) const CPU_ID_AA64MMFR2: c_int = 7;

extern "C" {
// Defined in sys/sysctl.h.
// https://man.openbsd.org/sysctl.2
// https://github.com/openbsd/src/blob/72ccc03bd11da614f31f7ff76e3f6fce99bc1c79/sys/sys/sysctl.h
// https://github.com/openbsd/src/blob/ed8f5e8d82ace15e4cefca2c82941b15cb1a7830/sys/sys/sysctl.h
// https://github.com/rust-lang/libc/blob/0.2.139/src/unix/bsd/netbsdlike/openbsd/mod.rs#L1817-L1824
pub(crate) fn sysctl(
name: *const c_int,
Expand All @@ -298,19 +286,19 @@ mod imp {
// https://github.com/openbsd/src/commit/d335af936b9d7dd9cf655cae1ce19560c45de6c8
// Others are supported on OpenBSD 7.3+.
// https://github.com/openbsd/src/commit/c7654cd65262d532212f65123ee3905ba200365c
// However, on 7.3-7.5, querying AA64MMFR2 returned 0.
// https://github.com/openbsd/src/commit/e8331b74e5c20302d4bd948c9db722af688ccfc1
// sysctl returns an unsupported error if operation is not supported,
// so we can safely use this function on older versions of OpenBSD.
pub(super) fn aa64reg() -> AA64Reg {
let aa64isar0 = sysctl64(&[ffi::CTL_MACHDEP, ffi::CPU_ID_AA64ISAR0]).unwrap_or(0);
#[cfg(test)]
let aa64isar1 = sysctl64(&[ffi::CTL_MACHDEP, ffi::CPU_ID_AA64ISAR1]).unwrap_or(0);
#[cfg(test)]
let aa64mmfr2 = sysctl64(&[ffi::CTL_MACHDEP, ffi::CPU_ID_AA64MMFR2]).unwrap_or(0);
AA64Reg {
aa64isar0,
#[cfg(test)]
aa64isar1,
#[cfg(test)]
aa64mmfr2,
}
}
Expand Down

0 comments on commit 4f8c735

Please sign in to comment.