system.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /*
  2. * File: include/asm/system.h
  3. * Based on:
  4. * Author: Tony Kou (tonyko@lineo.ca)
  5. * Copyright (c) 2002 Arcturus Networks Inc.
  6. * (www.arcturusnetworks.com)
  7. * Copyright (c) 2003 Metrowerks (www.metrowerks.com)
  8. * Copyright (c) 2004 Analog Device Inc.
  9. * Created: 25Jan2001 - Tony Kou
  10. * Description: system.h include file
  11. *
  12. * Modified: 22Sep2006 - Robin Getz
  13. * - move include blackfin.h down, so I can get access to
  14. * irq functions in other include files.
  15. *
  16. * Bugs: Enter bugs at http://blackfin.uclinux.org/
  17. *
  18. * This program is free software; you can redistribute it and/or modify
  19. * it under the terms of the GNU General Public License as published by
  20. * the Free Software Foundation; either version 2, or (at your option)
  21. * any later version.
  22. *
  23. * This program is distributed in the hope that it will be useful,
  24. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26. * GNU General Public License for more details.
  27. *
  28. * You should have received a copy of the GNU General Public License
  29. * along with this program; see the file COPYING.
  30. * If not, write to the Free Software Foundation,
  31. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  32. */
  33. #ifndef _BLACKFIN_SYSTEM_H
  34. #define _BLACKFIN_SYSTEM_H
  35. #include <linux/linkage.h>
  36. #include <linux/compiler.h>
  37. /*
  38. * Interrupt configuring macros.
  39. */
  40. extern unsigned long irq_flags;
  41. #define local_irq_enable() do { \
  42. __asm__ __volatile__ ( \
  43. "sti %0;" \
  44. ::"d"(irq_flags)); \
  45. } while (0)
  46. #define local_irq_disable() do { \
  47. int _tmp_dummy; \
  48. __asm__ __volatile__ ( \
  49. "cli %0;" \
  50. :"=d" (_tmp_dummy):); \
  51. } while (0)
  52. #if defined(ANOMALY_05000244) && defined (CONFIG_BLKFIN_CACHE)
  53. #define idle_with_irq_disabled() do { \
  54. __asm__ __volatile__ ( \
  55. "nop; nop;\n" \
  56. ".align 8;\n" \
  57. "sti %0; idle;\n" \
  58. ::"d" (irq_flags)); \
  59. } while (0)
  60. #else
  61. #define idle_with_irq_disabled() do { \
  62. __asm__ __volatile__ ( \
  63. ".align 8;\n" \
  64. "sti %0; idle;\n" \
  65. ::"d" (irq_flags)); \
  66. } while (0)
  67. #endif
  68. #ifdef CONFIG_DEBUG_HWERR
  69. #define __save_and_cli(x) do { \
  70. __asm__ __volatile__ ( \
  71. "cli %0;\n\tsti %1;" \
  72. :"=&d"(x): "d" (0x3F)); \
  73. } while (0)
  74. #else
  75. #define __save_and_cli(x) do { \
  76. __asm__ __volatile__ ( \
  77. "cli %0;" \
  78. :"=&d"(x):); \
  79. } while (0)
  80. #endif
  81. #define local_save_flags(x) asm volatile ("cli %0;" \
  82. "sti %0;" \
  83. :"=d"(x):);
  84. #ifdef CONFIG_DEBUG_HWERR
  85. #define irqs_enabled_from_flags(x) (((x) & ~0x3f) != 0)
  86. #else
  87. #define irqs_enabled_from_flags(x) ((x) != 0x1f)
  88. #endif
  89. #define local_irq_restore(x) do { \
  90. if (irqs_enabled_from_flags(x)) \
  91. local_irq_enable (); \
  92. } while (0)
  93. /* For spinlocks etc */
  94. #define local_irq_save(x) __save_and_cli(x)
  95. #define irqs_disabled() \
  96. ({ \
  97. unsigned long flags; \
  98. local_save_flags(flags); \
  99. !irqs_enabled_from_flags(flags); \
  100. })
  101. /*
  102. * Force strict CPU ordering.
  103. */
  104. #define nop() asm volatile ("nop;\n\t"::)
  105. #define mb() asm volatile ("" : : :"memory")
  106. #define rmb() asm volatile ("" : : :"memory")
  107. #define wmb() asm volatile ("" : : :"memory")
  108. #define set_rmb(var, value) do { (void) xchg(&var, value); } while (0)
  109. #define set_mb(var, value) set_rmb(var, value)
  110. #define set_wmb(var, value) do { var = value; wmb(); } while (0)
  111. #define read_barrier_depends() do { } while(0)
  112. #ifdef CONFIG_SMP
  113. #define smp_mb() mb()
  114. #define smp_rmb() rmb()
  115. #define smp_wmb() wmb()
  116. #define smp_read_barrier_depends() read_barrier_depends()
  117. #else
  118. #define smp_mb() barrier()
  119. #define smp_rmb() barrier()
  120. #define smp_wmb() barrier()
  121. #define smp_read_barrier_depends() do { } while(0)
  122. #endif
  123. #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
  124. struct __xchg_dummy {
  125. unsigned long a[100];
  126. };
  127. #define __xg(x) ((volatile struct __xchg_dummy *)(x))
  128. static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
  129. int size)
  130. {
  131. unsigned long tmp = 0;
  132. unsigned long flags = 0;
  133. local_irq_save(flags);
  134. switch (size) {
  135. case 1:
  136. __asm__ __volatile__
  137. ("%0 = b%2 (z);\n\t"
  138. "b%2 = %1;\n\t"
  139. : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
  140. break;
  141. case 2:
  142. __asm__ __volatile__
  143. ("%0 = w%2 (z);\n\t"
  144. "w%2 = %1;\n\t"
  145. : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
  146. break;
  147. case 4:
  148. __asm__ __volatile__
  149. ("%0 = %2;\n\t"
  150. "%2 = %1;\n\t"
  151. : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
  152. break;
  153. }
  154. local_irq_restore(flags);
  155. return tmp;
  156. }
  157. /*
  158. * Atomic compare and exchange. Compare OLD with MEM, if identical,
  159. * store NEW in MEM. Return the initial value in MEM. Success is
  160. * indicated by comparing RETURN with OLD.
  161. */
  162. static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
  163. unsigned long new, int size)
  164. {
  165. unsigned long tmp = 0;
  166. unsigned long flags = 0;
  167. local_irq_save(flags);
  168. switch (size) {
  169. case 1:
  170. __asm__ __volatile__
  171. ("%0 = b%3 (z);\n\t"
  172. "CC = %1 == %0;\n\t"
  173. "IF !CC JUMP 1f;\n\t"
  174. "b%3 = %2;\n\t"
  175. "1:\n\t"
  176. : "=&d" (tmp) : "d" (old), "d" (new), "m" (*__xg(ptr)) : "memory");
  177. break;
  178. case 2:
  179. __asm__ __volatile__
  180. ("%0 = w%3 (z);\n\t"
  181. "CC = %1 == %0;\n\t"
  182. "IF !CC JUMP 1f;\n\t"
  183. "w%3 = %2;\n\t"
  184. "1:\n\t"
  185. : "=&d" (tmp) : "d" (old), "d" (new), "m" (*__xg(ptr)) : "memory");
  186. break;
  187. case 4:
  188. __asm__ __volatile__
  189. ("%0 = %3;\n\t"
  190. "CC = %1 == %0;\n\t"
  191. "IF !CC JUMP 1f;\n\t"
  192. "%3 = %2;\n\t"
  193. "1:\n\t"
  194. : "=&d" (tmp) : "d" (old), "d" (new), "m" (*__xg(ptr)) : "memory");
  195. break;
  196. }
  197. local_irq_restore(flags);
  198. return tmp;
  199. }
  200. #define cmpxchg(ptr,o,n)\
  201. ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
  202. (unsigned long)(n),sizeof(*(ptr))))
  203. #define prepare_to_switch() do { } while(0)
  204. /*
  205. * switch_to(n) should switch tasks to task ptr, first checking that
  206. * ptr isn't the current task, in which case it does nothing.
  207. */
  208. #include <asm/blackfin.h>
  209. asmlinkage struct task_struct *resume(struct task_struct *prev, struct task_struct *next);
  210. #define switch_to(prev,next,last) \
  211. do { \
  212. memcpy (&task_thread_info(prev)->l1_task_info, L1_SCRATCH_TASK_INFO, \
  213. sizeof *L1_SCRATCH_TASK_INFO); \
  214. memcpy (L1_SCRATCH_TASK_INFO, &task_thread_info(next)->l1_task_info, \
  215. sizeof *L1_SCRATCH_TASK_INFO); \
  216. (last) = resume (prev, next); \
  217. } while (0)
  218. #endif /* _BLACKFIN_SYSTEM_H */