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_INTERRUPT_H 12#define _ASM_INTERRUPT_H 13 14#include <linux/config.h> 15#include <asm/hazards.h> 16 17__asm__ ( 18 " .macro local_irq_enable \n" 19 " .set push \n" 20 " .set reorder \n" 21 " .set noat \n" 22#ifdef CONFIG_CPU_MIPSR2 23 " ei \n" 24#else 25 " mfc0 $1,$12 \n" 26 " ori $1,0x1f \n" 27 " xori $1,0x1e \n" 28 " mtc0 $1,$12 \n" 29#endif 30 " irq_enable_hazard \n" 31 " .set pop \n" 32 " .endm"); 33 34static inline void local_irq_enable(void) 35{ 36 __asm__ __volatile__( 37 "local_irq_enable" 38 : /* no outputs */ 39 : /* no inputs */ 40 : "memory"); 41} 42 43/* 44 * For cli() we have to insert nops to make sure that the new value 45 * has actually arrived in the status register before the end of this 46 * macro. 47 * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs 48 * no nops at all. 49 */ 50__asm__ ( 51 " .macro local_irq_disable\n" 52 " .set push \n" 53 " .set noat \n" 54#ifdef CONFIG_CPU_MIPSR2 55 " di \n" 56#else 57 " mfc0 $1,$12 \n" 58 " ori $1,1 \n" 59 " xori $1,1 \n" 60 " .set noreorder \n" 61 " mtc0 $1,$12 \n" 62#endif 63 " irq_disable_hazard \n" 64 " .set pop \n" 65 " .endm \n"); 66 67static inline void local_irq_disable(void) 68{ 69 __asm__ __volatile__( 70 "local_irq_disable" 71 : /* no outputs */ 72 : /* no inputs */ 73 : "memory"); 74} 75 76__asm__ ( 77 " .macro local_save_flags flags \n" 78 " .set push \n" 79 " .set reorder \n" 80 " mfc0 \\flags, $12 \n" 81 " .set pop \n" 82 " .endm \n"); 83 84#define local_save_flags(x) \ 85__asm__ __volatile__( \ 86 "local_save_flags %0" \ 87 : "=r" (x)) 88 89__asm__ ( 90 " .macro local_irq_save result \n" 91 " .set push \n" 92 " .set reorder \n" 93 " .set noat \n" 94#ifdef CONFIG_CPU_MIPSR2 95 " di \\result \n" 96#else 97 " mfc0 \\result, $12 \n" 98 " ori $1, \\result, 1 \n" 99 " xori $1, 1 \n" 100 " .set noreorder \n" 101 " mtc0 $1, $12 \n" 102#endif 103 " irq_disable_hazard \n" 104 " .set pop \n" 105 " .endm \n"); 106 107#define local_irq_save(x) \ 108__asm__ __volatile__( \ 109 "local_irq_save\t%0" \ 110 : "=r" (x) \ 111 : /* no inputs */ \ 112 : "memory") 113 114__asm__ ( 115 " .macro local_irq_restore flags \n" 116 " .set noreorder \n" 117 " .set noat \n" 118#if defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) 119 /* 120 * Slow, but doesn't suffer from a relativly unlikely race 121 * condition we're having since days 1. 122 */ 123 " beqz \\flags, 1f \n" 124 " di \n" 125 " ei \n" 126 "1: \n" 127#elif defined(CONFIG_CPU_MIPSR2) 128 /* 129 * Fast, dangerous. Life is fun, life is good. 130 */ 131 " mfc0 $1, $12 \n" 132 " ins $1, \\flags, 0, 1 \n" 133 " mtc0 $1, $12 \n" 134#else 135 " mfc0 $1, $12 \n" 136 " andi \\flags, 1 \n" 137 " ori $1, 1 \n" 138 " xori $1, 1 \n" 139 " or \\flags, $1 \n" 140 " mtc0 \\flags, $12 \n" 141#endif 142 " irq_disable_hazard \n" 143 " .set at \n" 144 " .set reorder \n" 145 " .endm \n"); 146 147#define local_irq_restore(flags) \ 148do { \ 149 unsigned long __tmp1; \ 150 \ 151 __asm__ __volatile__( \ 152 "local_irq_restore\t%0" \ 153 : "=r" (__tmp1) \ 154 : "0" (flags) \ 155 : "memory"); \ 156} while(0) 157 158#define irqs_disabled() \ 159({ \ 160 unsigned long flags; \ 161 local_save_flags(flags); \ 162 !(flags & 1); \ 163}) 164 165#endif /* _ASM_INTERRUPT_H */