2 * linux/include/asm-arm/proc-armo/locks.h
4 * Copyright (C) 2000 Russell King
5 * Fixes for 26 bit machines, (C) 2000 Dave Gilbert
7 * Interrupt safe locking assembler.
10 #ifndef __ASM_PROC_LOCKS_H
11 #define __ASM_PROC_LOCKS_H
13 /* Decrements by 1, fails if value < 0 */
14 #define __down_op(ptr,fail) \
16 __asm__ __volatile__ ( \
17 "@ atomic down operation\n" \
19 " orr lr, ip, #0x08000000\n" \
22 " and ip, ip, #0x0c000003\n" \
23 " subs lr, lr, #1\n" \
25 " orrmi ip, ip, #0x80000000 @ set N\n" \
28 " blmi " SYMBOL_NAME_STR(fail) \
31 : "ip", "lr", "cc"); \
34 #define __down_op_ret(ptr,fail) \
36 unsigned int result; \
37 __asm__ __volatile__ ( \
40 " orr lr, ip, #0x08000000\n" \
43 " and ip, ip, #0x0c000003\n" \
44 " subs lr, lr, #1\n" \
46 " orrmi ip, ip, #0x80000000 @ set N\n" \
50 " blmi " SYMBOL_NAME_STR(fail) "\n" \
54 : "ip", "lr", "cc"); \
58 #define __up_op(ptr,wake) \
60 __asm__ __volatile__ ( \
63 " orr lr, ip, #0x08000000\n" \
66 " and ip, ip, #0x0c000003\n" \
67 " adds lr, lr, #1\n" \
69 " orrle ip, ip, #0x80000000 @ set N - should this be mi ??? DAG ! \n" \
72 " blmi " SYMBOL_NAME_STR(wake) \
75 : "ip", "lr", "cc"); \
79 * The value 0x01000000 supports up to 128 processors and
80 * lots of processes. BIAS must be chosen such that sub'ing
81 * BIAS once per CPU will result in the long remaining
84 #define RW_LOCK_BIAS 0x01000000
85 #define RW_LOCK_BIAS_STR "0x01000000"
87 /* Decrements by RW_LOCK_BIAS rather than 1, fails if value != 0 */
88 #define __down_op_write(ptr,fail) \
90 __asm__ __volatile__( \
93 " orr lr, ip, #0x08000000\n" \
95 " and ip, ip, #0x0c000003\n" \
98 " subs lr, lr, %1\n" \
101 " orreq ip, ip, #0x40000000 @ set Z \n"\
104 " blne " SYMBOL_NAME_STR(fail) \
106 : "r" (ptr), "I" (RW_LOCK_BIAS) \
107 : "ip", "lr", "cc"); \
110 /* Increments by RW_LOCK_BIAS, wakes if value >= 0 */
111 #define __up_op_write(ptr,wake) \
113 __asm__ __volatile__( \
116 " orr lr, ip, #0x08000000\n" \
120 " and ip, ip, #0x0c000003\n" \
121 " adds lr, lr, %1\n" \
124 " orrcs ip, ip, #0x20000000 @ set C\n" \
127 " blcs " SYMBOL_NAME_STR(wake) \
129 : "r" (ptr), "I" (RW_LOCK_BIAS) \
130 : "ip", "lr", "cc"); \
133 #define __down_op_read(ptr,fail) \
136 #define __up_op_read(ptr,wake) \
138 __asm__ __volatile__( \
141 " orr lr, ip, #0x08000000\n" \
145 " and ip, ip, #0x0c000003\n" \
146 " adds lr, lr, %1\n" \
149 " orreq ip, ip, #0x40000000 @ Set Z \n" \
152 " bleq " SYMBOL_NAME_STR(wake) \
154 : "r" (ptr), "I" (1) \
155 : "ip", "lr", "cc"); \