1/* 2 * linux/include/asm-arm/proc-armv/locks.h 3 * 4 * Copyright (C) 2000 Russell King 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * Interrupt safe locking assembler. 11 */ 12#ifndef __ASM_PROC_LOCKS_H 13#define __ASM_PROC_LOCKS_H 14 15#define __down_op(ptr,fail) \ 16 ({ \ 17 __asm__ __volatile__( \ 18 "@ down_op\n" \ 19" mrs ip, cpsr\n" \ 20" orr lr, ip, #128\n" \ 21" msr cpsr_c, lr\n" \ 22" ldr lr, [%0]\n" \ 23" subs lr, lr, %1\n" \ 24" str lr, [%0]\n" \ 25" msr cpsr_c, ip\n" \ 26" movmi ip, %0\n" \ 27" blmi " SYMBOL_NAME_STR(fail) \ 28 : \ 29 : "r" (ptr), "I" (1) \ 30 : "ip", "lr", "cc"); \ 31 }) 32 33#define __down_op_ret(ptr,fail) \ 34 ({ \ 35 unsigned int ret; \ 36 __asm__ __volatile__( \ 37 "@ down_op_ret\n" \ 38" mrs ip, cpsr\n" \ 39" orr lr, ip, #128\n" \ 40" msr cpsr_c, lr\n" \ 41" ldr lr, [%1]\n" \ 42" subs lr, lr, %2\n" \ 43" str lr, [%1]\n" \ 44" msr cpsr_c, ip\n" \ 45" movmi ip, %1\n" \ 46" movpl ip, #0\n" \ 47" blmi " SYMBOL_NAME_STR(fail) "\n" \ 48" mov %0, ip" \ 49 : "=&r" (ret) \ 50 : "r" (ptr), "I" (1) \ 51 : "ip", "lr", "cc"); \ 52 ret; \ 53 }) 54 55#define __up_op(ptr,wake) \ 56 ({ \ 57 __asm__ __volatile__( \ 58 "@ up_op\n" \ 59" mrs ip, cpsr\n" \ 60" orr lr, ip, #128\n" \ 61" msr cpsr_c, lr\n" \ 62" ldr lr, [%0]\n" \ 63" adds lr, lr, %1\n" \ 64" str lr, [%0]\n" \ 65" msr cpsr_c, ip\n" \ 66" movle ip, %0\n" \ 67" blle " SYMBOL_NAME_STR(wake) \ 68 : \ 69 : "r" (ptr), "I" (1) \ 70 : "ip", "lr", "cc"); \ 71 }) 72 73/* 74 * The value 0x01000000 supports up to 128 processors and 75 * lots of processes. BIAS must be chosen such that sub'ing 76 * BIAS once per CPU will result in the long remaining 77 * negative. 78 */ 79#define RW_LOCK_BIAS 0x01000000 80#define RW_LOCK_BIAS_STR "0x01000000" 81 82#define __down_op_write(ptr,fail) \ 83 ({ \ 84 __asm__ __volatile__( \ 85 "@ down_op_write\n" \ 86" mrs ip, cpsr\n" \ 87" orr lr, ip, #128\n" \ 88" msr cpsr_c, lr\n" \ 89" ldr lr, [%0]\n" \ 90" subs lr, lr, %1\n" \ 91" str lr, [%0]\n" \ 92" msr cpsr_c, ip\n" \ 93" movne ip, %0\n" \ 94" blne " SYMBOL_NAME_STR(fail) \ 95 : \ 96 : "r" (ptr), "I" (RW_LOCK_BIAS) \ 97 : "ip", "lr", "cc"); \ 98 }) 99 100#define __up_op_write(ptr,wake) \ 101 ({ \ 102 __asm__ __volatile__( \ 103 "@ up_op_read\n" \ 104" mrs ip, cpsr\n" \ 105" orr lr, ip, #128\n" \ 106" msr cpsr_c, lr\n" \ 107" ldr lr, [%0]\n" \ 108" adds lr, lr, %1\n" \ 109" str lr, [%0]\n" \ 110" msr cpsr_c, ip\n" \ 111" movcs ip, %0\n" \ 112" blcs " SYMBOL_NAME_STR(wake) \ 113 : \ 114 : "r" (ptr), "I" (RW_LOCK_BIAS) \ 115 : "ip", "lr", "cc"); \ 116 }) 117 118#define __down_op_read(ptr,fail) \ 119 __down_op(ptr, fail) 120 121#define __up_op_read(ptr,wake) \ 122 ({ \ 123 __asm__ __volatile__( \ 124 "@ up_op_read\n" \ 125" mrs ip, cpsr\n" \ 126" orr lr, ip, #128\n" \ 127" msr cpsr_c, lr\n" \ 128" ldr lr, [%0]\n" \ 129" adds lr, lr, %1\n" \ 130" str lr, [%0]\n" \ 131" msr cpsr_c, ip\n" \ 132" moveq ip, %0\n" \ 133" bleq " SYMBOL_NAME_STR(wake) \ 134 : \ 135 : "r" (ptr), "I" (1) \ 136 : "ip", "lr", "cc"); \ 137 }) 138 139#endif 140