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
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.
11 #include <asm/irqflags.h>
12 #include <asm/hazards.h>
13 #include <linux/compiler.h>
14 #include <linux/preempt.h>
15 #include <linux/export.h>
17 #if !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC)
20 * For cli() we have to insert nops to make sure that the new value
21 * has actually arrived in the status register before the end of this
23 * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
27 * For TX49, operating only IE bit is not enough.
29 * If mfc0 $12 follows store and the mfc0 is last instruction of a
30 * page and fetching the next instruction causes TLB miss, the result
31 * of the mfc0 might wrongly contain EXL bit.
33 * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008
35 * Workaround: mask EXL bit of the result or place a nop before mfc0.
38 " .macro arch_local_irq_disable\n"
41 #ifdef CONFIG_MIPS_MT_SMTC
46 #elif defined(CONFIG_CPU_MIPSR2)
47 /* see irqflags.h for inline function */
55 " irq_disable_hazard \n"
59 notrace void arch_local_irq_disable(void)
63 "arch_local_irq_disable"
69 EXPORT_SYMBOL(arch_local_irq_disable);
73 " .macro arch_local_irq_save result \n"
77 #ifdef CONFIG_MIPS_MT_SMTC
78 " mfc0 \\result, $2, 1 \n"
79 " ori $1, \\result, 0x400 \n"
82 " andi \\result, \\result, 0x400 \n"
83 #elif defined(CONFIG_CPU_MIPSR2)
84 /* see irqflags.h for inline function */
86 " mfc0 \\result, $12 \n"
87 " ori $1, \\result, 0x1f \n"
92 " irq_disable_hazard \n"
96 notrace unsigned long arch_local_irq_save(void)
100 asm volatile("arch_local_irq_save\t%0"
107 EXPORT_SYMBOL(arch_local_irq_save);
111 " .macro arch_local_irq_restore flags \n"
115 #ifdef CONFIG_MIPS_MT_SMTC
117 "andi \\flags, 0x400 \n"
121 "mtc0 \\flags, $2, 1 \n"
122 #elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
123 /* see irqflags.h for inline function */
124 #elif defined(CONFIG_CPU_MIPSR2)
125 /* see irqflags.h for inline function */
128 " andi \\flags, 1 \n"
132 " mtc0 \\flags, $12 \n"
134 " irq_disable_hazard \n"
138 notrace void arch_local_irq_restore(unsigned long flags)
140 unsigned long __tmp1;
142 #ifdef CONFIG_MIPS_MT_SMTC
144 * SMTC kernel needs to do a software replay of queued
145 * IPIs, at the cost of branch and call overhead on each
146 * local_irq_restore()
148 if (unlikely(!(flags & 0x0400)))
152 __asm__ __volatile__(
153 "arch_local_irq_restore\t%0"
159 EXPORT_SYMBOL(arch_local_irq_restore);
162 notrace void __arch_local_irq_restore(unsigned long flags)
164 unsigned long __tmp1;
167 __asm__ __volatile__(
168 "arch_local_irq_restore\t%0"
174 EXPORT_SYMBOL(__arch_local_irq_restore);
176 #endif /* !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC) */