115 lines · 2.3 KB · C
RawDownload
/* SPDX-License-Identifier: GPL-2.0 */#include <asm/assembler.h>#include <asm/unwind.h> #if __LINUX_ARM_ARCH__ >= 6	.macro	bitop, name, instrENTRY(	\name		)UNWIND(	.fnstart	)	ands	ip, r1, #3	strbne	r1, [ip]		@ assert word-aligned	mov	r2, #1	and	r3, r0, #31		@ Get bit offset	mov	r0, r0, lsr #5	add	r1, r1, r0, lsl #2	@ Get word offset#if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)	.arch_extension	mp	ALT_SMP(W(pldw)	[r1])	ALT_UP(W(nop))#endif	mov	r3, r2, lsl r31:	ldrex	r2, [r1]	\instr	r2, r2, r3	strex	r0, r2, [r1]	cmp	r0, #0	bne	1b	bx	lrUNWIND(	.fnend		)ENDPROC(\name		)	.endm 	.macro	__testop, name, instr, store, barrierENTRY(	\name		)UNWIND(	.fnstart	)	ands	ip, r1, #3	strbne	r1, [ip]		@ assert word-aligned	mov	r2, #1	and	r3, r0, #31		@ Get bit offset	mov	r0, r0, lsr #5	add	r1, r1, r0, lsl #2	@ Get word offset	mov	r3, r2, lsl r3		@ create mask	\barrier#if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)	.arch_extension	mp	ALT_SMP(W(pldw)	[r1])	ALT_UP(W(nop))#endif1:	ldrex	r2, [r1]	ands	r0, r2, r3		@ save old value of bit	\instr	r2, r2, r3		@ toggle bit	strex	ip, r2, [r1]	cmp	ip, #0	bne	1b	\barrier	cmp	r0, #0	movne	r0, #12:	bx	lrUNWIND(	.fnend		)ENDPROC(\name		)	.endm 	.macro	testop, name, instr, store	__testop \name, \instr, \store, smp_dmb	.endm 	.macro	sync_testop, name, instr, store	__testop \name, \instr, \store, __smp_dmb	.endm#else	.macro	bitop, name, instrENTRY(	\name		)UNWIND(	.fnstart	)	ands	ip, r1, #3	strbne	r1, [ip]		@ assert word-aligned	and	r2, r0, #31	mov	r0, r0, lsr #5	mov	r3, #1	mov	r3, r3, lsl r2	save_and_disable_irqs ip	ldr	r2, [r1, r0, lsl #2]	\instr	r2, r2, r3	str	r2, [r1, r0, lsl #2]	restore_irqs ip	ret	lrUNWIND(	.fnend		)ENDPROC(\name		)	.endm /** * testop - implement a test_and_xxx_bit operation. * @instr: operational instruction * @store: store instruction * * Note: we can trivially conditionalise the store instruction * to avoid dirtying the data cache. */	.macro	testop, name, instr, storeENTRY(	\name		)UNWIND(	.fnstart	)	ands	ip, r1, #3	strbne	r1, [ip]		@ assert word-aligned	and	r3, r0, #31	mov	r0, r0, lsr #5	save_and_disable_irqs ip	ldr	r2, [r1, r0, lsl #2]!	mov	r0, #1	tst	r2, r0, lsl r3	\instr	r2, r2, r0, lsl r3	\store	r2, [r1]	moveq	r0, #0	restore_irqs ip	ret	lrUNWIND(	.fnend		)ENDPROC(\name		)	.endm#endif