home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-arm / locks.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  5.6 KB  |  275 lines

  1. /*
  2.  *  linux/include/asm-arm/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. #if __LINUX_ARM_ARCH__ >= 6
  16.  
  17. #define __down_op(ptr,fail)            \
  18.     ({                    \
  19.     __asm__ __volatile__(            \
  20.     "@ down_op\n"                \
  21. "1:    ldrex    lr, [%0]\n"            \
  22. "    sub    lr, lr, %1\n"            \
  23. "    strex    ip, lr, [%0]\n"            \
  24. "    teq    ip, #0\n"            \
  25. "    bne    1b\n"                \
  26. "    teq    lr, #0\n"            \
  27. "    movmi    ip, %0\n"            \
  28. "    blmi    " #fail                \
  29.     :                    \
  30.     : "r" (ptr), "I" (1)            \
  31.     : "ip", "lr", "cc");            \
  32.     smp_mb();                \
  33.     })
  34.  
  35. #define __down_op_ret(ptr,fail)            \
  36.     ({                    \
  37.         unsigned int ret;        \
  38.     __asm__ __volatile__(            \
  39.     "@ down_op_ret\n"            \
  40. "1:    ldrex    lr, [%1]\n"            \
  41. "    sub    lr, lr, %2\n"            \
  42. "    strex    ip, lr, [%1]\n"            \
  43. "    teq    ip, #0\n"            \
  44. "    bne    1b\n"                \
  45. "    teq    lr, #0\n"            \
  46. "    movmi    ip, %1\n"            \
  47. "    movpl    ip, #0\n"            \
  48. "    blmi    " #fail "\n"            \
  49. "    mov    %0, ip"                \
  50.     : "=&r" (ret)                \
  51.     : "r" (ptr), "I" (1)            \
  52.     : "ip", "lr", "cc");            \
  53.     smp_mb();                \
  54.     ret;                    \
  55.     })
  56.  
  57. #define __up_op(ptr,wake)            \
  58.     ({                    \
  59.     smp_mb();                \
  60.     __asm__ __volatile__(            \
  61.     "@ up_op\n"                \
  62. "1:    ldrex    lr, [%0]\n"            \
  63. "    add    lr, lr, %1\n"            \
  64. "    strex    ip, lr, [%0]\n"            \
  65. "    teq    ip, #0\n"            \
  66. "    bne    1b\n"                \
  67. "    cmp    lr, #0\n"            \
  68. "    movle    ip, %0\n"            \
  69. "    blle    " #wake                \
  70.     :                    \
  71.     : "r" (ptr), "I" (1)            \
  72.     : "ip", "lr", "cc");            \
  73.     })
  74.  
  75. /*
  76.  * The value 0x01000000 supports up to 128 processors and
  77.  * lots of processes.  BIAS must be chosen such that sub'ing
  78.  * BIAS once per CPU will result in the long remaining
  79.  * negative.
  80.  */
  81. #define RW_LOCK_BIAS      0x01000000
  82. #define RW_LOCK_BIAS_STR "0x01000000"
  83.  
  84. #define __down_op_write(ptr,fail)        \
  85.     ({                    \
  86.     __asm__ __volatile__(            \
  87.     "@ down_op_write\n"            \
  88. "1:    ldrex    lr, [%0]\n"            \
  89. "    sub    lr, lr, %1\n"            \
  90. "    strex    ip, lr, [%0]\n"            \
  91. "    teq    ip, #0\n"            \
  92. "    bne    1b\n"                \
  93. "    teq    lr, #0\n"            \
  94. "    movne    ip, %0\n"            \
  95. "    blne    " #fail                \
  96.     :                    \
  97.     : "r" (ptr), "I" (RW_LOCK_BIAS)        \
  98.     : "ip", "lr", "cc");            \
  99.     smp_mb();                \
  100.     })
  101.  
  102. #define __up_op_write(ptr,wake)            \
  103.     ({                    \
  104.     smp_mb();                \
  105.     __asm__ __volatile__(            \
  106.     "@ up_op_write\n"            \
  107. "1:    ldrex    lr, [%0]\n"            \
  108. "    adds    lr, lr, %1\n"            \
  109. "    strex    ip, lr, [%0]\n"            \
  110. "    teq    ip, #0\n"            \
  111. "    bne    1b\n"                \
  112. "    movcs    ip, %0\n"            \
  113. "    blcs    " #wake                \
  114.     :                    \
  115.     : "r" (ptr), "I" (RW_LOCK_BIAS)        \
  116.     : "ip", "lr", "cc");            \
  117.     })
  118.  
  119. #define __down_op_read(ptr,fail)        \
  120.     __down_op(ptr, fail)
  121.  
  122. #define __up_op_read(ptr,wake)            \
  123.     ({                    \
  124.     smp_mb();                \
  125.     __asm__ __volatile__(            \
  126.     "@ up_op_read\n"            \
  127. "1:    ldrex    lr, [%0]\n"            \
  128. "    add    lr, lr, %1\n"            \
  129. "    strex    ip, lr, [%0]\n"            \
  130. "    teq    ip, #0\n"            \
  131. "    bne    1b\n"                \
  132. "    teq    lr, #0\n"            \
  133. "    moveq    ip, %0\n"            \
  134. "    bleq    " #wake                \
  135.     :                    \
  136.     : "r" (ptr), "I" (1)            \
  137.     : "ip", "lr", "cc");            \
  138.     })
  139.  
  140. #else
  141.  
  142. #define __down_op(ptr,fail)            \
  143.     ({                    \
  144.     __asm__ __volatile__(            \
  145.     "@ down_op\n"                \
  146. "    mrs    ip, cpsr\n"            \
  147. "    orr    lr, ip, #128\n"            \
  148. "    msr    cpsr_c, lr\n"            \
  149. "    ldr    lr, [%0]\n"            \
  150. "    subs    lr, lr, %1\n"            \
  151. "    str    lr, [%0]\n"            \
  152. "    msr    cpsr_c, ip\n"            \
  153. "    movmi    ip, %0\n"            \
  154. "    blmi    " #fail                \
  155.     :                    \
  156.     : "r" (ptr), "I" (1)            \
  157.     : "ip", "lr", "cc");            \
  158.     smp_mb();                \
  159.     })
  160.  
  161. #define __down_op_ret(ptr,fail)            \
  162.     ({                    \
  163.         unsigned int ret;        \
  164.     __asm__ __volatile__(            \
  165.     "@ down_op_ret\n"            \
  166. "    mrs    ip, cpsr\n"            \
  167. "    orr    lr, ip, #128\n"            \
  168. "    msr    cpsr_c, lr\n"            \
  169. "    ldr    lr, [%1]\n"            \
  170. "    subs    lr, lr, %2\n"            \
  171. "    str    lr, [%1]\n"            \
  172. "    msr    cpsr_c, ip\n"            \
  173. "    movmi    ip, %1\n"            \
  174. "    movpl    ip, #0\n"            \
  175. "    blmi    " #fail "\n"            \
  176. "    mov    %0, ip"                \
  177.     : "=&r" (ret)                \
  178.     : "r" (ptr), "I" (1)            \
  179.     : "ip", "lr", "cc");            \
  180.     smp_mb();                \
  181.     ret;                    \
  182.     })
  183.  
  184. #define __up_op(ptr,wake)            \
  185.     ({                    \
  186.     smp_mb();                \
  187.     __asm__ __volatile__(            \
  188.     "@ up_op\n"                \
  189. "    mrs    ip, cpsr\n"            \
  190. "    orr    lr, ip, #128\n"            \
  191. "    msr    cpsr_c, lr\n"            \
  192. "    ldr    lr, [%0]\n"            \
  193. "    adds    lr, lr, %1\n"            \
  194. "    str    lr, [%0]\n"            \
  195. "    msr    cpsr_c, ip\n"            \
  196. "    movle    ip, %0\n"            \
  197. "    blle    " #wake                \
  198.     :                    \
  199.     : "r" (ptr), "I" (1)            \
  200.     : "ip", "lr", "cc");            \
  201.     })
  202.  
  203. /*
  204.  * The value 0x01000000 supports up to 128 processors and
  205.  * lots of processes.  BIAS must be chosen such that sub'ing
  206.  * BIAS once per CPU will result in the long remaining
  207.  * negative.
  208.  */
  209. #define RW_LOCK_BIAS      0x01000000
  210. #define RW_LOCK_BIAS_STR "0x01000000"
  211.  
  212. #define __down_op_write(ptr,fail)        \
  213.     ({                    \
  214.     __asm__ __volatile__(            \
  215.     "@ down_op_write\n"            \
  216. "    mrs    ip, cpsr\n"            \
  217. "    orr    lr, ip, #128\n"            \
  218. "    msr    cpsr_c, lr\n"            \
  219. "    ldr    lr, [%0]\n"            \
  220. "    subs    lr, lr, %1\n"            \
  221. "    str    lr, [%0]\n"            \
  222. "    msr    cpsr_c, ip\n"            \
  223. "    movne    ip, %0\n"            \
  224. "    blne    " #fail                \
  225.     :                    \
  226.     : "r" (ptr), "I" (RW_LOCK_BIAS)        \
  227.     : "ip", "lr", "cc");            \
  228.     smp_mb();                \
  229.     })
  230.  
  231. #define __up_op_write(ptr,wake)            \
  232.     ({                    \
  233.     __asm__ __volatile__(            \
  234.     "@ up_op_write\n"            \
  235. "    mrs    ip, cpsr\n"            \
  236. "    orr    lr, ip, #128\n"            \
  237. "    msr    cpsr_c, lr\n"            \
  238. "    ldr    lr, [%0]\n"            \
  239. "    adds    lr, lr, %1\n"            \
  240. "    str    lr, [%0]\n"            \
  241. "    msr    cpsr_c, ip\n"            \
  242. "    movcs    ip, %0\n"            \
  243. "    blcs    " #wake                \
  244.     :                    \
  245.     : "r" (ptr), "I" (RW_LOCK_BIAS)        \
  246.     : "ip", "lr", "cc");            \
  247.     smp_mb();                \
  248.     })
  249.  
  250. #define __down_op_read(ptr,fail)        \
  251.     __down_op(ptr, fail)
  252.  
  253. #define __up_op_read(ptr,wake)            \
  254.     ({                    \
  255.     smp_mb();                \
  256.     __asm__ __volatile__(            \
  257.     "@ up_op_read\n"            \
  258. "    mrs    ip, cpsr\n"            \
  259. "    orr    lr, ip, #128\n"            \
  260. "    msr    cpsr_c, lr\n"            \
  261. "    ldr    lr, [%0]\n"            \
  262. "    adds    lr, lr, %1\n"            \
  263. "    str    lr, [%0]\n"            \
  264. "    msr    cpsr_c, ip\n"            \
  265. "    moveq    ip, %0\n"            \
  266. "    bleq    " #wake                \
  267.     :                    \
  268.     : "r" (ptr), "I" (1)            \
  269.     : "ip", "lr", "cc");            \
  270.     })
  271.  
  272. #endif
  273.  
  274. #endif
  275.