1 /* 2 * Copyright (C) 2012 ARM Ltd. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16 #ifndef __ASM_IRQFLAGS_H 17 #define __ASM_IRQFLAGS_H 18 19 #ifdef __KERNEL__ 20 21 #include <asm/ptrace.h> 22 23 /* 24 * Aarch64 has flags for masking: Debug, Asynchronous (serror), Interrupts and 25 * FIQ exceptions, in the 'daif' register. We mask and unmask them in 'dai' 26 * order: 27 * Masking debug exceptions causes all other exceptions to be masked too/ 28 * Masking SError masks irq, but not debug exceptions. Masking irqs has no 29 * side effects for other flags. Keeping to this order makes it easier for 30 * entry.S to know which exceptions should be unmasked. 31 * 32 * FIQ is never expected, but we mask it when we disable debug exceptions, and 33 * unmask it at all other times. 34 */ 35 36 /* 37 * CPU interrupt mask handling. 38 */ 39 static inline unsigned long arch_local_irq_save(void) 40 { 41 unsigned long flags; 42 asm volatile( 43 "mrs %0, daif // arch_local_irq_save\n" 44 "msr daifset, #2" 45 : "=r" (flags) 46 : 47 : "memory"); 48 return flags; 49 } 50 51 static inline void arch_local_irq_enable(void) 52 { 53 asm volatile( 54 "msr daifclr, #2 // arch_local_irq_enable" 55 : 56 : 57 : "memory"); 58 } 59 60 static inline void arch_local_irq_disable(void) 61 { 62 asm volatile( 63 "msr daifset, #2 // arch_local_irq_disable" 64 : 65 : 66 : "memory"); 67 } 68 69 /* 70 * Save the current interrupt enable state. 71 */ 72 static inline unsigned long arch_local_save_flags(void) 73 { 74 unsigned long flags; 75 asm volatile( 76 "mrs %0, daif // arch_local_save_flags" 77 : "=r" (flags) 78 : 79 : "memory"); 80 return flags; 81 } 82 83 /* 84 * restore saved IRQ state 85 */ 86 static inline void arch_local_irq_restore(unsigned long flags) 87 { 88 asm volatile( 89 "msr daif, %0 // arch_local_irq_restore" 90 : 91 : "r" (flags) 92 : "memory"); 93 } 94 95 static inline int arch_irqs_disabled_flags(unsigned long flags) 96 { 97 return flags & PSR_I_BIT; 98 } 99 #endif 100 #endif 101