162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef _TOOLS_LINUX_ASM_AARCH64_BARRIER_H 362306a36Sopenharmony_ci#define _TOOLS_LINUX_ASM_AARCH64_BARRIER_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci/* 662306a36Sopenharmony_ci * From tools/perf/perf-sys.h, last modified in: 762306a36Sopenharmony_ci * f428ebd184c82a7914b2aa7e9f868918aaf7ea78 perf tools: Fix AAAAARGH64 memory barriers 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * XXX: arch/arm64/include/asm/barrier.h in the kernel sources use dsb, is this 1062306a36Sopenharmony_ci * a case like for arm32 where we do things differently in userspace? 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#define mb() asm volatile("dmb ish" ::: "memory") 1462306a36Sopenharmony_ci#define wmb() asm volatile("dmb ishst" ::: "memory") 1562306a36Sopenharmony_ci#define rmb() asm volatile("dmb ishld" ::: "memory") 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci/* 1862306a36Sopenharmony_ci * Kernel uses dmb variants on arm64 for smp_*() barriers. Pretty much the same 1962306a36Sopenharmony_ci * implementation as above mb()/wmb()/rmb(), though for the latter kernel uses 2062306a36Sopenharmony_ci * dsb. In any case, should above mb()/wmb()/rmb() change, make sure the below 2162306a36Sopenharmony_ci * smp_*() don't. 2262306a36Sopenharmony_ci */ 2362306a36Sopenharmony_ci#define smp_mb() asm volatile("dmb ish" ::: "memory") 2462306a36Sopenharmony_ci#define smp_wmb() asm volatile("dmb ishst" ::: "memory") 2562306a36Sopenharmony_ci#define smp_rmb() asm volatile("dmb ishld" ::: "memory") 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#define smp_store_release(p, v) \ 2862306a36Sopenharmony_cido { \ 2962306a36Sopenharmony_ci union { typeof(*p) __val; char __c[1]; } __u = \ 3062306a36Sopenharmony_ci { .__val = (v) }; \ 3162306a36Sopenharmony_ci \ 3262306a36Sopenharmony_ci switch (sizeof(*p)) { \ 3362306a36Sopenharmony_ci case 1: \ 3462306a36Sopenharmony_ci asm volatile ("stlrb %w1, %0" \ 3562306a36Sopenharmony_ci : "=Q" (*p) \ 3662306a36Sopenharmony_ci : "r" (*(__u8_alias_t *)__u.__c) \ 3762306a36Sopenharmony_ci : "memory"); \ 3862306a36Sopenharmony_ci break; \ 3962306a36Sopenharmony_ci case 2: \ 4062306a36Sopenharmony_ci asm volatile ("stlrh %w1, %0" \ 4162306a36Sopenharmony_ci : "=Q" (*p) \ 4262306a36Sopenharmony_ci : "r" (*(__u16_alias_t *)__u.__c) \ 4362306a36Sopenharmony_ci : "memory"); \ 4462306a36Sopenharmony_ci break; \ 4562306a36Sopenharmony_ci case 4: \ 4662306a36Sopenharmony_ci asm volatile ("stlr %w1, %0" \ 4762306a36Sopenharmony_ci : "=Q" (*p) \ 4862306a36Sopenharmony_ci : "r" (*(__u32_alias_t *)__u.__c) \ 4962306a36Sopenharmony_ci : "memory"); \ 5062306a36Sopenharmony_ci break; \ 5162306a36Sopenharmony_ci case 8: \ 5262306a36Sopenharmony_ci asm volatile ("stlr %1, %0" \ 5362306a36Sopenharmony_ci : "=Q" (*p) \ 5462306a36Sopenharmony_ci : "r" (*(__u64_alias_t *)__u.__c) \ 5562306a36Sopenharmony_ci : "memory"); \ 5662306a36Sopenharmony_ci break; \ 5762306a36Sopenharmony_ci default: \ 5862306a36Sopenharmony_ci /* Only to shut up gcc ... */ \ 5962306a36Sopenharmony_ci mb(); \ 6062306a36Sopenharmony_ci break; \ 6162306a36Sopenharmony_ci } \ 6262306a36Sopenharmony_ci} while (0) 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci#define smp_load_acquire(p) \ 6562306a36Sopenharmony_ci({ \ 6662306a36Sopenharmony_ci union { typeof(*p) __val; char __c[1]; } __u = \ 6762306a36Sopenharmony_ci { .__c = { 0 } }; \ 6862306a36Sopenharmony_ci \ 6962306a36Sopenharmony_ci switch (sizeof(*p)) { \ 7062306a36Sopenharmony_ci case 1: \ 7162306a36Sopenharmony_ci asm volatile ("ldarb %w0, %1" \ 7262306a36Sopenharmony_ci : "=r" (*(__u8_alias_t *)__u.__c) \ 7362306a36Sopenharmony_ci : "Q" (*p) : "memory"); \ 7462306a36Sopenharmony_ci break; \ 7562306a36Sopenharmony_ci case 2: \ 7662306a36Sopenharmony_ci asm volatile ("ldarh %w0, %1" \ 7762306a36Sopenharmony_ci : "=r" (*(__u16_alias_t *)__u.__c) \ 7862306a36Sopenharmony_ci : "Q" (*p) : "memory"); \ 7962306a36Sopenharmony_ci break; \ 8062306a36Sopenharmony_ci case 4: \ 8162306a36Sopenharmony_ci asm volatile ("ldar %w0, %1" \ 8262306a36Sopenharmony_ci : "=r" (*(__u32_alias_t *)__u.__c) \ 8362306a36Sopenharmony_ci : "Q" (*p) : "memory"); \ 8462306a36Sopenharmony_ci break; \ 8562306a36Sopenharmony_ci case 8: \ 8662306a36Sopenharmony_ci asm volatile ("ldar %0, %1" \ 8762306a36Sopenharmony_ci : "=r" (*(__u64_alias_t *)__u.__c) \ 8862306a36Sopenharmony_ci : "Q" (*p) : "memory"); \ 8962306a36Sopenharmony_ci break; \ 9062306a36Sopenharmony_ci default: \ 9162306a36Sopenharmony_ci /* Only to shut up gcc ... */ \ 9262306a36Sopenharmony_ci mb(); \ 9362306a36Sopenharmony_ci break; \ 9462306a36Sopenharmony_ci } \ 9562306a36Sopenharmony_ci __u.__val; \ 9662306a36Sopenharmony_ci}) 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci#endif /* _TOOLS_LINUX_ASM_AARCH64_BARRIER_H */ 99