162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#include <stdlib.h> 362306a36Sopenharmony_ci#if defined(__i386__) || defined(__x86_64__) 462306a36Sopenharmony_ci#define barrier() asm volatile("" ::: "memory") 562306a36Sopenharmony_ci#define virt_mb() __sync_synchronize() 662306a36Sopenharmony_ci#define virt_rmb() barrier() 762306a36Sopenharmony_ci#define virt_wmb() barrier() 862306a36Sopenharmony_ci/* Atomic store should be enough, but gcc generates worse code in that case. */ 962306a36Sopenharmony_ci#define virt_store_mb(var, value) do { \ 1062306a36Sopenharmony_ci typeof(var) virt_store_mb_value = (value); \ 1162306a36Sopenharmony_ci __atomic_exchange(&(var), &virt_store_mb_value, &virt_store_mb_value, \ 1262306a36Sopenharmony_ci __ATOMIC_SEQ_CST); \ 1362306a36Sopenharmony_ci barrier(); \ 1462306a36Sopenharmony_ci} while (0); 1562306a36Sopenharmony_ci/* Weak barriers should be used. If not - it's a bug */ 1662306a36Sopenharmony_ci# define mb() abort() 1762306a36Sopenharmony_ci# define dma_rmb() abort() 1862306a36Sopenharmony_ci# define dma_wmb() abort() 1962306a36Sopenharmony_ci#elif defined(__aarch64__) 2062306a36Sopenharmony_ci#define dmb(opt) asm volatile("dmb " #opt : : : "memory") 2162306a36Sopenharmony_ci#define virt_mb() __sync_synchronize() 2262306a36Sopenharmony_ci#define virt_rmb() dmb(ishld) 2362306a36Sopenharmony_ci#define virt_wmb() dmb(ishst) 2462306a36Sopenharmony_ci#define virt_store_mb(var, value) do { WRITE_ONCE(var, value); dmb(ish); } while (0) 2562306a36Sopenharmony_ci/* Weak barriers should be used. If not - it's a bug */ 2662306a36Sopenharmony_ci# define mb() abort() 2762306a36Sopenharmony_ci# define dma_rmb() abort() 2862306a36Sopenharmony_ci# define dma_wmb() abort() 2962306a36Sopenharmony_ci#else 3062306a36Sopenharmony_ci#error Please fill in barrier macros 3162306a36Sopenharmony_ci#endif 3262306a36Sopenharmony_ci 33