| 
									
										
										
										
											2011-11-23 11:28:25 +01:00
										 |  |  | #include <asm/unwind.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-16 18:02:17 +00:00
										 |  |  | #if __LINUX_ARM_ARCH__ >= 6
 | 
					
						
							| 
									
										
										
										
											2011-11-23 11:28:25 +01:00
										 |  |  | 	.macro	bitop, name, instr | 
					
						
							|  |  |  | ENTRY(	\name		) | 
					
						
							|  |  |  | UNWIND(	.fnstart	) | 
					
						
							| 
									
										
										
										
											2011-01-16 17:59:44 +00:00
										 |  |  | 	ands	ip, r1, #3 | 
					
						
							|  |  |  | 	strneb	r1, [ip]		@ assert word-aligned | 
					
						
							| 
									
										
										
										
											2005-07-16 15:21:51 +01:00
										 |  |  | 	mov	r2, #1 | 
					
						
							| 
									
										
										
										
											2011-01-16 18:02:17 +00:00
										 |  |  | 	and	r3, r0, #31		@ Get bit offset | 
					
						
							|  |  |  | 	mov	r0, r0, lsr #5 | 
					
						
							|  |  |  | 	add	r1, r1, r0, lsl #2	@ Get word offset | 
					
						
							| 
									
										
										
										
											2005-07-16 15:21:51 +01:00
										 |  |  | 	mov	r3, r2, lsl r3 | 
					
						
							| 
									
										
										
										
											2011-01-16 18:02:17 +00:00
										 |  |  | 1:	ldrex	r2, [r1] | 
					
						
							| 
									
										
										
										
											2005-07-16 15:21:51 +01:00
										 |  |  | 	\instr	r2, r2, r3 | 
					
						
							| 
									
										
										
										
											2011-01-16 18:02:17 +00:00
										 |  |  | 	strex	r0, r2, [r1] | 
					
						
							| 
									
										
										
										
											2005-07-28 20:36:26 +01:00
										 |  |  | 	cmp	r0, #0 | 
					
						
							| 
									
										
										
										
											2005-07-16 15:21:51 +01:00
										 |  |  | 	bne	1b | 
					
						
							| 
									
										
										
										
											2011-02-08 12:09:52 +01:00
										 |  |  | 	bx	lr | 
					
						
							| 
									
										
										
										
											2011-11-23 11:28:25 +01:00
										 |  |  | UNWIND(	.fnend		) | 
					
						
							|  |  |  | ENDPROC(\name		) | 
					
						
							| 
									
										
										
										
											2005-07-16 15:21:51 +01:00
										 |  |  | 	.endm | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-23 11:28:25 +01:00
										 |  |  | 	.macro	testop, name, instr, store | 
					
						
							|  |  |  | ENTRY(	\name		) | 
					
						
							|  |  |  | UNWIND(	.fnstart	) | 
					
						
							| 
									
										
										
										
											2011-01-16 17:59:44 +00:00
										 |  |  | 	ands	ip, r1, #3 | 
					
						
							|  |  |  | 	strneb	r1, [ip]		@ assert word-aligned | 
					
						
							| 
									
										
										
										
											2005-07-16 15:21:51 +01:00
										 |  |  | 	mov	r2, #1 | 
					
						
							| 
									
										
										
										
											2011-01-16 18:02:17 +00:00
										 |  |  | 	and	r3, r0, #31		@ Get bit offset | 
					
						
							|  |  |  | 	mov	r0, r0, lsr #5 | 
					
						
							|  |  |  | 	add	r1, r1, r0, lsl #2	@ Get word offset | 
					
						
							| 
									
										
										
										
											2005-07-16 15:21:51 +01:00
										 |  |  | 	mov	r3, r2, lsl r3		@ create mask | 
					
						
							| 
									
										
										
										
											2009-05-25 20:58:00 +01:00
										 |  |  | 	smp_dmb | 
					
						
							| 
									
										
										
										
											2011-01-16 18:02:17 +00:00
										 |  |  | 1:	ldrex	r2, [r1] | 
					
						
							| 
									
										
										
										
											2005-07-16 15:21:51 +01:00
										 |  |  | 	ands	r0, r2, r3		@ save old value of bit | 
					
						
							| 
									
										
										
										
											2011-01-16 18:02:17 +00:00
										 |  |  | 	\instr	r2, r2, r3		@ toggle bit | 
					
						
							|  |  |  | 	strex	ip, r2, [r1] | 
					
						
							| 
									
										
										
										
											2005-07-27 23:00:05 +01:00
										 |  |  | 	cmp	ip, #0 | 
					
						
							| 
									
										
										
										
											2005-07-16 15:21:51 +01:00
										 |  |  | 	bne	1b | 
					
						
							| 
									
										
										
										
											2009-05-25 20:58:00 +01:00
										 |  |  | 	smp_dmb | 
					
						
							| 
									
										
										
										
											2005-07-16 15:21:51 +01:00
										 |  |  | 	cmp	r0, #0 | 
					
						
							|  |  |  | 	movne	r0, #1 | 
					
						
							| 
									
										
										
										
											2011-02-08 12:09:52 +01:00
										 |  |  | 2:	bx	lr | 
					
						
							| 
									
										
										
										
											2011-11-23 11:28:25 +01:00
										 |  |  | UNWIND(	.fnend		) | 
					
						
							|  |  |  | ENDPROC(\name		) | 
					
						
							| 
									
										
										
										
											2005-07-16 15:21:51 +01:00
										 |  |  | 	.endm | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2011-11-23 11:28:25 +01:00
										 |  |  | 	.macro	bitop, name, instr | 
					
						
							|  |  |  | ENTRY(	\name		) | 
					
						
							|  |  |  | UNWIND(	.fnstart	) | 
					
						
							| 
									
										
										
										
											2011-01-16 17:59:44 +00:00
										 |  |  | 	ands	ip, r1, #3 | 
					
						
							|  |  |  | 	strneb	r1, [ip]		@ assert word-aligned | 
					
						
							| 
									
										
										
										
											2011-01-16 18:02:17 +00:00
										 |  |  | 	and	r2, r0, #31 | 
					
						
							|  |  |  | 	mov	r0, r0, lsr #5 | 
					
						
							| 
									
										
										
										
											2005-04-18 22:50:01 +01:00
										 |  |  | 	mov	r3, #1 | 
					
						
							|  |  |  | 	mov	r3, r3, lsl r2 | 
					
						
							| 
									
										
										
										
											2005-11-09 15:04:22 +00:00
										 |  |  | 	save_and_disable_irqs ip | 
					
						
							| 
									
										
										
										
											2011-01-16 18:02:17 +00:00
										 |  |  | 	ldr	r2, [r1, r0, lsl #2] | 
					
						
							| 
									
										
										
										
											2005-04-18 22:50:01 +01:00
										 |  |  | 	\instr	r2, r2, r3 | 
					
						
							| 
									
										
										
										
											2011-01-16 18:02:17 +00:00
										 |  |  | 	str	r2, [r1, r0, lsl #2] | 
					
						
							| 
									
										
										
										
											2005-04-18 22:50:01 +01:00
										 |  |  | 	restore_irqs ip | 
					
						
							|  |  |  | 	mov	pc, lr | 
					
						
							| 
									
										
										
										
											2011-11-23 11:28:25 +01:00
										 |  |  | UNWIND(	.fnend		) | 
					
						
							|  |  |  | ENDPROC(\name		) | 
					
						
							| 
									
										
										
										
											2005-04-18 22:50:01 +01:00
										 |  |  | 	.endm | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * testop - implement a test_and_xxx_bit operation. | 
					
						
							|  |  |  |  * @instr: operational instruction | 
					
						
							|  |  |  |  * @store: store instruction | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Note: we can trivially conditionalise the store instruction | 
					
						
							| 
									
										
										
										
											2007-05-11 20:40:30 +01:00
										 |  |  |  * to avoid dirtying the data cache. | 
					
						
							| 
									
										
										
										
											2005-04-18 22:50:01 +01:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-11-23 11:28:25 +01:00
										 |  |  | 	.macro	testop, name, instr, store | 
					
						
							|  |  |  | ENTRY(	\name		) | 
					
						
							|  |  |  | UNWIND(	.fnstart	) | 
					
						
							| 
									
										
										
										
											2011-01-16 17:59:44 +00:00
										 |  |  | 	ands	ip, r1, #3 | 
					
						
							|  |  |  | 	strneb	r1, [ip]		@ assert word-aligned | 
					
						
							| 
									
										
										
										
											2011-01-16 18:02:17 +00:00
										 |  |  | 	and	r3, r0, #31 | 
					
						
							|  |  |  | 	mov	r0, r0, lsr #5 | 
					
						
							| 
									
										
										
										
											2005-11-09 15:04:22 +00:00
										 |  |  | 	save_and_disable_irqs ip | 
					
						
							| 
									
										
										
										
											2011-01-16 18:02:17 +00:00
										 |  |  | 	ldr	r2, [r1, r0, lsl #2]! | 
					
						
							|  |  |  | 	mov	r0, #1 | 
					
						
							| 
									
										
										
										
											2005-04-18 22:50:01 +01:00
										 |  |  | 	tst	r2, r0, lsl r3 | 
					
						
							|  |  |  | 	\instr	r2, r2, r0, lsl r3 | 
					
						
							|  |  |  | 	\store	r2, [r1] | 
					
						
							|  |  |  | 	moveq	r0, #0 | 
					
						
							| 
									
										
										
										
											2009-08-13 20:38:17 +02:00
										 |  |  | 	restore_irqs ip | 
					
						
							| 
									
										
										
										
											2005-04-18 22:50:01 +01:00
										 |  |  | 	mov	pc, lr | 
					
						
							| 
									
										
										
										
											2011-11-23 11:28:25 +01:00
										 |  |  | UNWIND(	.fnend		) | 
					
						
							|  |  |  | ENDPROC(\name		) | 
					
						
							| 
									
										
										
										
											2005-04-18 22:50:01 +01:00
										 |  |  | 	.endm | 
					
						
							| 
									
										
										
										
											2005-07-16 15:21:51 +01:00
										 |  |  | #endif
 |