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-xtensa / system.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  5.7 KB  |  234 lines

  1. /*
  2.  * include/asm-xtensa/system.h
  3.  *
  4.  * This file is subject to the terms and conditions of the GNU General Public
  5.  * License.  See the file "COPYING" in the main directory of this archive
  6.  * for more details.
  7.  *
  8.  * Copyright (C) 2001 - 2005 Tensilica Inc.
  9.  */
  10.  
  11. #ifndef _XTENSA_SYSTEM_H
  12. #define _XTENSA_SYSTEM_H
  13.  
  14. #include <linux/stringify.h>
  15.  
  16. #include <asm/processor.h>
  17.  
  18. /* interrupt control */
  19.  
  20. #define local_save_flags(x)                        \
  21.     __asm__ __volatile__ ("rsr %0,"__stringify(PS) : "=a" (x));
  22. #define local_irq_restore(x)    do {                    \
  23.     __asm__ __volatile__ ("wsr %0, "__stringify(PS)" ; rsync"     \
  24.                       :: "a" (x) : "memory"); } while(0);
  25. #define local_irq_save(x)    do {                    \
  26.     __asm__ __volatile__ ("rsil %0, "__stringify(LOCKLEVEL)     \
  27.                       : "=a" (x) :: "memory");} while(0);
  28.  
  29. static inline void local_irq_disable(void)
  30. {
  31.     unsigned long flags;
  32.     __asm__ __volatile__ ("rsil %0, "__stringify(LOCKLEVEL)
  33.                       : "=a" (flags) :: "memory");
  34. }
  35. static inline void local_irq_enable(void)
  36. {
  37.     unsigned long flags;
  38.     __asm__ __volatile__ ("rsil %0, 0" : "=a" (flags) :: "memory");
  39.  
  40. }
  41.  
  42. static inline int irqs_disabled(void)
  43. {
  44.     unsigned long flags;
  45.     local_save_flags(flags);
  46.     return flags & 0xf;
  47. }
  48.  
  49. #define RSR_CPENABLE(x)    do {                          \
  50.     __asm__ __volatile__("rsr %0," __stringify(CPENABLE) : "=a" (x)); \
  51.     } while(0);
  52. #define WSR_CPENABLE(x)    do {                          \
  53.       __asm__ __volatile__("wsr %0," __stringify(CPENABLE)";rsync"       \
  54.                      :: "a" (x));} while(0);
  55.  
  56. #define clear_cpenable() __clear_cpenable()
  57.  
  58. static inline void __clear_cpenable(void)
  59. {
  60. #if XCHAL_HAVE_CP
  61.     unsigned long i = 0;
  62.     WSR_CPENABLE(i);
  63. #endif
  64. }
  65.  
  66. static inline void enable_coprocessor(int i)
  67. {
  68. #if XCHAL_HAVE_CP
  69.     int cp;
  70.     RSR_CPENABLE(cp);
  71.     cp |= 1 << i;
  72.     WSR_CPENABLE(cp);
  73. #endif
  74. }
  75.  
  76. static inline void disable_coprocessor(int i)
  77. {
  78. #if XCHAL_HAVE_CP
  79.     int cp;
  80.     RSR_CPENABLE(cp);
  81.     cp &= ~(1 << i);
  82.     WSR_CPENABLE(cp);
  83. #endif
  84. }
  85.  
  86. #define smp_read_barrier_depends() do { } while(0)
  87. #define read_barrier_depends() do { } while(0)
  88.  
  89. #define mb()  barrier()
  90. #define rmb() mb()
  91. #define wmb() mb()
  92.  
  93. #ifdef CONFIG_SMP
  94. #error smp_* not defined
  95. #else
  96. #define smp_mb()    barrier()
  97. #define smp_rmb()    barrier()
  98. #define smp_wmb()    barrier()
  99. #endif
  100.  
  101. #define set_mb(var, value)    do { var = value; mb(); } while (0)
  102. #define set_wmb(var, value)    do { var = value; wmb(); } while (0)
  103.  
  104. #if !defined (__ASSEMBLY__)
  105.  
  106. /* * switch_to(n) should switch tasks to task nr n, first
  107.  * checking that n isn't the current task, in which case it does nothing.
  108.  */
  109. extern void *_switch_to(void *last, void *next);
  110.  
  111. #endif    /* __ASSEMBLY__ */
  112.  
  113. #define switch_to(prev,next,last)        \
  114. do {                        \
  115.     clear_cpenable();            \
  116.     (last) = _switch_to(prev, next);    \
  117. } while(0)
  118.  
  119. /*
  120.  * cmpxchg
  121.  */
  122.  
  123. static inline unsigned long
  124. __cmpxchg_u32(volatile int *p, int old, int new)
  125. {
  126.   __asm__ __volatile__("rsil    a15, "__stringify(LOCKLEVEL)"\n\t"
  127.                "l32i    %0, %1, 0              \n\t"
  128.                "bne    %0, %2, 1f             \n\t"
  129.                "s32i    %3, %1, 0              \n\t"
  130.                "1:                             \n\t"
  131.                "wsr     a15, "__stringify(PS)" \n\t"
  132.                "rsync                          \n\t"
  133.                : "=&a" (old)
  134.                : "a" (p), "a" (old), "r" (new)
  135.                : "a15", "memory");
  136.   return old;
  137. }
  138. /* This function doesn't exist, so you'll get a linker error
  139.  * if something tries to do an invalid cmpxchg(). */
  140.  
  141. extern void __cmpxchg_called_with_bad_pointer(void);
  142.  
  143. static __inline__ unsigned long
  144. __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
  145. {
  146.     switch (size) {
  147.     case 4:  return __cmpxchg_u32(ptr, old, new);
  148.     default: __cmpxchg_called_with_bad_pointer();
  149.          return old;
  150.     }
  151. }
  152.  
  153. #define cmpxchg(ptr,o,n)                              \
  154.     ({ __typeof__(*(ptr)) _o_ = (o);                      \
  155.        __typeof__(*(ptr)) _n_ = (n);                      \
  156.        (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,          \
  157.                            (unsigned long)_n_, sizeof (*(ptr))); \
  158.     })
  159.  
  160.  
  161.  
  162.  
  163. /*
  164.  * xchg_u32
  165.  *
  166.  * Note that a15 is used here because the register allocation
  167.  * done by the compiler is not guaranteed and a window overflow
  168.  * may not occur between the rsil and wsr instructions. By using
  169.  * a15 in the rsil, the machine is guaranteed to be in a state
  170.  * where no register reference will cause an overflow.
  171.  */
  172.  
  173. static inline unsigned long xchg_u32(volatile int * m, unsigned long val)
  174. {
  175.   unsigned long tmp;
  176.   __asm__ __volatile__("rsil    a15, "__stringify(LOCKLEVEL)"\n\t"
  177.                "l32i    %0, %1, 0              \n\t"
  178.                "s32i    %2, %1, 0              \n\t"
  179.                "wsr     a15, "__stringify(PS)" \n\t"
  180.                "rsync                          \n\t"
  181.                : "=&a" (tmp)
  182.                : "a" (m), "a" (val)
  183.                : "a15", "memory");
  184.   return tmp;
  185. }
  186.  
  187. #define tas(ptr) (xchg((ptr),1))
  188.  
  189. #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
  190.  
  191. /*
  192.  * This only works if the compiler isn't horribly bad at optimizing.
  193.  * gcc-2.5.8 reportedly can't handle this, but I define that one to
  194.  * be dead anyway.
  195.  */
  196.  
  197. extern void __xchg_called_with_bad_pointer(void);
  198.  
  199. static __inline__ unsigned long
  200. __xchg(unsigned long x, volatile void * ptr, int size)
  201. {
  202.     switch (size) {
  203.         case 4:
  204.             return xchg_u32(ptr, x);
  205.     }
  206.     __xchg_called_with_bad_pointer();
  207.     return x;
  208. }
  209.  
  210. extern void set_except_vector(int n, void *addr);
  211.  
  212. static inline void spill_registers(void)
  213. {
  214.     unsigned int a0, ps;
  215.  
  216.     __asm__ __volatile__ (
  217.         "movi    a14," __stringify (PS_EXCM_MASK) " | 1\n\t"
  218.         "mov    a12, a0\n\t"
  219.         "rsr    a13," __stringify(SAR) "\n\t"
  220.         "xsr    a14," __stringify(PS) "\n\t"
  221.         "movi    a0, _spill_registers\n\t"
  222.         "rsync\n\t"
  223.         "callx0 a0\n\t"
  224.         "mov    a0, a12\n\t"
  225.         "wsr    a13," __stringify(SAR) "\n\t"
  226.         "wsr    a14," __stringify(PS) "\n\t"
  227.         :: "a" (&a0), "a" (&ps)
  228.         : "a2", "a3", "a12", "a13", "a14", "a15", "memory");
  229. }
  230.  
  231. #define arch_align_stack(x) (x)
  232.  
  233. #endif    /* _XTENSA_SYSTEM_H */
  234.