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 */ 39static 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 51static 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 60static 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 */ 72static 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 */ 86static 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 95static inline int arch_irqs_disabled_flags(unsigned long flags) 96{ 97 return flags & PSR_I_BIT; 98} 99#endif 100#endif 101