| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 |  */ | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 11 | #ifndef _ASM_IRQFLAGS_H | 
 | 12 | #define _ASM_IRQFLAGS_H | 
 | 13 |  | 
 | 14 | #ifndef __ASSEMBLY__ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 15 |  | 
 | 16 | #include <asm/hazards.h> | 
 | 17 |  | 
 | 18 | __asm__ ( | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 19 | 	"	.macro	raw_local_irq_enable				\n" | 
| Ralf Baechle | ff88f8a | 2005-07-12 14:54:31 +0000 | [diff] [blame] | 20 | 	"	.set	push						\n" | 
 | 21 | 	"	.set	reorder						\n" | 
 | 22 | 	"	.set	noat						\n" | 
| Ralf Baechle | 41c594a | 2006-04-05 09:45:45 +0100 | [diff] [blame] | 23 | #ifdef CONFIG_MIPS_MT_SMTC | 
 | 24 | 	"	mfc0	$1, $2, 1	# SMTC - clear TCStatus.IXMT	\n" | 
 | 25 | 	"	ori	$1, 0x400					\n" | 
 | 26 | 	"	xori	$1, 0x400					\n" | 
 | 27 | 	"	mtc0	$1, $2, 1					\n" | 
 | 28 | #elif defined(CONFIG_CPU_MIPSR2) | 
| Ralf Baechle | ff88f8a | 2005-07-12 14:54:31 +0000 | [diff] [blame] | 29 | 	"	ei							\n" | 
 | 30 | #else | 
 | 31 | 	"	mfc0	$1,$12						\n" | 
 | 32 | 	"	ori	$1,0x1f						\n" | 
 | 33 | 	"	xori	$1,0x1e						\n" | 
 | 34 | 	"	mtc0	$1,$12						\n" | 
 | 35 | #endif | 
 | 36 | 	"	irq_enable_hazard					\n" | 
 | 37 | 	"	.set	pop						\n" | 
 | 38 | 	"	.endm"); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 39 |  | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 40 | static inline void raw_local_irq_enable(void) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 41 | { | 
 | 42 | 	__asm__ __volatile__( | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 43 | 		"raw_local_irq_enable" | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 44 | 		: /* no outputs */ | 
 | 45 | 		: /* no inputs */ | 
 | 46 | 		: "memory"); | 
 | 47 | } | 
 | 48 |  | 
 | 49 | /* | 
 | 50 |  * For cli() we have to insert nops to make sure that the new value | 
 | 51 |  * has actually arrived in the status register before the end of this | 
 | 52 |  * macro. | 
 | 53 |  * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs | 
 | 54 |  * no nops at all. | 
 | 55 |  */ | 
