blob: 24692edf1a691a95d623208dc9b8641b404c2248 [file] [log] [blame]
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001/*
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