mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-09-04 20:19:47 +08:00 
			
		
		
		
	 dc7a12bdfc
			
		
	
	
		dc7a12bdfc
		
	
	
	
	
		
			
			Converts ARM the text files to ReST, preparing them to be an architecture book. The conversion is actually: - add blank lines and identation in order to identify paragraphs; - fix tables markups; - add some lists markups; - mark literal blocks; - adjust title markups. At its new index.rst, let's add a :orphan: while this is not linked to the main index.rst file, in order to avoid build warnings. Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> Reviewed-by Corentin Labbe <clabbe.montjoie@gmail.com> # For sun4i-ss
		
			
				
	
	
		
			100 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /* SPDX-License-Identifier: GPL-2.0-only */
 | |
| /*
 | |
|  * vlock.S - simple voting lock implementation for ARM
 | |
|  *
 | |
|  * Created by:	Dave Martin, 2012-08-16
 | |
|  * Copyright:	(C) 2012-2013  Linaro Limited
 | |
|  *
 | |
|  * This algorithm is described in more detail in
 | |
|  * Documentation/arm/vlocks.rst.
 | |
|  */
 | |
| 
 | |
| #include <linux/linkage.h>
 | |
| #include "vlock.h"
 | |
| 
 | |
| /* Select different code if voting flags  can fit in a single word. */
 | |
| #if VLOCK_VOTING_SIZE > 4
 | |
| #define FEW(x...)
 | |
| #define MANY(x...) x
 | |
| #else
 | |
| #define FEW(x...) x
 | |
| #define MANY(x...)
 | |
| #endif
 | |
| 
 | |
| @ voting lock for first-man coordination
 | |
| 
 | |
| .macro voting_begin rbase:req, rcpu:req, rscratch:req
 | |
| 	mov	\rscratch, #1
 | |
| 	strb	\rscratch, [\rbase, \rcpu]
 | |
| 	dmb
 | |
| .endm
 | |
| 
 | |
| .macro voting_end rbase:req, rcpu:req, rscratch:req
 | |
| 	dmb
 | |
| 	mov	\rscratch, #0
 | |
| 	strb	\rscratch, [\rbase, \rcpu]
 | |
| 	dsb	st
 | |
| 	sev
 | |
| .endm
 | |
| 
 | |
| /*
 | |
|  * The vlock structure must reside in Strongly-Ordered or Device memory.
 | |
|  * This implementation deliberately eliminates most of the barriers which
 | |
|  * would be required for other memory types, and assumes that independent
 | |
|  * writes to neighbouring locations within a cacheline do not interfere
 | |
|  * with one another.
 | |
|  */
 | |
| 
 | |
| @ r0: lock structure base
 | |
| @ r1: CPU ID (0-based index within cluster)
 | |
| ENTRY(vlock_trylock)
 | |
| 	add	r1, r1, #VLOCK_VOTING_OFFSET
 | |
| 
 | |
| 	voting_begin	r0, r1, r2
 | |
| 
 | |
| 	ldrb	r2, [r0, #VLOCK_OWNER_OFFSET]	@ check whether lock is held
 | |
| 	cmp	r2, #VLOCK_OWNER_NONE
 | |
| 	bne	trylock_fail			@ fail if so
 | |
| 
 | |
| 	@ Control dependency implies strb not observable before previous ldrb.
 | |
| 
 | |
| 	strb	r1, [r0, #VLOCK_OWNER_OFFSET]	@ submit my vote
 | |
| 
 | |
| 	voting_end	r0, r1, r2		@ implies DMB
 | |
| 
 | |
| 	@ Wait for the current round of voting to finish:
 | |
| 
 | |
|  MANY(	mov	r3, #VLOCK_VOTING_OFFSET			)
 | |
| 0:
 | |
|  MANY(	ldr	r2, [r0, r3]					)
 | |
|  FEW(	ldr	r2, [r0, #VLOCK_VOTING_OFFSET]			)
 | |
| 	cmp	r2, #0
 | |
| 	wfene
 | |
| 	bne	0b
 | |
|  MANY(	add	r3, r3, #4					)
 | |
|  MANY(	cmp	r3, #VLOCK_VOTING_OFFSET + VLOCK_VOTING_SIZE	)
 | |
|  MANY(	bne	0b						)
 | |
| 
 | |
| 	@ Check who won:
 | |
| 
 | |
| 	dmb
 | |
| 	ldrb	r2, [r0, #VLOCK_OWNER_OFFSET]
 | |
| 	eor	r0, r1, r2			@ zero if I won, else nonzero
 | |
| 	bx	lr
 | |
| 
 | |
| trylock_fail:
 | |
| 	voting_end	r0, r1, r2
 | |
| 	mov	r0, #1				@ nonzero indicates that I lost
 | |
| 	bx	lr
 | |
| ENDPROC(vlock_trylock)
 | |
| 
 | |
| @ r0: lock structure base
 | |
| ENTRY(vlock_unlock)
 | |
| 	dmb
 | |
| 	mov	r1, #VLOCK_OWNER_NONE
 | |
| 	strb	r1, [r0, #VLOCK_OWNER_OFFSET]
 | |
| 	dsb	st
 | |
| 	sev
 | |
| 	bx	lr
 | |
| ENDPROC(vlock_unlock)
 |