| Atsushi Nemoto | c226f26 | 2006-02-03 01:34:01 +0900 | [diff] [blame] | 56 | /* | 
 | 57 |  * For TX49, operating only IE bit is not enough. | 
 | 58 |  * | 
 | 59 |  * If mfc0 $12 follows store and the mfc0 is last instruction of a | 
 | 60 |  * page and fetching the next instruction causes TLB miss, the result | 
 | 61 |  * of the mfc0 might wrongly contain EXL bit. | 
 | 62 |  * | 
 | 63 |  * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008 | 
 | 64 |  * | 
 | 65 |  * Workaround: mask EXL bit of the result or place a nop before mfc0. | 
 | 66 |  */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 67 | __asm__ ( | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 68 | 	"	.macro	raw_local_irq_disable\n" | 
| Ralf Baechle | ff88f8a | 2005-07-12 14:54:31 +0000 | [diff] [blame] | 69 | 	"	.set	push						\n" | 
 | 70 | 	"	.set	noat						\n" | 
| Ralf Baechle | 41c594a | 2006-04-05 09:45:45 +0100 | [diff] [blame] | 71 | #ifdef CONFIG_MIPS_MT_SMTC | 
 | 72 | 	"	mfc0	$1, $2, 1					\n" | 
 | 73 | 	"	ori	$1, 0x400					\n" | 
 | 74 | 	"	.set	noreorder					\n" | 
 | 75 | 	"	mtc0	$1, $2, 1					\n" | 
 | 76 | #elif defined(CONFIG_CPU_MIPSR2) | 
| Ralf Baechle | ff88f8a | 2005-07-12 14:54:31 +0000 | [diff] [blame] | 77 | 	"	di							\n" | 
 | 78 | #else | 
 | 79 | 	"	mfc0	$1,$12						\n" | 
| Atsushi Nemoto | c226f26 | 2006-02-03 01:34:01 +0900 | [diff] [blame] | 80 | 	"	ori	$1,0x1f						\n" | 
 | 81 | 	"	xori	$1,0x1f						\n" | 
| Ralf Baechle | ff88f8a | 2005-07-12 14:54:31 +0000 | [diff] [blame] | 82 | 	"	.set	noreorder					\n" | 
 | 83 | 	"	mtc0	$1,$12						\n" | 
 | 84 | #endif | 
 | 85 | 	"	irq_disable_hazard					\n" | 
 | 86 | 	"	.set	pop						\n" | 
 | 87 | 	"	.endm							\n"); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 88 |  | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 89 | static inline void raw_local_irq_disable(void) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 90 | { | 
 | 91 | 	__asm__ __volatile__( | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 92 | 		"raw_local_irq_disable" | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 93 | 		: /* no outputs */ | 
 | 94 | 		: /* no inputs */ | 
 | 95 | 		: "memory"); | 
 | 96 | } | 
 | 97 |  | 
 | 98 | __asm__ ( | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 99 | 	"	.macro	raw_local_save_flags flags			\n" | 
| Ralf Baechle | ff88f8a | 2005-07-12 14:54:31 +0000 | [diff] [blame] | 100 | 	"	.set	push						\n" | 
 | 101 | 	"	.set	reorder						\n" | 
| Ralf Baechle | 41c594a | 2006-04-05 09:45:45 +0100 | [diff] [blame] | 102 | #ifdef CONFIG_MIPS_MT_SMTC | 
 | 103 | 	"	mfc0	\\flags, $2, 1					\n" | 
 | 104 | #else | 
| Ralf Baechle | ff88f8a | 2005-07-12 14:54:31 +0000 | [diff] [blame] | 105 | 	"	mfc0	\\flags, $12					\n" | 
| Ralf Baechle | 41c594a | 2006-04-05 09:45:45 +0100 | [diff] [blame] | 106 | #endif | 
| Ralf Baechle | ff88f8a | 2005-07-12 14:54:31 +0000 | [diff] [blame] | 107 | 	"	.set	pop						\n" | 
 | 108 | 	"	.endm							\n"); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 109 |  | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 110 | #define raw_local_save_flags(x)						\ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 111 | __asm__ __volatile__(							\ | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 112 | 	"raw_local_save_flags %0"					\ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 113 | 	: "=r" (x)) | 
 | 114 |  | 
 | 115 | __asm__ ( | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 116 | 	"	.macro	raw_local_irq_save result			\n" | 
| Ralf Baechle | ff88f8a | 2005-07-12 14:54:31 +0000 | [diff] [blame] | 117 | 	"	.set	push						\n" | 
 | 118 | 	"	.set	reorder						\n" | 
 | 119 | 	"	.set	noat						\n" | 
| Ralf Baechle | 41c594a | 2006-04-05 09:45:45 +0100 | [diff] [blame] | 120 | #ifdef CONFIG_MIPS_MT_SMTC | 
 | 121 | 	"	mfc0	\\result, $2, 1					\n" | 
 | 122 | 	"	ori	$1, \\result, 0x400				\n" | 
 | 123 | 	"	.set	noreorder					\n" | 
 | 124 | 	"	mtc0	$1, $2, 1					\n" | 
 | 125 | 	"	andi	\\result, \\result, 0x400			\n" | 
 | 126 | #elif defined(CONFIG_CPU_MIPSR2) | 
| Ralf Baechle | ff88f8a | 2005-07-12 14:54:31 +0000 | [diff] [blame] | 127 | 	"	di	\\result					\n" | 
| Maxime Bizon | 1526525 | 2005-12-20 06:32:19 +0100 | [diff] [blame] | 128 | 	"	andi	\\result, 1					\n" | 
| Ralf Baechle | ff88f8a | 2005-07-12 14:54:31 +0000 | [diff] [blame] | 129 | #else | 
 | 130 | 	"	mfc0	\\result, $12					\n" | 
| Atsushi Nemoto | c226f26 | 2006-02-03 01:34:01 +0900 | [diff] [blame] | 131 | 	"	ori	$1, \\result, 0x1f				\n" | 
 | 132 | 	"	xori	$1, 0x1f					\n" | 
| Ralf Baechle | ff88f8a | 2005-07-12 14:54:31 +0000 | [diff] [blame] | 133 | 	"	.set	noreorder					\n" | 
 | 134 | 	"	mtc0	$1, $12						\n" | 
 | 135 | #endif | 
 | 136 | 	"	irq_disable_hazard					\n" | 
 | 137 | 	"	.set	pop						\n" | 
 | 138 | 	"	.endm							\n"); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 139 |  | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 140 | #define raw_local_irq_save(x)						\ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 141 | __asm__ __volatile__(							\ | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 142 | 	"raw_local_irq_save\t%0"					\ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 143 | 	: "=r" (x)							\ | 
 | 144 | 	: /* no inputs */						\ | 
 | 145 | 	: "memory") | 
 | 146 |  | 
 | 147 | __asm__ ( | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 148 | 	"	.macro	raw_local_irq_restore flags			\n" | 
| Ralf Baechle | 2e66fe2 | 2006-01-30 16:48:26 +0000 | [diff] [blame] | 149 | 	"	.set	push						\n" | 
| Ralf Baechle | ff88f8a | 2005-07-12 14:54:31 +0000 | [diff] [blame] | 150 | 	"	.set	noreorder					\n" | 
 | 151 | 	"	.set	noat						\n" | 
| Ralf Baechle | 41c594a | 2006-04-05 09:45:45 +0100 | [diff] [blame] | 152 | #ifdef CONFIG_MIPS_MT_SMTC | 
 | 153 | 	"mfc0	$1, $2, 1						\n" | 
 | 154 | 	"andi	\\flags, 0x400						\n" | 
 | 155 | 	"ori	$1, 0x400						\n" | 
 | 156 | 	"xori	$1, 0x400						\n" | 
 | 157 | 	"or	\\flags, $1						\n" | 
 | 158 | 	"mtc0	\\flags, $2, 1						\n" | 
 | 159 | #elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) | 
| Ralf Baechle | ff88f8a | 2005-07-12 14:54:31 +0000 | [diff] [blame] | 160 | 	/* | 
 | 161 | 	 * Slow, but doesn't suffer from a relativly unlikely race | 
 | 162 | 	 * condition we're having since days 1. | 
 | 163 | 	 */ | 
 | 164 | 	"	beqz	\\flags, 1f					\n" | 
 | 165 | 	"	 di							\n" | 
 | 166 | 	"	ei							\n" | 
 | 167 | 	"1:								\n" | 
| Ralf Baechle | ec917c2 | 2005-10-07 16:58:15 +0100 | [diff] [blame] | 168 | #elif defined(CONFIG_CPU_MIPSR2) | 
| Ralf Baechle | ff88f8a | 2005-07-12 14:54:31 +0000 | [diff] [blame] | 169 | 	/* | 
 | 170 | 	 * Fast, dangerous.  Life is fun, life is good. | 
 | 171 | 	 */ | 
 | 172 | 	"	mfc0	$1, $12						\n" | 
 | 173 | 	"	ins	$1, \\flags, 0, 1				\n" | 
 | 174 | 	"	mtc0	$1, $12						\n" | 
 | 175 | #else | 
 | 176 | 	"	mfc0	$1, $12						\n" | 
 | 177 | 	"	andi	\\flags, 1					\n" | 
| Atsushi Nemoto | c226f26 | 2006-02-03 01:34:01 +0900 | [diff] [blame] | 178 | 	"	ori	$1, 0x1f					\n" | 
 | 179 | 	"	xori	$1, 0x1f					\n" | 
| Ralf Baechle | ff88f8a | 2005-07-12 14:54:31 +0000 | [diff] [blame] | 180 | 	"	or	\\flags, $1					\n" | 
 | 181 | 	"	mtc0	\\flags, $12					\n" | 
 | 182 | #endif | 
 | 183 | 	"	irq_disable_hazard					\n" | 
| Ralf Baechle | 2e66fe2 | 2006-01-30 16:48:26 +0000 | [diff] [blame] | 184 | 	"	.set	pop						\n" | 
| Ralf Baechle | ff88f8a | 2005-07-12 14:54:31 +0000 | [diff] [blame] | 185 | 	"	.endm							\n"); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 186 |  | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 187 | #define raw_local_irq_restore(flags)					\ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 188 | do {									\ | 
 | 189 | 	unsigned long __tmp1;						\ | 
 | 190 | 									\ | 
 | 191 | 	__asm__ __volatile__(						\ | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 192 | 		"raw_local_irq_restore\t%0"				\ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 193 | 		: "=r" (__tmp1)						\ | 
 | 194 | 		: "0" (flags)						\ | 
 | 195 | 		: "memory");						\ | 
 | 196 | } while(0) | 
 | 197 |  | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 198 | static inline int raw_irqs_disabled_flags(unsigned long flags) | 
