arch/riscv/include/asm/cmpxchg.h

Source file repositories/reference/linux-study-clean/arch/riscv/include/asm/cmpxchg.h

File Facts

System
Linux kernel
Corpus path
arch/riscv/include/asm/cmpxchg.h
Extension
.h
Size
12563 bytes
Lines
448
Domain
Architecture Layer
Bucket
arch/riscv
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

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)	\
				<< __s;						\
		ulong __newx = (ulong)(n) << __s;				\
		ulong __retx;							\
		ulong __rc;							\
										\
		__asm__ __volatile__ (						\
		       prepend							\
		       PREFETCHW_ASM(%5)					\
		       "0:	lr.w %0, %2\n"					\
		       "	and  %1, %0, %z4\n"				\
		       "	or   %1, %1, %z3\n"				\
		       "	sc.w" sc_sfx " %1, %1, %2\n"			\
		       "	bnez %1, 0b\n"					\
		       sc_append						\
		       : "=&r" (__retx), "=&r" (__rc), "+A" (*(__ptr32b))	\
		       : "rJ" (__newx), "rJ" (~__mask), "rJ" (__ptr32b)		\
		       : "memory");						\
										\
		r = (__typeof__(*(p)))((__retx & __mask) >> __s);		\
	}									\
})

#define __arch_xchg(sfx, prepend, append, r, p, n)			\
({									\
	__asm__ __volatile__ (						\
		prepend							\
		"	amoswap" sfx " %0, %2, %1\n"			\
		append							\
		: "=r" (r), "+A" (*(p))					\
		: "r" (n)						\
		: "memory");						\
})

#define _arch_xchg(ptr, new, sc_sfx, swap_sfx, prepend,			\
		   sc_append, swap_append)				\
({									\
	__typeof__(ptr) __ptr = (ptr);					\
	__typeof__(*(__ptr)) __new = (new);				\
	__typeof__(*(__ptr)) __ret;					\
									\
	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, ".h" swap_sfx,		\
				   prepend, sc_append, swap_append,	\
				   __ret, __ptr, __new);		\
		break;							\
	case 4:								\
		__arch_xchg(".w" swap_sfx, prepend, swap_append,	\
			      __ret, __ptr, __new);			\
		break;							\
	case 8:								\
		__arch_xchg(".d" swap_sfx, prepend, swap_append,	\
			      __ret, __ptr, __new);			\
		break;							\
	default:							\
		BUILD_BUG();						\
	}								\
	(__typeof__(*(__ptr)))__ret;					\
})

#define arch_xchg_relaxed(ptr, x)					\
	_arch_xchg(ptr, x, "", "", "", "", "")

#define arch_xchg_acquire(ptr, x)					\
	_arch_xchg(ptr, x, "", "", "",					\
		   RISCV_ACQUIRE_BARRIER, RISCV_ACQUIRE_BARRIER)

#define arch_xchg_release(ptr, x)					\
	_arch_xchg(ptr, x, "", "", RISCV_RELEASE_BARRIER, "", "")

#define arch_xchg(ptr, x)						\
	_arch_xchg(ptr, x, ".rl", ".aqrl", "", RISCV_FULL_BARRIER, "")

Annotation

Implementation Notes