fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / include / asm-frv / system.h
index 29cfa21..1166899 100644 (file)
 #ifndef _ASM_SYSTEM_H
 #define _ASM_SYSTEM_H
 
-#include <linux/config.h> /* get configuration macros */
 #include <linux/linkage.h>
 #include <asm/atomic.h>
 
 struct thread_struct;
 
-#define prepare_to_switch()    do { } while(0)
-
 /*
  * switch_to(prev, next) should switch from task `prev' to `next'
  * `prev' will never be the same as `next'.
@@ -40,8 +37,84 @@ do {                                                                 \
 
 /*
  * interrupt flag manipulation
+ * - use virtual interrupt management since touching the PSR is slow
+ *   - ICC2.Z: T if interrupts virtually disabled
+ *   - ICC2.C: F if interrupts really disabled
+ * - if Z==1 upon interrupt:
+ *   - C is set to 0
+ *   - interrupts are really disabled
+ *   - entry.S returns immediately
+ * - uses TIHI (TRAP if Z==0 && C==0) #2 to really reenable interrupts
+ *   - if taken, the trap:
+ *     - sets ICC2.C
+ *     - enables interrupts
+ */
+#define local_irq_disable()                                    \
+do {                                                           \
+       /* set Z flag, but don't change the C flag */           \
+       asm volatile("  andcc   gr0,gr0,gr0,icc2        \n"     \
+                    :                                          \
+                    :                                          \
+                    : "memory", "icc2"                         \
+                    );                                         \
+} while(0)
+
+#define local_irq_enable()                                     \
+do {                                                           \
+       /* clear Z flag and then test the C flag */             \
+       asm volatile("  oricc   gr0,#1,gr0,icc2         \n"     \
+                    "  tihi    icc2,gr0,#2             \n"     \
+                    :                                          \
+                    :                                          \
+                    : "memory", "icc2"                         \
+                    );                                         \
+} while(0)
+
+#define local_save_flags(flags)                                        \
+do {                                                           \
+       typecheck(unsigned long, flags);                        \
+       asm volatile("movsg ccr,%0"                             \
+                    : "=r"(flags)                              \
+                    :                                          \
+                    : "memory");                               \
+                                                               \
+       /* shift ICC2.Z to bit 0 */                             \
+       flags >>= 26;                                           \
+                                                               \
+       /* make flags 1 if interrupts disabled, 0 otherwise */  \
+       flags &= 1UL;                                           \
+} while(0)
+
+#define irqs_disabled() \
+       ({unsigned long flags; local_save_flags(flags); flags; })
+
+#define        local_irq_save(flags)                   \
+do {                                           \
+       typecheck(unsigned long, flags);        \
+       local_save_flags(flags);                \
+       local_irq_disable();                    \
+} while(0)
+
+#define        local_irq_restore(flags)                                        \
+do {                                                                   \
+       typecheck(unsigned long, flags);                                \
+                                                                       \
+       /* load the Z flag by turning 1 if disabled into 0 if disabled  \
+        * and thus setting the Z flag but not the C flag */            \
+       asm volatile("  xoricc  %0,#1,gr0,icc2          \n"             \
+                    /* then test Z=0 and C=0 */                        \
+                    "  tihi    icc2,gr0,#2             \n"             \
+                    :                                                  \
+                    : "r"(flags)                                       \
+                    : "memory", "icc2"                                 \
+                    );                                                 \
+                                                                       \
+} while(0)
+
+/*
+ * real interrupt flag manipulation
  */
-#define local_irq_disable()                            \
+#define __local_irq_disable()                          \
 do {                                                   \
        unsigned long psr;                              \
        asm volatile("  movsg   psr,%0          \n"     \
@@ -53,7 +126,7 @@ do {                                                 \
                     : "memory");                       \
 } while(0)
 
-#define local_irq_enable()                             \
+#define __local_irq_enable()                           \
 do {                                                   \
        unsigned long psr;                              \
        asm volatile("  movsg   psr,%0          \n"     \
@@ -64,7 +137,7 @@ do {                                                 \
                     : "memory");                       \
 } while(0)
 
-#define local_save_flags(flags)                        \
+#define __local_save_flags(flags)              \
 do {                                           \
        typecheck(unsigned long, flags);        \
        asm("movsg psr,%0"                      \
@@ -73,7 +146,7 @@ do {                                         \
            : "memory");                        \
 } while(0)
 
-#define        local_irq_save(flags)                           \
+#define        __local_irq_save(flags)                         \
 do {                                                   \
        unsigned long npsr;                             \
        typecheck(unsigned long, flags);                \
@@ -86,7 +159,7 @@ do {                                                 \
                     : "memory");                       \
 } while(0)
 
-#define        local_irq_restore(flags)                        \
+#define        __local_irq_restore(flags)                      \
 do {                                                   \
        typecheck(unsigned long, flags);                \
        asm volatile("  movgs   %0,psr          \n"     \
@@ -95,7 +168,7 @@ do {                                                 \
                     : "memory");                       \
 } while(0)
 
-#define irqs_disabled() \
+#define __irqs_disabled() \
        ((__get_PSR() & PSR_PIL) >= PSR_PIL_14)
 
 /*
@@ -106,7 +179,6 @@ do {                                                        \
 #define rmb()                  asm volatile ("membar" : : :"memory")
 #define wmb()                  asm volatile ("membar" : : :"memory")
 #define set_mb(var, value)     do { var = value; mb(); } while (0)
-#define set_wmb(var, value)    do { var = value; wmb(); } while (0)
 
 #define smp_mb()               mb()
 #define smp_rmb()              rmb()
@@ -123,4 +195,6 @@ do {                                                \
 extern void die_if_kernel(const char *, ...) __attribute__((format(printf, 1, 2)));
 extern void free_initmem(void);
 
+#define arch_align_stack(x) (x)
+
 #endif /* _ASM_SYSTEM_H */