xref: /linux/arch/arm64/include/asm/irqflags.h (revision 791d3ef2e11100449837dc0b6fe884e60ca3a484)
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