irqflags.h (4206B)
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 <linux/stringify.h> 18#include <asm/compiler.h> 19#include <asm/hazards.h> 20 21#if defined(CONFIG_CPU_HAS_DIEI) 22 23static inline void arch_local_irq_disable(void) 24{ 25 __asm__ __volatile__( 26 " .set push \n" 27 " .set noat \n" 28 " di \n" 29 " " __stringify(__irq_disable_hazard) " \n" 30 " .set pop \n" 31 : /* no outputs */ 32 : /* no inputs */ 33 : "memory"); 34} 35 36static inline unsigned long arch_local_irq_save(void) 37{ 38 unsigned long flags; 39 40 asm __volatile__( 41 " .set push \n" 42 " .set reorder \n" 43 " .set noat \n" 44#if defined(CONFIG_CPU_LOONGSON64) || defined(CONFIG_CPU_LOONGSON32) 45 " mfc0 %[flags], $12 \n" 46 " di \n" 47#else 48 " di %[flags] \n" 49#endif 50 " andi %[flags], 1 \n" 51 " " __stringify(__irq_disable_hazard) " \n" 52 " .set pop \n" 53 : [flags] "=r" (flags) 54 : /* no inputs */ 55 : "memory"); 56 57 return flags; 58} 59 60static inline void arch_local_irq_restore(unsigned long flags) 61{ 62 unsigned long __tmp1; 63 64 __asm__ __volatile__( 65 " .set push \n" 66 " .set noreorder \n" 67 " .set noat \n" 68#if defined(CONFIG_IRQ_MIPS_CPU) 69 /* 70 * Slow, but doesn't suffer from a relatively unlikely race 71 * condition we're having since days 1. 72 */ 73 " beqz %[flags], 1f \n" 74 " di \n" 75 " ei \n" 76 "1: \n" 77#else 78 /* 79 * Fast, dangerous. Life is fun, life is good. 80 */ 81 " mfc0 $1, $12 \n" 82 " ins $1, %[flags], 0, 1 \n" 83 " mtc0 $1, $12 \n" 84#endif 85 " " __stringify(__irq_disable_hazard) " \n" 86 " .set pop \n" 87 : [flags] "=r" (__tmp1) 88 : "0" (flags) 89 : "memory"); 90} 91 92#else 93/* Functions that require preempt_{dis,en}able() are in mips-atomic.c */ 94void arch_local_irq_disable(void); 95unsigned long arch_local_irq_save(void); 96void arch_local_irq_restore(unsigned long flags); 97#endif /* CONFIG_CPU_HAS_DIEI */ 98 99static inline void arch_local_irq_enable(void) 100{ 101 __asm__ __volatile__( 102 " .set push \n" 103 " .set reorder \n" 104 " .set noat \n" 105#if defined(CONFIG_CPU_HAS_DIEI) 106 " ei \n" 107#else 108 " mfc0 $1,$12 \n" 109 " ori $1,0x1f \n" 110 " xori $1,0x1e \n" 111 " mtc0 $1,$12 \n" 112#endif 113 " " __stringify(__irq_enable_hazard) " \n" 114 " .set pop \n" 115 : /* no outputs */ 116 : /* no inputs */ 117 : "memory"); 118} 119 120static inline unsigned long arch_local_save_flags(void) 121{ 122 unsigned long flags; 123 124 asm __volatile__( 125 " .set push \n" 126 " .set reorder \n" 127 " mfc0 %[flags], $12 \n" 128 " .set pop \n" 129 : [flags] "=r" (flags)); 130 131 return flags; 132} 133 134 135static inline int arch_irqs_disabled_flags(unsigned long flags) 136{ 137 return !(flags & 1); 138} 139 140static inline int arch_irqs_disabled(void) 141{ 142 return arch_irqs_disabled_flags(arch_local_save_flags()); 143} 144 145#endif /* #ifndef __ASSEMBLY__ */ 146 147/* 148 * Do the CPU's IRQ-state tracing from assembly code. 149 */ 150#ifdef CONFIG_TRACE_IRQFLAGS 151/* Reload some registers clobbered by trace_hardirqs_on */ 152#ifdef CONFIG_64BIT 153# define TRACE_IRQS_RELOAD_REGS \ 154 LONG_L $11, PT_R11(sp); \ 155 LONG_L $10, PT_R10(sp); \ 156 LONG_L $9, PT_R9(sp); \ 157 LONG_L $8, PT_R8(sp); \ 158 LONG_L $7, PT_R7(sp); \ 159 LONG_L $6, PT_R6(sp); \ 160 LONG_L $5, PT_R5(sp); \ 161 LONG_L $4, PT_R4(sp); \ 162 LONG_L $2, PT_R2(sp) 163#else 164# define TRACE_IRQS_RELOAD_REGS \ 165 LONG_L $7, PT_R7(sp); \ 166 LONG_L $6, PT_R6(sp); \ 167 LONG_L $5, PT_R5(sp); \ 168 LONG_L $4, PT_R4(sp); \ 169 LONG_L $2, PT_R2(sp) 170#endif 171# define TRACE_IRQS_ON \ 172 CLI; /* make sure trace_hardirqs_on() is called in kernel level */ \ 173 jal trace_hardirqs_on 174# define TRACE_IRQS_ON_RELOAD \ 175 TRACE_IRQS_ON; \ 176 TRACE_IRQS_RELOAD_REGS 177# define TRACE_IRQS_OFF \ 178 jal trace_hardirqs_off 179#else 180# define TRACE_IRQS_ON 181# define TRACE_IRQS_ON_RELOAD 182# define TRACE_IRQS_OFF 183#endif 184 185#endif /* _ASM_IRQFLAGS_H */