Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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