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" | |
1e820da3 HC |
44 | #if defined(CONFIG_CPU_LOONGSON3) |
45 | " mfc0 %[flags], $12 \n" | |
46 | " di \n" | |
47 | #else | |
02b849f7 | 48 | " di %[flags] \n" |
1e820da3 | 49 | #endif |
02b849f7 RB |
50 | " andi %[flags], 1 \n" |
51 | " " __stringify(__irq_disable_hazard) " \n" | |
ff88f8a3 | 52 | " .set pop \n" |
02b849f7 RB |
53 | : [flags] "=r" (flags) |
54 | : /* no inputs */ | |
55 | : "memory"); | |
1da177e4 | 56 | |
df9ee292 DH |
57 | return flags; |
58 | } | |
1da177e4 | 59 | |
02b849f7 RB |
60 | static inline void arch_local_irq_restore(unsigned long flags) |
61 | { | |
62 | unsigned long __tmp1; | |
e97c5b60 | 63 | |
02b849f7 | 64 | __asm__ __volatile__( |
2e66fe24 | 65 | " .set push \n" |
ff88f8a3 RB |
66 | " .set noreorder \n" |
67 | " .set noat \n" | |
67e38cf2 | 68 | #if defined(CONFIG_IRQ_MIPS_CPU) |
ff88f8a3 | 69 | /* |
25985edc | 70 | * Slow, but doesn't suffer from a relatively unlikely race |
ff88f8a3 RB |
71 | * condition we're having since days 1. |
72 | */ | |
02b849f7 | 73 | " beqz %[flags], 1f \n" |
e97c5b60 | 74 | " di \n" |
ff88f8a3 RB |
75 | " ei \n" |
76 | "1: \n" | |
e97c5b60 | 77 | #else |
ff88f8a3 RB |
78 | /* |
79 | * Fast, dangerous. Life is fun, life is good. | |
80 | */ | |
81 | " mfc0 $1, $12 \n" | |
02b849f7 | 82 | " ins $1, %[flags], 0, 1 \n" |
ff88f8a3 | 83 | " mtc0 $1, $12 \n" |
ff88f8a3 | 84 | #endif |
02b849f7 | 85 | " " __stringify(__irq_disable_hazard) " \n" |
2e66fe24 | 86 | " .set pop \n" |
02b849f7 RB |
87 | : [flags] "=r" (__tmp1) |
88 | : "0" (flags) | |
89 | : "memory"); | |
8a1e97ee | 90 | } |
1da177e4 | 91 | |
e97c5b60 JQ |
92 | #else |
93 | /* Functions that require preempt_{dis,en}able() are in mips-atomic.c */ | |
94 | void arch_local_irq_disable(void); | |
95 | unsigned long arch_local_irq_save(void); | |
96 | void arch_local_irq_restore(unsigned long flags); | |
8716a763 | 97 | #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */ |
02b849f7 RB |
98 | |
99 | static inline void arch_local_irq_enable(void) | |
100 | { | |
02b849f7 | 101 | __asm__ __volatile__( |
e97c5b60 JQ |
102 | " .set push \n" |
103 | " .set reorder \n" | |
104 | " .set noat \n" | |
8716a763 | 105 | #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) |
e97c5b60 JQ |
106 | " ei \n" |
107 | #else | |
108 | " mfc0 $1,$12 \n" | |
109 | " ori $1,0x1f \n" | |
110 | " xori $1,0x1e \n" | |
111 | " mtc0 $1,$12 \n" | |
112 | #endif | |
02b849f7 | 113 | " " __stringify(__irq_enable_hazard) " \n" |
e97c5b60 | 114 | " .set pop \n" |
02b849f7 RB |
115 | : /* no outputs */ |
116 | : /* no inputs */ | |
117 | : "memory"); | |
e97c5b60 JQ |
118 | } |
119 | ||
02b849f7 RB |
120 | static inline unsigned long arch_local_save_flags(void) |
121 | { | |
122 | unsigned long flags; | |
e97c5b60 | 123 | |
02b849f7 | 124 | asm __volatile__( |
e97c5b60 JQ |
125 | " .set push \n" |
126 | " .set reorder \n" | |
02b849f7 | 127 | " mfc0 %[flags], $12 \n" |
e97c5b60 | 128 | " .set pop \n" |
02b849f7 | 129 | : [flags] "=r" (flags)); |
e97c5b60 | 130 | |
e97c5b60 JQ |
131 | return flags; |
132 | } | |
133 | ||
8531a35e | 134 | |
df9ee292 | 135 | static inline int arch_irqs_disabled_flags(unsigned long flags) |
41c594ab | 136 | { |
41c594ab | 137 | return !(flags & 1); |
41c594ab | 138 | } |
1da177e4 | 139 | |
e97c5b60 | 140 | #endif /* #ifndef __ASSEMBLY__ */ |
192ef366 RB |
141 | |
142 | /* | |
143 | * Do the CPU's IRQ-state tracing from assembly code. | |
144 | */ | |
145 | #ifdef CONFIG_TRACE_IRQFLAGS | |
eae6c0da AN |
146 | /* Reload some registers clobbered by trace_hardirqs_on */ |
147 | #ifdef CONFIG_64BIT | |
148 | # define TRACE_IRQS_RELOAD_REGS \ | |
149 | LONG_L $11, PT_R11(sp); \ | |
150 | LONG_L $10, PT_R10(sp); \ | |
151 | LONG_L $9, PT_R9(sp); \ | |
152 | LONG_L $8, PT_R8(sp); \ | |
153 | LONG_L $7, PT_R7(sp); \ | |
154 | LONG_L $6, PT_R6(sp); \ | |
155 | LONG_L $5, PT_R5(sp); \ | |
156 | LONG_L $4, PT_R4(sp); \ | |
157 | LONG_L $2, PT_R2(sp) | |
158 | #else | |
159 | # define TRACE_IRQS_RELOAD_REGS \ | |
160 | LONG_L $7, PT_R7(sp); \ | |
161 | LONG_L $6, PT_R6(sp); \ | |
162 | LONG_L $5, PT_R5(sp); \ | |
163 | LONG_L $4, PT_R4(sp); \ | |
164 | LONG_L $2, PT_R2(sp) | |
165 | #endif | |
192ef366 | 166 | # define TRACE_IRQS_ON \ |
eae6c0da | 167 | CLI; /* make sure trace_hardirqs_on() is called in kernel level */ \ |
192ef366 | 168 | jal trace_hardirqs_on |
eae6c0da AN |
169 | # define TRACE_IRQS_ON_RELOAD \ |
170 | TRACE_IRQS_ON; \ | |
171 | TRACE_IRQS_RELOAD_REGS | |
192ef366 RB |
172 | # define TRACE_IRQS_OFF \ |
173 | jal trace_hardirqs_off | |
174 | #else | |
175 | # define TRACE_IRQS_ON | |
eae6c0da | 176 | # define TRACE_IRQS_ON_RELOAD |
192ef366 RB |
177 | # define TRACE_IRQS_OFF |
178 | #endif | |
179 | ||
180 | #endif /* _ASM_IRQFLAGS_H */ |