1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * Copyright (C) 2012 ARM Ltd.
5 #ifndef __ASM_IRQFLAGS_H
6 #define __ASM_IRQFLAGS_H
10 #include <asm/alternative.h>
11 #include <asm/ptrace.h>
12 #include <asm/sysreg.h>
15 * Aarch64 has flags for masking: Debug, Asynchronous (serror), Interrupts and
16 * FIQ exceptions, in the 'daif' register. We mask and unmask them in 'dai'
18 * Masking debug exceptions causes all other exceptions to be masked too/
19 * Masking SError masks irq, but not debug exceptions. Masking irqs has no
20 * side effects for other flags. Keeping to this order makes it easier for
21 * entry.S to know which exceptions should be unmasked.
23 * FIQ is never expected, but we mask it when we disable debug exceptions, and
24 * unmask it at all other times.
28 * CPU interrupt mask handling.
30 static inline void arch_local_irq_enable(void)
32 asm volatile(ALTERNATIVE(
33 "msr daifclr, #2 // arch_local_irq_enable\n"
35 __msr_s(SYS_ICC_PMR_EL1, "%0")
37 ARM64_HAS_IRQ_PRIO_MASKING)
39 : "r" ((unsigned long) GIC_PRIO_IRQON)
43 static inline void arch_local_irq_disable(void)
45 asm volatile(ALTERNATIVE(
46 "msr daifset, #2 // arch_local_irq_disable",
47 __msr_s(SYS_ICC_PMR_EL1, "%0"),
48 ARM64_HAS_IRQ_PRIO_MASKING)
50 : "r" ((unsigned long) GIC_PRIO_IRQOFF)
55 * Save the current interrupt enable state.
57 static inline unsigned long arch_local_save_flags(void)
59 unsigned long daif_bits;
62 daif_bits = read_sysreg(daif);
65 * The asm is logically equivalent to:
67 * if (system_uses_irq_prio_masking())
68 * flags = (daif_bits & PSR_I_BIT) ?
70 * read_sysreg_s(SYS_ICC_PMR_EL1);
74 asm volatile(ALTERNATIVE(
78 __mrs_s("%0", SYS_ICC_PMR_EL1)
79 "ands %1, %1, " __stringify(PSR_I_BIT) "\n"
80 "csel %0, %0, %2, eq",
81 ARM64_HAS_IRQ_PRIO_MASKING)
82 : "=&r" (flags), "+r" (daif_bits)
83 : "r" ((unsigned long) GIC_PRIO_IRQOFF)
89 static inline unsigned long arch_local_irq_save(void)
93 flags = arch_local_save_flags();
95 arch_local_irq_disable();
101 * restore saved IRQ state
103 static inline void arch_local_irq_restore(unsigned long flags)
105 asm volatile(ALTERNATIVE(
108 __msr_s(SYS_ICC_PMR_EL1, "%0")
110 ARM64_HAS_IRQ_PRIO_MASKING)
116 static inline int arch_irqs_disabled_flags(unsigned long flags)
120 asm volatile(ALTERNATIVE(
121 "and %w0, %w1, #" __stringify(PSR_I_BIT) "\n"
123 "cmp %w1, #" __stringify(GIC_PRIO_IRQOFF) "\n"
125 ARM64_HAS_IRQ_PRIO_MASKING)