Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.20-rc5 250 lines 6.0 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 <asm/hazards.h> 17 18__asm__ ( 19 " .macro raw_local_irq_enable \n" 20 " .set push \n" 21 " .set reorder \n" 22 " .set noat \n" 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) 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"); 39 40static inline void raw_local_irq_enable(void) 41{ 42 __asm__ __volatile__( 43 "raw_local_irq_enable" 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 */ 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 */ 67__asm__ ( 68 " .macro raw_local_irq_disable\n" 69 " .set push \n" 70 " .set noat \n" 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) 77 " di \n" 78#else 79 " mfc0 $1,$12 \n" 80 " ori $1,0x1f \n" 81 " xori $1,0x1f \n" 82 " .set noreorder \n" 83 " mtc0 $1,$12 \n" 84#endif 85 " irq_disable_hazard \n" 86 " .set pop \n" 87 " .endm \n"); 88 89static inline void raw_local_irq_disable(void) 90{ 91 __asm__ __volatile__( 92 "raw_local_irq_disable" 93 : /* no outputs */ 94 : /* no inputs */ 95 : "memory"); 96} 97 98__asm__ ( 99 " .macro raw_local_save_flags flags \n" 100 " .set push \n" 101 " .set reorder \n" 102#ifdef CONFIG_MIPS_MT_SMTC 103 " mfc0 \\flags, $2, 1 \n" 104#else 105 " mfc0 \\flags, $12 \n" 106#endif 107 " .set pop \n" 108 " .endm \n"); 109 110#define raw_local_save_flags(x) \ 111__asm__ __volatile__( \ 112 "raw_local_save_flags %0" \ 113 : "=r" (x)) 114 115__asm__ ( 116 " .macro raw_local_irq_save result \n" 117 " .set push \n" 118 " .set reorder \n" 119 " .set noat \n" 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) 127 " di \\result \n" 128 " andi \\result, 1 \n" 129#else 130 " mfc0 \\result, $12 \n" 131 " ori $1, \\result, 0x1f \n" 132 " xori $1, 0x1f \n" 133 " .set noreorder \n" 134 " mtc0 $1, $12 \n" 135#endif 136 " irq_disable_hazard \n" 137 " .set pop \n" 138 " .endm \n"); 139 140#define raw_local_irq_save(x) \ 141__asm__ __volatile__( \ 142 "raw_local_irq_save\t%0" \ 143 : "=r" (x) \ 144 : /* no inputs */ \ 145 : "memory") 146 147__asm__ ( 148 " .macro raw_local_irq_restore flags \n" 149 " .set push \n" 150 " .set noreorder \n" 151 " .set noat \n" 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) 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" 168#elif defined(CONFIG_CPU_MIPSR2) 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" 178 " ori $1, 0x1f \n" 179 " xori $1, 0x1f \n" 180 " or \\flags, $1 \n" 181 " mtc0 \\flags, $12 \n" 182#endif 183 " irq_disable_hazard \n" 184 " .set pop \n" 185 " .endm \n"); 186 187#define raw_local_irq_restore(flags) \ 188do { \ 189 unsigned long __tmp1; \ 190 \ 191 __asm__ __volatile__( \ 192 "raw_local_irq_restore\t%0" \ 193 : "=r" (__tmp1) \ 194 : "0" (flags) \ 195 : "memory"); \ 196} while(0) 197 198static inline int raw_irqs_disabled_flags(unsigned long flags) 199{ 200#ifdef CONFIG_MIPS_MT_SMTC 201 /* 202 * SMTC model uses TCStatus.IXMT to disable interrupts for a thread/CPU 203 */ 204 return flags & 0x400; 205#else 206 return !(flags & 1); 207#endif 208} 209 210#endif 211 212/* 213 * Do the CPU's IRQ-state tracing from assembly code. 214 */ 215#ifdef CONFIG_TRACE_IRQFLAGS 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 236# define TRACE_IRQS_ON \ 237 CLI; /* make sure trace_hardirqs_on() is called in kernel level */ \ 238 jal trace_hardirqs_on 239# define TRACE_IRQS_ON_RELOAD \ 240 TRACE_IRQS_ON; \ 241 TRACE_IRQS_RELOAD_REGS 242# define TRACE_IRQS_OFF \ 243 jal trace_hardirqs_off 244#else 245# define TRACE_IRQS_ON 246# define TRACE_IRQS_ON_RELOAD 247# define TRACE_IRQS_OFF 248#endif 249 250#endif /* _ASM_IRQFLAGS_H */