1
2
3
4
5#ifndef __ASM_IRQFLAGS_H
6#define __ASM_IRQFLAGS_H
7
8#include <asm/alternative.h>
9#include <asm/barrier.h>
10#include <asm/ptrace.h>
11#include <asm/sysreg.h>
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27static inline void arch_local_irq_enable(void)
28{
29 if (system_has_prio_mask_debugging()) {
30 u32 pmr = read_sysreg_s(SYS_ICC_PMR_EL1);
31
32 WARN_ON_ONCE(pmr != GIC_PRIO_IRQON && pmr != GIC_PRIO_IRQOFF);
33 }
34
35 asm volatile(ALTERNATIVE(
36 "msr daifclr, #3 // arch_local_irq_enable",
37 __msr_s(SYS_ICC_PMR_EL1, "%0"),
38 ARM64_HAS_IRQ_PRIO_MASKING)
39 :
40 : "r" ((unsigned long) GIC_PRIO_IRQON)
41 : "memory");
42
43 pmr_sync();
44}
45
46static inline void arch_local_irq_disable(void)
47{
48 if (system_has_prio_mask_debugging()) {
49 u32 pmr = read_sysreg_s(SYS_ICC_PMR_EL1);
50
51 WARN_ON_ONCE(pmr != GIC_PRIO_IRQON && pmr != GIC_PRIO_IRQOFF);
52 }
53
54 asm volatile(ALTERNATIVE(
55 "msr daifset, #3 // arch_local_irq_disable",
56 __msr_s(SYS_ICC_PMR_EL1, "%0"),
57 ARM64_HAS_IRQ_PRIO_MASKING)
58 :
59 : "r" ((unsigned long) GIC_PRIO_IRQOFF)
60 : "memory");
61}
62
63
64
65
66static inline unsigned long arch_local_save_flags(void)
67{
68 unsigned long flags;
69
70 asm volatile(ALTERNATIVE(
71 "mrs %0, daif",
72 __mrs_s("%0", SYS_ICC_PMR_EL1),
73 ARM64_HAS_IRQ_PRIO_MASKING)
74 : "=&r" (flags)
75 :
76 : "memory");
77
78 return flags;
79}
80
81static inline int arch_irqs_disabled_flags(unsigned long flags)
82{
83 int res;
84
85 asm volatile(ALTERNATIVE(
86 "and %w0, %w1, #" __stringify(PSR_I_BIT),
87 "eor %w0, %w1, #" __stringify(GIC_PRIO_IRQON),
88 ARM64_HAS_IRQ_PRIO_MASKING)
89 : "=&r" (res)
90 : "r" ((int) flags)
91 : "memory");
92
93 return res;
94}
95
96static inline int arch_irqs_disabled(void)
97{
98 return arch_irqs_disabled_flags(arch_local_save_flags());
99}
100
101static inline unsigned long arch_local_irq_save(void)
102{
103 unsigned long flags;
104
105 flags = arch_local_save_flags();
106
107
108
109
110
111 if (!arch_irqs_disabled_flags(flags))
112 arch_local_irq_disable();
113
114 return flags;
115}
116
117
118
119
120static inline void arch_local_irq_restore(unsigned long flags)
121{
122 asm volatile(ALTERNATIVE(
123 "msr daif, %0",
124 __msr_s(SYS_ICC_PMR_EL1, "%0"),
125 ARM64_HAS_IRQ_PRIO_MASKING)
126 :
127 : "r" (flags)
128 : "memory");
129
130 pmr_sync();
131}
132
133#endif
134