diff --git a/platform/linux-generic/arch/aarch64/cpu_flags.c b/platform/linux-generic/arch/aarch64/cpu_flags.c index 35ef7c1f0a..244aca0761 100644 --- a/platform/linux-generic/arch/aarch64/cpu_flags.c +++ b/platform/linux-generic/arch/aarch64/cpu_flags.c @@ -992,6 +992,13 @@ static void _odp_sys_info_print_acle_flags(void) _ODP_PRINT("%s\n", ndef); #endif + _ODP_PRINT(" __ARM_FEATURE_WFXT "); +#ifdef __ARM_FEATURE_WFXT + _ODP_PRINT("%i\n", __ARM_FEATURE_WFXT); +#else + _ODP_PRINT("%s\n", ndef); +#endif + _ODP_PRINT("\n"); } diff --git a/platform/linux-generic/arch/aarch64/odp/api/abi/wait_until.h b/platform/linux-generic/arch/aarch64/odp/api/abi/wait_until.h index 61fc6e96e5..7ca0bc9d5a 100644 --- a/platform/linux-generic/arch/aarch64/odp/api/abi/wait_until.h +++ b/platform/linux-generic/arch/aarch64/odp/api/abi/wait_until.h @@ -33,6 +33,32 @@ _odp_wait_until_equal_acq_u32(odp_atomic_u32_t *addr, uint32_t expected) } while (expected != value); } +static inline void +_odp_wait_until_equal_rel_u32(odp_atomic_u32_t *addr, uint32_t expected) +{ + uint32_t value; + uint32_t *var = &addr->v; + + __asm__ volatile("sevl" : : : "memory"); + do { + #ifdef __ARM_FEATURE_WFXT + __asm__ volatile("wfet %x0" : : "r"(100) : "memory"); + #else + __asm__ volatile("wfe" : : : "memory"); + #endif + __asm__ volatile("ldxr %w0, [%1]" + : "=&r" (value) + : "r" (var) + : "memory"); + } while (expected != value); +} + +static inline void +_odp_wait_until_equal_32(odp_atomic_u32_t *addr, uint32_t expected) +{ + _odp_wait_until_equal_rel_u32(addr, expected); +} + #ifdef __cplusplus } #endif diff --git a/platform/linux-generic/arch/default/odp/api/abi/wait_until_generic.h b/platform/linux-generic/arch/default/odp/api/abi/wait_until_generic.h index a476aa09f3..1e72d26c0e 100644 --- a/platform/linux-generic/arch/default/odp/api/abi/wait_until_generic.h +++ b/platform/linux-generic/arch/default/odp/api/abi/wait_until_generic.h @@ -18,6 +18,12 @@ _odp_wait_until_equal_acq_u32(odp_atomic_u32_t *addr, uint32_t expected) odp_cpu_pause(); } +static inline void +_odp_wait_until_equal_u32(odp_atomic_u32_t *addr, uint32_t expected) +{ + while (odp_atomic_load_u32(addr) != expected) + odp_cpu_pause(); +} #ifdef __cplusplus } #endif