aboutsummaryrefslogtreecommitdiff
path: root/libatomic/config/linux/aarch64/host-config.h
diff options
context:
space:
mode:
Diffstat (limited to 'libatomic/config/linux/aarch64/host-config.h')
-rw-r--r--libatomic/config/linux/aarch64/host-config.h34
1 files changed, 30 insertions, 4 deletions
diff --git a/libatomic/config/linux/aarch64/host-config.h b/libatomic/config/linux/aarch64/host-config.h
index d05e9eb..93f367d 100644
--- a/libatomic/config/linux/aarch64/host-config.h
+++ b/libatomic/config/linux/aarch64/host-config.h
@@ -33,6 +33,9 @@
#ifndef HWCAP_USCAT
# define HWCAP_USCAT (1 << 25)
#endif
+#ifndef HWCAP2_LRCPC3
+# define HWCAP2_LRCPC3 (1UL << 46)
+#endif
#ifndef HWCAP2_LSE128
# define HWCAP2_LSE128 (1UL << 47)
#endif
@@ -54,7 +57,7 @@ typedef struct __ifunc_arg_t {
#if defined (LAT_CAS_N)
# define LSE_ATOP
#elif defined (LAT_LOAD_N) || defined (LAT_STORE_N)
-# define LSE2_ATOP
+# define LSE2_LRCPC3_ATOP
#elif defined (LAT_EXCH_N) || defined (LAT_FIOR_N) || defined (LAT_FAND_N)
# define LSE128_ATOP
#endif
@@ -63,9 +66,10 @@ typedef struct __ifunc_arg_t {
# if defined (LSE_ATOP)
# define IFUNC_NCOND(N) 1
# define IFUNC_COND_1 (hwcap & HWCAP_ATOMICS)
-# elif defined (LSE2_ATOP)
-# define IFUNC_NCOND(N) 1
-# define IFUNC_COND_1 (has_lse2 (hwcap, features))
+# elif defined (LSE2_LRCPC3_ATOP)
+# define IFUNC_NCOND(N) 2
+# define IFUNC_COND_1 (has_rcpc3 (hwcap, features))
+# define IFUNC_COND_2 (has_lse2 (hwcap, features))
# elif defined (LSE128_ATOP)
# define IFUNC_NCOND(N) 1
# define IFUNC_COND_1 (has_lse128 (hwcap, features))
@@ -131,6 +135,28 @@ has_lse128 (unsigned long hwcap, const __ifunc_arg_t *features)
return false;
}
+/* LRCPC atomic support encoded in ID_AA64ISAR1_EL1.Atomic, bits[23:20]. The
+ expected value is 0b0011. Check that. */
+
+static inline bool
+has_rcpc3 (unsigned long hwcap, const __ifunc_arg_t *features)
+{
+ if (hwcap & _IFUNC_ARG_HWCAP
+ && features->_hwcap2 & HWCAP2_LRCPC3)
+ return true;
+ /* Try fallback feature check method to guarantee LRCPC3 is not implemented.
+
+ In the absence of HWCAP_CPUID, we are unable to check for RCPC3, return.
+ If feature check available, check LSE2 prerequisite before proceeding. */
+ if (!(hwcap & HWCAP_CPUID) || !(hwcap & HWCAP_USCAT))
+ return false;
+ unsigned long isar1;
+ asm volatile ("mrs %0, ID_AA64ISAR1_EL1" : "=r" (isar1));
+ if (AT_FEAT_FIELD (isar1) >= 3)
+ return true;
+ return false;
+}
+
#endif /* HAVE_IFUNC */
/* All 128-bit atomic functions are defined in aarch64/atomic_16.S. */