| Ralf Baechle | 41c594a | 2006-04-05 09:45:45 +0100 | [diff] [blame] | 199 | { | 
 | 200 | #ifdef CONFIG_MIPS_MT_SMTC | 
 | 201 | 	/* | 
 | 202 | 	 * SMTC model uses TCStatus.IXMT to disable interrupts for a thread/CPU | 
 | 203 | 	 */ | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 204 | 	return flags & 0x400; | 
| Ralf Baechle | 41c594a | 2006-04-05 09:45:45 +0100 | [diff] [blame] | 205 | #else | 
| Ralf Baechle | 41c594a | 2006-04-05 09:45:45 +0100 | [diff] [blame] | 206 | 	return !(flags & 1); | 
 | 207 | #endif | 
 | 208 | } | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 209 |  | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 210 | #endif | 
 | 211 |  | 
 | 212 | /* | 
 | 213 |  * Do the CPU's IRQ-state tracing from assembly code. | 
 | 214 |  */ | 
 | 215 | #ifdef CONFIG_TRACE_IRQFLAGS | 
| Atsushi Nemoto | eae6c0d | 2006-09-26 23:43:40 +0900 | [diff] [blame] | 216 | /* Reload some registers clobbered by trace_hardirqs_on */ | 
 | 217 | #ifdef CONFIG_64BIT | 
 | 218 | # define TRACE_IRQS_RELOAD_REGS						\ | 
 | 219 | 	LONG_L	$11, PT_R11(sp);					\ | 
 | 220 | 	LONG_L	$10, PT_R10(sp);					\ | 
 | 221 | 	LONG_L	$9, PT_R9(sp);						\ | 
 | 222 | 	LONG_L	$8, PT_R8(sp);						\ | 
 | 223 | 	LONG_L	$7, PT_R7(sp);						\ | 
 | 224 | 	LONG_L	$6, PT_R6(sp);						\ | 
 | 225 | 	LONG_L	$5, PT_R5(sp);						\ | 
 | 226 | 	LONG_L	$4, PT_R4(sp);						\ | 
 | 227 | 	LONG_L	$2, PT_R2(sp) | 
 | 228 | #else | 
 | 229 | # define TRACE_IRQS_RELOAD_REGS						\ | 
 | 230 | 	LONG_L	$7, PT_R7(sp);						\ | 
 | 231 | 	LONG_L	$6, PT_R6(sp);						\ | 
 | 232 | 	LONG_L	$5, PT_R5(sp);						\ | 
 | 233 | 	LONG_L	$4, PT_R4(sp);						\ | 
 | 234 | 	LONG_L	$2, PT_R2(sp) | 
 | 235 | #endif | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 236 | # define TRACE_IRQS_ON							\ | 
| Atsushi Nemoto | eae6c0d | 2006-09-26 23:43:40 +0900 | [diff] [blame] | 237 | 	CLI;	/* make sure trace_hardirqs_on() is called in kernel level */ \ | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 238 | 	jal	trace_hardirqs_on | 
| Atsushi Nemoto | eae6c0d | 2006-09-26 23:43:40 +0900 | [diff] [blame] | 239 | # define TRACE_IRQS_ON_RELOAD						\ | 
 | 240 | 	TRACE_IRQS_ON;							\ | 
 | 241 | 	TRACE_IRQS_RELOAD_REGS | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 242 | # define TRACE_IRQS_OFF							\ | 
 | 243 | 	jal	trace_hardirqs_off | 
 | 244 | #else | 
 | 245 | # define TRACE_IRQS_ON | 
| Atsushi Nemoto | eae6c0d | 2006-09-26 23:43:40 +0900 | [diff] [blame] | 246 | # define TRACE_IRQS_ON_RELOAD | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 247 | # define TRACE_IRQS_OFF | 
 | 248 | #endif | 
 | 249 |  | 
 | 250 | #endif /* _ASM_IRQFLAGS_H */ |