18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _ASM_POWERPC_SYNCH_H
38c2ecf20Sopenharmony_ci#define _ASM_POWERPC_SYNCH_H
48c2ecf20Sopenharmony_ci#ifdef __KERNEL__
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <asm/cputable.h>
78c2ecf20Sopenharmony_ci#include <asm/feature-fixups.h>
88c2ecf20Sopenharmony_ci#include <asm/ppc-opcode.h>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__
118c2ecf20Sopenharmony_ciextern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup;
128c2ecf20Sopenharmony_ciextern void do_lwsync_fixups(unsigned long value, void *fixup_start,
138c2ecf20Sopenharmony_ci			     void *fixup_end);
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_cistatic inline void eieio(void)
168c2ecf20Sopenharmony_ci{
178c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("eieio" : : : "memory");
188c2ecf20Sopenharmony_ci}
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_cistatic inline void isync(void)
218c2ecf20Sopenharmony_ci{
228c2ecf20Sopenharmony_ci	__asm__ __volatile__ ("isync" : : : "memory");
238c2ecf20Sopenharmony_ci}
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_cistatic inline void ppc_after_tlbiel_barrier(void)
268c2ecf20Sopenharmony_ci{
278c2ecf20Sopenharmony_ci	asm volatile("ptesync": : :"memory");
288c2ecf20Sopenharmony_ci	/*
298c2ecf20Sopenharmony_ci	 * POWER9, POWER10 need a cp_abort after tlbiel to ensure the copy is
308c2ecf20Sopenharmony_ci	 * invalidated correctly. If this is not done, the paste can take data
318c2ecf20Sopenharmony_ci	 * from the physical address that was translated at copy time.
328c2ecf20Sopenharmony_ci	 *
338c2ecf20Sopenharmony_ci	 * POWER9 in practice does not need this, because address spaces with
348c2ecf20Sopenharmony_ci	 * accelerators mapped will use tlbie (which does invalidate the copy)
358c2ecf20Sopenharmony_ci	 * to invalidate translations. It's not possible to limit POWER10 this
368c2ecf20Sopenharmony_ci	 * way due to local copy-paste.
378c2ecf20Sopenharmony_ci	 */
388c2ecf20Sopenharmony_ci	asm volatile(ASM_FTR_IFSET(PPC_CP_ABORT, "", %0) : : "i" (CPU_FTR_ARCH_31) : "memory");
398c2ecf20Sopenharmony_ci}
408c2ecf20Sopenharmony_ci#endif /* __ASSEMBLY__ */
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci#if defined(__powerpc64__)
438c2ecf20Sopenharmony_ci#    define LWSYNC	lwsync
448c2ecf20Sopenharmony_ci#elif defined(CONFIG_E500)
458c2ecf20Sopenharmony_ci#    define LWSYNC					\
468c2ecf20Sopenharmony_ci	START_LWSYNC_SECTION(96);			\
478c2ecf20Sopenharmony_ci	sync;						\
488c2ecf20Sopenharmony_ci	MAKE_LWSYNC_SECTION_ENTRY(96, __lwsync_fixup);
498c2ecf20Sopenharmony_ci#else
508c2ecf20Sopenharmony_ci#    define LWSYNC	sync
518c2ecf20Sopenharmony_ci#endif
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci#ifdef CONFIG_SMP
548c2ecf20Sopenharmony_ci#define __PPC_ACQUIRE_BARRIER				\
558c2ecf20Sopenharmony_ci	START_LWSYNC_SECTION(97);			\
568c2ecf20Sopenharmony_ci	isync;						\
578c2ecf20Sopenharmony_ci	MAKE_LWSYNC_SECTION_ENTRY(97, __lwsync_fixup);
588c2ecf20Sopenharmony_ci#define PPC_ACQUIRE_BARRIER	 "\n" stringify_in_c(__PPC_ACQUIRE_BARRIER)
598c2ecf20Sopenharmony_ci#define PPC_RELEASE_BARRIER	 stringify_in_c(LWSYNC) "\n"
608c2ecf20Sopenharmony_ci#define PPC_ATOMIC_ENTRY_BARRIER "\n" stringify_in_c(sync) "\n"
618c2ecf20Sopenharmony_ci#define PPC_ATOMIC_EXIT_BARRIER	 "\n" stringify_in_c(sync) "\n"
628c2ecf20Sopenharmony_ci#else
638c2ecf20Sopenharmony_ci#define PPC_ACQUIRE_BARRIER
648c2ecf20Sopenharmony_ci#define PPC_RELEASE_BARRIER
658c2ecf20Sopenharmony_ci#define PPC_ATOMIC_ENTRY_BARRIER
668c2ecf20Sopenharmony_ci#define PPC_ATOMIC_EXIT_BARRIER
678c2ecf20Sopenharmony_ci#endif
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci#endif /* __KERNEL__ */
708c2ecf20Sopenharmony_ci#endif	/* _ASM_POWERPC_SYNCH_H */
71