0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef _ASM_IRQFLAGS_H
0012 #define _ASM_IRQFLAGS_H
0013
0014 #ifndef __ASSEMBLY__
0015
0016 #include <linux/compiler.h>
0017 #include <linux/stringify.h>
0018 #include <asm/compiler.h>
0019 #include <asm/hazards.h>
0020
0021 #if defined(CONFIG_CPU_HAS_DIEI)
0022
0023 static inline void arch_local_irq_disable(void)
0024 {
0025 __asm__ __volatile__(
0026 " .set push \n"
0027 " .set noat \n"
0028 " di \n"
0029 " " __stringify(__irq_disable_hazard) " \n"
0030 " .set pop \n"
0031 :
0032 :
0033 : "memory");
0034 }
0035
0036 static inline unsigned long arch_local_irq_save(void)
0037 {
0038 unsigned long flags;
0039
0040 asm __volatile__(
0041 " .set push \n"
0042 " .set reorder \n"
0043 " .set noat \n"
0044 #if defined(CONFIG_CPU_LOONGSON64) || defined(CONFIG_CPU_LOONGSON32)
0045 " mfc0 %[flags], $12 \n"
0046 " di \n"
0047 #else
0048 " di %[flags] \n"
0049 #endif
0050 " andi %[flags], 1 \n"
0051 " " __stringify(__irq_disable_hazard) " \n"
0052 " .set pop \n"
0053 : [flags] "=r" (flags)
0054 :
0055 : "memory");
0056
0057 return flags;
0058 }
0059
0060 static inline void arch_local_irq_restore(unsigned long flags)
0061 {
0062 unsigned long __tmp1;
0063
0064 __asm__ __volatile__(
0065 " .set push \n"
0066 " .set noreorder \n"
0067 " .set noat \n"
0068 #if defined(CONFIG_IRQ_MIPS_CPU)
0069
0070
0071
0072
0073 " beqz %[flags], 1f \n"
0074 " di \n"
0075 " ei \n"
0076 "1: \n"
0077 #else
0078
0079
0080
0081 " mfc0 $1, $12 \n"
0082 " ins $1, %[flags], 0, 1 \n"
0083 " mtc0 $1, $12 \n"
0084 #endif
0085 " " __stringify(__irq_disable_hazard) " \n"
0086 " .set pop \n"
0087 : [flags] "=r" (__tmp1)
0088 : "0" (flags)
0089 : "memory");
0090 }
0091
0092 #else
0093
0094 void arch_local_irq_disable(void);
0095 unsigned long arch_local_irq_save(void);
0096 void arch_local_irq_restore(unsigned long flags);
0097 #endif
0098
0099 static inline void arch_local_irq_enable(void)
0100 {
0101 __asm__ __volatile__(
0102 " .set push \n"
0103 " .set reorder \n"
0104 " .set noat \n"
0105 #if defined(CONFIG_CPU_HAS_DIEI)
0106 " ei \n"
0107 #else
0108 " mfc0 $1,$12 \n"
0109 " ori $1,0x1f \n"
0110 " xori $1,0x1e \n"
0111 " mtc0 $1,$12 \n"
0112 #endif
0113 " " __stringify(__irq_enable_hazard) " \n"
0114 " .set pop \n"
0115 :
0116 :
0117 : "memory");
0118 }
0119
0120 static inline unsigned long arch_local_save_flags(void)
0121 {
0122 unsigned long flags;
0123
0124 asm __volatile__(
0125 " .set push \n"
0126 " .set reorder \n"
0127 " mfc0 %[flags], $12 \n"
0128 " .set pop \n"
0129 : [flags] "=r" (flags));
0130
0131 return flags;
0132 }
0133
0134
0135 static inline int arch_irqs_disabled_flags(unsigned long flags)
0136 {
0137 return !(flags & 1);
0138 }
0139
0140 static inline int arch_irqs_disabled(void)
0141 {
0142 return arch_irqs_disabled_flags(arch_local_save_flags());
0143 }
0144
0145 #endif
0146
0147
0148
0149
0150 #ifdef CONFIG_TRACE_IRQFLAGS
0151
0152 #ifdef CONFIG_64BIT
0153 # define TRACE_IRQS_RELOAD_REGS \
0154 LONG_L $11, PT_R11(sp); \
0155 LONG_L $10, PT_R10(sp); \
0156 LONG_L $9, PT_R9(sp); \
0157 LONG_L $8, PT_R8(sp); \
0158 LONG_L $7, PT_R7(sp); \
0159 LONG_L $6, PT_R6(sp); \
0160 LONG_L $5, PT_R5(sp); \
0161 LONG_L $4, PT_R4(sp); \
0162 LONG_L $2, PT_R2(sp)
0163 #else
0164 # define TRACE_IRQS_RELOAD_REGS \
0165 LONG_L $7, PT_R7(sp); \
0166 LONG_L $6, PT_R6(sp); \
0167 LONG_L $5, PT_R5(sp); \
0168 LONG_L $4, PT_R4(sp); \
0169 LONG_L $2, PT_R2(sp)
0170 #endif
0171 # define TRACE_IRQS_ON \
0172 CLI; \
0173 jal trace_hardirqs_on
0174 # define TRACE_IRQS_ON_RELOAD \
0175 TRACE_IRQS_ON; \
0176 TRACE_IRQS_RELOAD_REGS
0177 # define TRACE_IRQS_OFF \
0178 jal trace_hardirqs_off
0179 #else
0180 # define TRACE_IRQS_ON
0181 # define TRACE_IRQS_ON_RELOAD
0182 # define TRACE_IRQS_OFF
0183 #endif
0184
0185 #endif