locks.h
上传用户:szlgq88
上传日期:2009-04-28
资源大小:48287k
文件大小:6k
- /*
- * linux/include/asm-arm/locks.h
- *
- * Copyright (C) 2000 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Interrupt safe locking assembler.
- */
- #ifndef __ASM_PROC_LOCKS_H
- #define __ASM_PROC_LOCKS_H
- #if __LINUX_ARM_ARCH__ >= 6
- #define __down_op(ptr,fail)
- ({
- __asm__ __volatile__(
- "@ down_opn"
- "1: ldrex lr, [%0]n"
- " sub lr, lr, %1n"
- " strex ip, lr, [%0]n"
- " teq ip, #0n"
- " bne 1bn"
- " teq lr, #0n"
- " movmi ip, %0n"
- " blmi " #fail
- :
- : "r" (ptr), "I" (1)
- : "ip", "lr", "cc");
- smp_mb();
- })
- #define __down_op_ret(ptr,fail)
- ({
- unsigned int ret;
- __asm__ __volatile__(
- "@ down_op_retn"
- "1: ldrex lr, [%1]n"
- " sub lr, lr, %2n"
- " strex ip, lr, [%1]n"
- " teq ip, #0n"
- " bne 1bn"
- " teq lr, #0n"
- " movmi ip, %1n"
- " movpl ip, #0n"
- " blmi " #fail "n"
- " mov %0, ip"
- : "=&r" (ret)
- : "r" (ptr), "I" (1)
- : "ip", "lr", "cc");
- smp_mb();
- ret;
- })
- #define __up_op(ptr,wake)
- ({
- smp_mb();
- __asm__ __volatile__(
- "@ up_opn"
- "1: ldrex lr, [%0]n"
- " add lr, lr, %1n"
- " strex ip, lr, [%0]n"
- " teq ip, #0n"
- " bne 1bn"
- " cmp lr, #0n"
- " movle ip, %0n"
- " blle " #wake
- :
- : "r" (ptr), "I" (1)
- : "ip", "lr", "cc");
- })
- /*
- * The value 0x01000000 supports up to 128 processors and
- * lots of processes. BIAS must be chosen such that sub'ing
- * BIAS once per CPU will result in the long remaining
- * negative.
- */
- #define RW_LOCK_BIAS 0x01000000
- #define RW_LOCK_BIAS_STR "0x01000000"
- #define __down_op_write(ptr,fail)
- ({
- __asm__ __volatile__(
- "@ down_op_writen"
- "1: ldrex lr, [%0]n"
- " sub lr, lr, %1n"
- " strex ip, lr, [%0]n"
- " teq ip, #0n"
- " bne 1bn"
- " teq lr, #0n"
- " movne ip, %0n"
- " blne " #fail
- :
- : "r" (ptr), "I" (RW_LOCK_BIAS)
- : "ip", "lr", "cc");
- smp_mb();
- })
- #define __up_op_write(ptr,wake)
- ({
- smp_mb();
- __asm__ __volatile__(
- "@ up_op_writen"
- "1: ldrex lr, [%0]n"
- " adds lr, lr, %1n"
- " strex ip, lr, [%0]n"
- " teq ip, #0n"
- " bne 1bn"
- " movcs ip, %0n"
- " blcs " #wake
- :
- : "r" (ptr), "I" (RW_LOCK_BIAS)
- : "ip", "lr", "cc");
- })
- #define __down_op_read(ptr,fail)
- __down_op(ptr, fail)
- #define __up_op_read(ptr,wake)
- ({
- smp_mb();
- __asm__ __volatile__(
- "@ up_op_readn"
- "1: ldrex lr, [%0]n"
- " add lr, lr, %1n"
- " strex ip, lr, [%0]n"
- " teq ip, #0n"
- " bne 1bn"
- " teq lr, #0n"
- " moveq ip, %0n"
- " bleq " #wake
- :
- : "r" (ptr), "I" (1)
- : "ip", "lr", "cc");
- })
- #else
- #define __down_op(ptr,fail)
- ({
- __asm__ __volatile__(
- "@ down_opn"
- " mrs ip, cpsrn"
- " orr lr, ip, #128n"
- " msr cpsr_c, lrn"
- " ldr lr, [%0]n"
- " subs lr, lr, %1n"
- " str lr, [%0]n"
- " msr cpsr_c, ipn"
- " movmi ip, %0n"
- " blmi " #fail
- :
- : "r" (ptr), "I" (1)
- : "ip", "lr", "cc");
- smp_mb();
- })
- #define __down_op_ret(ptr,fail)
- ({
- unsigned int ret;
- __asm__ __volatile__(
- "@ down_op_retn"
- " mrs ip, cpsrn"
- " orr lr, ip, #128n"
- " msr cpsr_c, lrn"
- " ldr lr, [%1]n"
- " subs lr, lr, %2n"
- " str lr, [%1]n"
- " msr cpsr_c, ipn"
- " movmi ip, %1n"
- " movpl ip, #0n"
- " blmi " #fail "n"
- " mov %0, ip"
- : "=&r" (ret)
- : "r" (ptr), "I" (1)
- : "ip", "lr", "cc");
- smp_mb();
- ret;
- })
- #define __up_op(ptr,wake)
- ({
- smp_mb();
- __asm__ __volatile__(
- "@ up_opn"
- " mrs ip, cpsrn"
- " orr lr, ip, #128n"
- " msr cpsr_c, lrn"
- " ldr lr, [%0]n"
- " adds lr, lr, %1n"
- " str lr, [%0]n"
- " msr cpsr_c, ipn"
- " movle ip, %0n"
- " blle " #wake
- :
- : "r" (ptr), "I" (1)
- : "ip", "lr", "cc");
- })
- /*
- * The value 0x01000000 supports up to 128 processors and
- * lots of processes. BIAS must be chosen such that sub'ing
- * BIAS once per CPU will result in the long remaining
- * negative.
- */
- #define RW_LOCK_BIAS 0x01000000
- #define RW_LOCK_BIAS_STR "0x01000000"
- #define __down_op_write(ptr,fail)
- ({
- __asm__ __volatile__(
- "@ down_op_writen"
- " mrs ip, cpsrn"
- " orr lr, ip, #128n"
- " msr cpsr_c, lrn"
- " ldr lr, [%0]n"
- " subs lr, lr, %1n"
- " str lr, [%0]n"
- " msr cpsr_c, ipn"
- " movne ip, %0n"
- " blne " #fail
- :
- : "r" (ptr), "I" (RW_LOCK_BIAS)
- : "ip", "lr", "cc");
- smp_mb();
- })
- #define __up_op_write(ptr,wake)
- ({
- __asm__ __volatile__(
- "@ up_op_writen"
- " mrs ip, cpsrn"
- " orr lr, ip, #128n"
- " msr cpsr_c, lrn"
- " ldr lr, [%0]n"
- " adds lr, lr, %1n"
- " str lr, [%0]n"
- " msr cpsr_c, ipn"
- " movcs ip, %0n"
- " blcs " #wake
- :
- : "r" (ptr), "I" (RW_LOCK_BIAS)
- : "ip", "lr", "cc");
- smp_mb();
- })
- #define __down_op_read(ptr,fail)
- __down_op(ptr, fail)
- #define __up_op_read(ptr,wake)
- ({
- smp_mb();
- __asm__ __volatile__(
- "@ up_op_readn"
- " mrs ip, cpsrn"
- " orr lr, ip, #128n"
- " msr cpsr_c, lrn"
- " ldr lr, [%0]n"
- " adds lr, lr, %1n"
- " str lr, [%0]n"
- " msr cpsr_c, ipn"
- " moveq ip, %0n"
- " bleq " #wake
- :
- : "r" (ptr), "I" (1)
- : "ip", "lr", "cc");
- })
- #endif
- #endif