1 #include <asm/unwind.h> 2 3 #if __LINUX_ARM_ARCH__ >= 6 4 .macro bitop, name, instr 5 ENTRY( \name ) 6 UNWIND( .fnstart ) 7 ands ip, r1, #3 8 strneb r1, [ip] @ assert word-aligned 9 mov r2, #1 10 and r3, r0, #31 @ Get bit offset 11 mov r0, r0, lsr #5 12 add r1, r1, r0, lsl #2 @ Get word offset 13 mov r3, r2, lsl r3 14 1: ldrex r2, [r1] 15 \instr r2, r2, r3 16 strex r0, r2, [r1] 17 cmp r0, #0 18 bne 1b 19 bx lr 20 UNWIND( .fnend ) 21 ENDPROC(\name ) 22 .endm 23 24 .macro testop, name, instr, store 25 ENTRY( \name ) 26 UNWIND( .fnstart ) 27 ands ip, r1, #3 28 strneb r1, [ip] @ assert word-aligned 29 mov r2, #1 30 and r3, r0, #31 @ Get bit offset 31 mov r0, r0, lsr #5 32 add r1, r1, r0, lsl #2 @ Get word offset 33 mov r3, r2, lsl r3 @ create mask 34 smp_dmb 35 1: ldrex r2, [r1] 36 ands r0, r2, r3 @ save old value of bit 37 \instr r2, r2, r3 @ toggle bit 38 strex ip, r2, [r1] 39 cmp ip, #0 40 bne 1b 41 smp_dmb 42 cmp r0, #0 43 movne r0, #1 44 2: bx lr 45 UNWIND( .fnend ) 46 ENDPROC(\name ) 47 .endm 48 #else 49 .macro bitop, name, instr 50 ENTRY( \name ) 51 UNWIND( .fnstart ) 52 ands ip, r1, #3 53 strneb r1, [ip] @ assert word-aligned 54 and r2, r0, #31 55 mov r0, r0, lsr #5 56 mov r3, #1 57 mov r3, r3, lsl r2 58 save_and_disable_irqs ip 59 ldr r2, [r1, r0, lsl #2] 60 \instr r2, r2, r3 61 str r2, [r1, r0, lsl #2] 62 restore_irqs ip 63 mov pc, lr 64 UNWIND( .fnend ) 65 ENDPROC(\name ) 66 .endm 67 68 /** 69 * testop - implement a test_and_xxx_bit operation. 70 * @instr: operational instruction 71 * @store: store instruction 72 * 73 * Note: we can trivially conditionalise the store instruction 74 * to avoid dirtying the data cache. 75 */ 76 .macro testop, name, instr, store 77 ENTRY( \name ) 78 UNWIND( .fnstart ) 79 ands ip, r1, #3 80 strneb r1, [ip] @ assert word-aligned 81 and r3, r0, #31 82 mov r0, r0, lsr #5 83 save_and_disable_irqs ip 84 ldr r2, [r1, r0, lsl #2]! 85 mov r0, #1 86 tst r2, r0, lsl r3 87 \instr r2, r2, r0, lsl r3 88 \store r2, [r1] 89 moveq r0, #0 90 restore_irqs ip 91 mov pc, lr 92 UNWIND( .fnend ) 93 ENDPROC(\name ) 94 .endm 95 #endif 96