1384740dcSRalf Baechle /*
2384740dcSRalf Baechle * This file is subject to the terms and conditions of the GNU General Public
3384740dcSRalf Baechle * License. See the file "COPYING" in the main directory of this archive
4384740dcSRalf Baechle * for more details.
5384740dcSRalf Baechle *
6384740dcSRalf Baechle * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle
7384740dcSRalf Baechle * Copyright (C) 1996 by Paul M. Antoine
8384740dcSRalf Baechle * Copyright (C) 1999 Silicon Graphics
9384740dcSRalf Baechle * Copyright (C) 2000 MIPS Technologies, Inc.
10384740dcSRalf Baechle */
11384740dcSRalf Baechle #ifndef _ASM_IRQFLAGS_H
12384740dcSRalf Baechle #define _ASM_IRQFLAGS_H
13384740dcSRalf Baechle
14384740dcSRalf Baechle #ifndef __ASSEMBLY__
15384740dcSRalf Baechle
16384740dcSRalf Baechle #include <linux/compiler.h>
1702b849f7SRalf Baechle #include <linux/stringify.h>
188716a763SMarkos Chandras #include <asm/compiler.h>
19384740dcSRalf Baechle #include <asm/hazards.h>
20384740dcSRalf Baechle
21ba9196d2SJiaxun Yang #if defined(CONFIG_CPU_HAS_DIEI)
22e97c5b60SJim Quinlan
arch_local_irq_disable(void)23e97c5b60SJim Quinlan static inline void arch_local_irq_disable(void)
24e97c5b60SJim Quinlan {
25e97c5b60SJim Quinlan __asm__ __volatile__(
2602b849f7SRalf Baechle " .set push \n"
2702b849f7SRalf Baechle " .set noat \n"
2802b849f7SRalf Baechle " di \n"
2902b849f7SRalf Baechle " " __stringify(__irq_disable_hazard) " \n"
3002b849f7SRalf Baechle " .set pop \n"
31e97c5b60SJim Quinlan : /* no outputs */
32e97c5b60SJim Quinlan : /* no inputs */
33e97c5b60SJim Quinlan : "memory");
34e97c5b60SJim Quinlan }
35e97c5b60SJim Quinlan
arch_local_irq_save(void)36e97c5b60SJim Quinlan static inline unsigned long arch_local_irq_save(void)
37e97c5b60SJim Quinlan {
38e97c5b60SJim Quinlan unsigned long flags;
3902b849f7SRalf Baechle
4002b849f7SRalf Baechle asm __volatile__(
4102b849f7SRalf Baechle " .set push \n"
4202b849f7SRalf Baechle " .set reorder \n"
4302b849f7SRalf Baechle " .set noat \n"
44b2afb64cSHuacai Chen #if defined(CONFIG_CPU_LOONGSON64) || defined(CONFIG_CPU_LOONGSON32)
451e820da3SHuacai Chen " mfc0 %[flags], $12 \n"
461e820da3SHuacai Chen " di \n"
471e820da3SHuacai Chen #else
4802b849f7SRalf Baechle " di %[flags] \n"
491e820da3SHuacai Chen #endif
5002b849f7SRalf Baechle " andi %[flags], 1 \n"
5102b849f7SRalf Baechle " " __stringify(__irq_disable_hazard) " \n"
5202b849f7SRalf Baechle " .set pop \n"
5302b849f7SRalf Baechle : [flags] "=r" (flags)
54e97c5b60SJim Quinlan : /* no inputs */
55e97c5b60SJim Quinlan : "memory");
5602b849f7SRalf Baechle
57e97c5b60SJim Quinlan return flags;
58e97c5b60SJim Quinlan }
59e97c5b60SJim Quinlan
arch_local_irq_restore(unsigned long flags)6002b849f7SRalf Baechle static inline void arch_local_irq_restore(unsigned long flags)
6102b849f7SRalf Baechle {
6202b849f7SRalf Baechle unsigned long __tmp1;
63e97c5b60SJim Quinlan
6402b849f7SRalf Baechle __asm__ __volatile__(
65e97c5b60SJim Quinlan " .set push \n"
66e97c5b60SJim Quinlan " .set noreorder \n"
67e97c5b60SJim Quinlan " .set noat \n"
6867e38cf2SRalf Baechle #if defined(CONFIG_IRQ_MIPS_CPU)
69e97c5b60SJim Quinlan /*
70e97c5b60SJim Quinlan * Slow, but doesn't suffer from a relatively unlikely race
71e97c5b60SJim Quinlan * condition we're having since days 1.
72e97c5b60SJim Quinlan */
7302b849f7SRalf Baechle " beqz %[flags], 1f \n"
74e97c5b60SJim Quinlan " di \n"
75e97c5b60SJim Quinlan " ei \n"
76e97c5b60SJim Quinlan "1: \n"
77e97c5b60SJim Quinlan #else
78e97c5b60SJim Quinlan /*
79e97c5b60SJim Quinlan * Fast, dangerous. Life is fun, life is good.
80e97c5b60SJim Quinlan */
81e97c5b60SJim Quinlan " mfc0 $1, $12 \n"
8202b849f7SRalf Baechle " ins $1, %[flags], 0, 1 \n"
83e97c5b60SJim Quinlan " mtc0 $1, $12 \n"
84e97c5b60SJim Quinlan #endif
8502b849f7SRalf Baechle " " __stringify(__irq_disable_hazard) " \n"
86e97c5b60SJim Quinlan " .set pop \n"
8702b849f7SRalf Baechle : [flags] "=r" (__tmp1)
88e97c5b60SJim Quinlan : "0" (flags)
89e97c5b60SJim Quinlan : "memory");
90e97c5b60SJim Quinlan }
91e97c5b60SJim Quinlan
92e97c5b60SJim Quinlan #else
93e97c5b60SJim Quinlan /* Functions that require preempt_{dis,en}able() are in mips-atomic.c */
94e97c5b60SJim Quinlan void arch_local_irq_disable(void);
95e97c5b60SJim Quinlan unsigned long arch_local_irq_save(void);
96e97c5b60SJim Quinlan void arch_local_irq_restore(unsigned long flags);
97ba9196d2SJiaxun Yang #endif /* CONFIG_CPU_HAS_DIEI */
9802b849f7SRalf Baechle
arch_local_irq_enable(void)9902b849f7SRalf Baechle static inline void arch_local_irq_enable(void)
10002b849f7SRalf Baechle {
10102b849f7SRalf Baechle __asm__ __volatile__(
102384740dcSRalf Baechle " .set push \n"
103384740dcSRalf Baechle " .set reorder \n"
104384740dcSRalf Baechle " .set noat \n"
105ba9196d2SJiaxun Yang #if defined(CONFIG_CPU_HAS_DIEI)
106384740dcSRalf Baechle " ei \n"
107384740dcSRalf Baechle #else
108384740dcSRalf Baechle " mfc0 $1,$12 \n"
109384740dcSRalf Baechle " ori $1,0x1f \n"
110384740dcSRalf Baechle " xori $1,0x1e \n"
111384740dcSRalf Baechle " mtc0 $1,$12 \n"
112384740dcSRalf Baechle #endif
11302b849f7SRalf Baechle " " __stringify(__irq_enable_hazard) " \n"
114384740dcSRalf Baechle " .set pop \n"
115384740dcSRalf Baechle : /* no outputs */
116384740dcSRalf Baechle : /* no inputs */
117384740dcSRalf Baechle : "memory");
118384740dcSRalf Baechle }
119384740dcSRalf Baechle
arch_local_save_flags(void)120df9ee292SDavid Howells static inline unsigned long arch_local_save_flags(void)
121df9ee292SDavid Howells {
122df9ee292SDavid Howells unsigned long flags;
12302b849f7SRalf Baechle
12402b849f7SRalf Baechle asm __volatile__(
12502b849f7SRalf Baechle " .set push \n"
12602b849f7SRalf Baechle " .set reorder \n"
12702b849f7SRalf Baechle " mfc0 %[flags], $12 \n"
12802b849f7SRalf Baechle " .set pop \n"
12902b849f7SRalf Baechle : [flags] "=r" (flags));
13002b849f7SRalf Baechle
131df9ee292SDavid Howells return flags;
132df9ee292SDavid Howells }
133384740dcSRalf Baechle
134384740dcSRalf Baechle
arch_irqs_disabled_flags(unsigned long flags)135df9ee292SDavid Howells static inline int arch_irqs_disabled_flags(unsigned long flags)
136384740dcSRalf Baechle {
137384740dcSRalf Baechle return !(flags & 1);
138384740dcSRalf Baechle }
139384740dcSRalf Baechle
arch_irqs_disabled(void)140*99dc56feSPeter Zijlstra static inline int arch_irqs_disabled(void)
141*99dc56feSPeter Zijlstra {
142*99dc56feSPeter Zijlstra return arch_irqs_disabled_flags(arch_local_save_flags());
143*99dc56feSPeter Zijlstra }
144*99dc56feSPeter Zijlstra
145e97c5b60SJim Quinlan #endif /* #ifndef __ASSEMBLY__ */
146384740dcSRalf Baechle
147384740dcSRalf Baechle /*
148384740dcSRalf Baechle * Do the CPU's IRQ-state tracing from assembly code.
149384740dcSRalf Baechle */
150384740dcSRalf Baechle #ifdef CONFIG_TRACE_IRQFLAGS
151384740dcSRalf Baechle /* Reload some registers clobbered by trace_hardirqs_on */
152384740dcSRalf Baechle #ifdef CONFIG_64BIT
153384740dcSRalf Baechle # define TRACE_IRQS_RELOAD_REGS \
154384740dcSRalf Baechle LONG_L $11, PT_R11(sp); \
155384740dcSRalf Baechle LONG_L $10, PT_R10(sp); \
156384740dcSRalf Baechle LONG_L $9, PT_R9(sp); \
157384740dcSRalf Baechle LONG_L $8, PT_R8(sp); \
158384740dcSRalf Baechle LONG_L $7, PT_R7(sp); \
159384740dcSRalf Baechle LONG_L $6, PT_R6(sp); \
160384740dcSRalf Baechle LONG_L $5, PT_R5(sp); \
161384740dcSRalf Baechle LONG_L $4, PT_R4(sp); \
162384740dcSRalf Baechle LONG_L $2, PT_R2(sp)
163384740dcSRalf Baechle #else
164384740dcSRalf Baechle # define TRACE_IRQS_RELOAD_REGS \
165384740dcSRalf Baechle LONG_L $7, PT_R7(sp); \
166384740dcSRalf Baechle LONG_L $6, PT_R6(sp); \
167384740dcSRalf Baechle LONG_L $5, PT_R5(sp); \
168384740dcSRalf Baechle LONG_L $4, PT_R4(sp); \
169384740dcSRalf Baechle LONG_L $2, PT_R2(sp)
170384740dcSRalf Baechle #endif
171384740dcSRalf Baechle # define TRACE_IRQS_ON \
172384740dcSRalf Baechle CLI; /* make sure trace_hardirqs_on() is called in kernel level */ \
173384740dcSRalf Baechle jal trace_hardirqs_on
174384740dcSRalf Baechle # define TRACE_IRQS_ON_RELOAD \
175384740dcSRalf Baechle TRACE_IRQS_ON; \
176384740dcSRalf Baechle TRACE_IRQS_RELOAD_REGS
177384740dcSRalf Baechle # define TRACE_IRQS_OFF \
178384740dcSRalf Baechle jal trace_hardirqs_off
179384740dcSRalf Baechle #else
180384740dcSRalf Baechle # define TRACE_IRQS_ON
181384740dcSRalf Baechle # define TRACE_IRQS_ON_RELOAD
182384740dcSRalf Baechle # define TRACE_IRQS_OFF
183384740dcSRalf Baechle #endif
184384740dcSRalf Baechle
185384740dcSRalf Baechle #endif /* _ASM_IRQFLAGS_H */
186