Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * This file is subject to the terms and conditions of the GNU General Public | |
3 | * License. See the file "COPYING" in the main directory of this archive | |
4 | * for more details. | |
5 | * | |
6 | * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle | |
7 | * Copyright (C) 1996 by Paul M. Antoine | |
8 | * Copyright (C) 1999 Silicon Graphics | |
9 | * Copyright (C) 2000 MIPS Technologies, Inc. | |
10 | */ | |
192ef366 RB |
11 | #ifndef _ASM_IRQFLAGS_H |
12 | #define _ASM_IRQFLAGS_H | |
13 | ||
14 | #ifndef __ASSEMBLY__ | |
1da177e4 | 15 | |
8a1e97ee | 16 | #include <linux/compiler.h> |
02b849f7 | 17 | #include <linux/stringify.h> |
8716a763 | 18 | #include <asm/compiler.h> |
1da177e4 LT |
19 | #include <asm/hazards.h> |
20 | ||
8716a763 | 21 | #if defined(CONFIG_CPU_MIPSR2) || defined (CONFIG_CPU_MIPSR6) |
1da177e4 | 22 | |
02b849f7 RB |
23 | static inline void arch_local_irq_disable(void) |
24 | { | |
25 | __asm__ __volatile__( | |
ff88f8a3 RB |
26 | " .set push \n" |
27 | " .set noat \n" | |
ff88f8a3 | 28 | " di \n" |
02b849f7 | 29 | " " __stringify(__irq_disable_hazard) " \n" |
ff88f8a3 | 30 | " .set pop \n" |
02b849f7 RB |
31 | : /* no outputs */ |
32 | : /* no inputs */ | |
33 | : "memory"); | |
1da177e4 LT |
34 | } |
35 | ||
02b849f7 RB |
36 | static inline unsigned long arch_local_irq_save(void) |
37 | { | |
38 | unsigned long flags; | |
1da177e4 | 39 | |
02b849f7 | 40 | asm __volatile__( |
ff88f8a3 RB |
41 | " .set push \n" |
42 | " .set reorder \n" | |
43 | " .set noat \n" | |
02b849f7 RB |
44 | " di %[flags] \n" |
45 | " andi %[flags], 1 \n" | |
46 | " " __stringify(__irq_disable_hazard) " \n" | |
ff88f8a3 | 47 | " .set pop \n" |
02b849f7 RB |
48 | : [flags] "=r" (flags) |
49 | : /* no inputs */ | |
50 | : "memory"); | |
1da177e4 | 51 | |
df9ee292 DH |
52 | return flags; |
53 | } | |
1da177e4 | 54 | |
02b849f7 RB |
55 | static inline void arch_local_irq_restore(unsigned long flags) |
56 | { | |
57 | unsigned long __tmp1; | |
e97c5b60 | 58 | |
02b849f7 | 59 | __asm__ __volatile__( |
2e66fe24 | 60 | " .set push \n" |
ff88f8a3 RB |
61 | " .set noreorder \n" |
62 | " .set noat \n" | |
67e38cf2 | 63 | #if defined(CONFIG_IRQ_MIPS_CPU) |
ff88f8a3 | 64 | /* |
25985edc | 65 | * Slow, but doesn't suffer from a relatively unlikely race |
ff88f8a3 RB |
66 | * condition we're having since days 1. |
67 | */ | |
02b849f7 | 68 | " beqz %[flags], 1f \n" |
e97c5b60 | 69 | " di \n" |
ff88f8a3 RB |
70 | " ei \n" |
71 | "1: \n" | |
e97c5b60 | 72 | #else |
ff88f8a3 RB |
73 | /* |
74 | * Fast, dangerous. Life is fun, life is good. | |
75 | */ | |
76 | " mfc0 $1, $12 \n" | |
02b849f7 | 77 | " ins $1, %[flags], 0, 1 \n" |
ff88f8a3 | 78 | " mtc0 $1, $12 \n" |
ff88f8a3 | 79 | #endif |
02b849f7 | 80 | " " __stringify(__irq_disable_hazard) " \n" |
2e66fe24 | 81 | " .set pop \n" |
02b849f7 RB |
82 | : [flags] "=r" (__tmp1) |
83 | : "0" (flags) | |
84 | : "memory"); | |
8a1e97ee | 85 | } |
1da177e4 | 86 | |
df9ee292 | 87 | static inline void __arch_local_irq_restore(unsigned long flags) |
8531a35e | 88 | { |
8531a35e | 89 | __asm__ __volatile__( |
02b849f7 RB |
90 | " .set push \n" |
91 | " .set noreorder \n" | |
92 | " .set noat \n" | |
67e38cf2 | 93 | #if defined(CONFIG_IRQ_MIPS_CPU) |
02b849f7 RB |
94 | /* |
95 | * Slow, but doesn't suffer from a relatively unlikely race | |
96 | * condition we're having since days 1. | |
97 | */ | |
98 | " beqz %[flags], 1f \n" | |
99 | " di \n" | |
100 | " ei \n" | |
101 | "1: \n" | |
102 | #else | |
103 | /* | |
104 | * Fast, dangerous. Life is fun, life is good. | |
105 | */ | |
106 | " mfc0 $1, $12 \n" | |
107 | " ins $1, %[flags], 0, 1 \n" | |
108 | " mtc0 $1, $12 \n" | |
109 | #endif | |
110 | " " __stringify(__irq_disable_hazard) " \n" | |
111 | " .set pop \n" | |
112 | : [flags] "=r" (flags) | |
113 | : "0" (flags) | |
114 | : "memory"); | |
8531a35e | 115 | } |
e97c5b60 JQ |
116 | #else |
117 | /* Functions that require preempt_{dis,en}able() are in mips-atomic.c */ | |
118 | void arch_local_irq_disable(void); | |
119 | unsigned long arch_local_irq_save(void); | |
120 | void arch_local_irq_restore(unsigned long flags); | |
121 | void __arch_local_irq_restore(unsigned long flags); | |
8716a763 | 122 | #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */ |
02b849f7 RB |
123 | |
124 | static inline void arch_local_irq_enable(void) | |
125 | { | |
02b849f7 | 126 | __asm__ __volatile__( |
e97c5b60 JQ |
127 | " .set push \n" |
128 | " .set reorder \n" | |
129 | " .set noat \n" | |
8716a763 | 130 | #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) |
e97c5b60 JQ |
131 | " ei \n" |
132 | #else | |
133 | " mfc0 $1,$12 \n" | |
134 | " ori $1,0x1f \n" | |
135 | " xori $1,0x1e \n" | |
136 | " mtc0 $1,$12 \n" | |
137 | #endif | |
02b849f7 | 138 | " " __stringify(__irq_enable_hazard) " \n" |
e97c5b60 | 139 | " .set pop \n" |
02b849f7 RB |
140 | : /* no outputs */ |
141 | : /* no inputs */ | |
142 | : "memory"); | |
e97c5b60 JQ |
143 | } |
144 | ||
02b849f7 RB |
145 | static inline unsigned long arch_local_save_flags(void) |
146 | { | |
147 | unsigned long flags; | |
e97c5b60 | 148 | |
02b849f7 | 149 | asm __volatile__( |
e97c5b60 JQ |
150 | " .set push \n" |
151 | " .set reorder \n" | |
02b849f7 | 152 | " mfc0 %[flags], $12 \n" |
e97c5b60 | 153 | " .set pop \n" |
02b849f7 | 154 | : [flags] "=r" (flags)); |
e97c5b60 | 155 | |
e97c5b60 JQ |
156 | return flags; |
157 | } | |
158 | ||
8531a35e | 159 | |
df9ee292 | 160 | static inline int arch_irqs_disabled_flags(unsigned long flags) |
41c594ab | 161 | { |
41c594ab | 162 | return !(flags & 1); |
41c594ab | 163 | } |
1da177e4 | 164 | |
e97c5b60 | 165 | #endif /* #ifndef __ASSEMBLY__ */ |
192ef366 RB |
166 | |
167 | /* | |
168 | * Do the CPU's IRQ-state tracing from assembly code. | |
169 | */ | |
170 | #ifdef CONFIG_TRACE_IRQFLAGS | |
eae6c0da AN |
171 | /* Reload some registers clobbered by trace_hardirqs_on */ |
172 | #ifdef CONFIG_64BIT | |
173 | # define TRACE_IRQS_RELOAD_REGS \ | |
174 | LONG_L $11, PT_R11(sp); \ | |
175 | LONG_L $10, PT_R10(sp); \ | |
176 | LONG_L $9, PT_R9(sp); \ | |
177 | LONG_L $8, PT_R8(sp); \ | |
178 | LONG_L $7, PT_R7(sp); \ | |
179 | LONG_L $6, PT_R6(sp); \ | |
180 | LONG_L $5, PT_R5(sp); \ | |
181 | LONG_L $4, PT_R4(sp); \ | |
182 | LONG_L $2, PT_R2(sp) | |
183 | #else | |
184 | # define TRACE_IRQS_RELOAD_REGS \ | |
185 | LONG_L $7, PT_R7(sp); \ | |
186 | LONG_L $6, PT_R6(sp); \ | |
187 | LONG_L $5, PT_R5(sp); \ | |
188 | LONG_L $4, PT_R4(sp); \ | |
189 | LONG_L $2, PT_R2(sp) | |
190 | #endif | |
192ef366 | 191 | # define TRACE_IRQS_ON \ |
eae6c0da | 192 | CLI; /* make sure trace_hardirqs_on() is called in kernel level */ \ |
192ef366 | 193 | jal trace_hardirqs_on |
eae6c0da AN |
194 | # define TRACE_IRQS_ON_RELOAD \ |
195 | TRACE_IRQS_ON; \ | |
196 | TRACE_IRQS_RELOAD_REGS | |
192ef366 RB |
197 | # define TRACE_IRQS_OFF \ |
198 | jal trace_hardirqs_off | |
199 | #else | |
200 | # define TRACE_IRQS_ON | |
eae6c0da | 201 | # define TRACE_IRQS_ON_RELOAD |
192ef366 RB |
202 | # define TRACE_IRQS_OFF |
203 | #endif | |
204 | ||
205 | #endif /* _ASM_IRQFLAGS_H */ |