Unverified Commit 97ddab7f authored by Alexandre Ghiti's avatar Alexandre Ghiti Committed by Palmer Dabbelt
Browse files

riscv: Implement xchg8/16() using Zabha



This adds runtime support for Zabha in xchg8/16() operations.

Signed-off-by: default avatarAlexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: default avatarAndrew Jones <ajones@ventanamicro.com>
Reviewed-by: default avatarAndrea Parri <parri.andrea@gmail.com>
Link: https://lore.kernel.org/r/20241103145153.105097-9-alexghiti@rivosinc.com


Signed-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parent f7bd2be7
Loading
Loading
Loading
Loading
+41 −24
Original line number Diff line number Diff line
@@ -14,8 +14,19 @@
#include <asm/insn-def.h>
#include <asm/cpufeature-macros.h>

#define __arch_xchg_masked(sc_sfx, prepend, append, r, p, n)		\
#define __arch_xchg_masked(sc_sfx, swap_sfx, prepend, sc_append,		\
			   swap_append, r, p, n)				\
({										\
	if (IS_ENABLED(CONFIG_RISCV_ISA_ZABHA) &&				\
	    riscv_has_extension_unlikely(RISCV_ISA_EXT_ZABHA)) {		\
		__asm__ __volatile__ (						\
			prepend							\
			"	amoswap" swap_sfx " %0, %z2, %1\n"		\
			swap_append						\
			: "=&r" (r), "+A" (*(p))				\
			: "rJ" (n)						\
			: "memory");						\
	} else {								\
		u32 *__ptr32b = (u32 *)((ulong)(p) & ~0x3);			\
		ulong __s = ((ulong)(p) & (0x4 - sizeof(*p))) * BITS_PER_BYTE;	\
		ulong __mask = GENMASK(((sizeof(*p)) * BITS_PER_BYTE) - 1, 0)	\
@@ -31,12 +42,13 @@
		       "	or   %1, %1, %z3\n"				\
		       "	sc.w" sc_sfx " %1, %1, %2\n"			\
		       "	bnez %1, 0b\n"					\
	       append							\
		       sc_append						\
		       : "=&r" (__retx), "=&r" (__rc), "+A" (*(__ptr32b))	\
		       : "rJ" (__newx), "rJ" (~__mask)				\
		       : "memory");						\
										\
		r = (__typeof__(*(p)))((__retx & __mask) >> __s);		\
	}									\
})

#define __arch_xchg(sfx, prepend, append, r, p, n)			\
@@ -59,8 +71,13 @@
									\
	switch (sizeof(*__ptr)) {					\
	case 1:								\
		__arch_xchg_masked(sc_sfx, ".b" swap_sfx,		\
				   prepend, sc_append, swap_append,	\
				   __ret, __ptr, __new);		\
		break;							\
	case 2:								\
		__arch_xchg_masked(sc_sfx, prepend, sc_append,		\
		__arch_xchg_masked(sc_sfx, ".h" swap_sfx,		\
				   prepend, sc_append, swap_append,	\
				   __ret, __ptr, __new);		\
		break;							\
	case 4:								\