Commit | Line | Data |
---|---|---|
d2912cb1 | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
5793e273 VG |
2 | /* |
3 | * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com) | |
4 | * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) | |
5793e273 VG |
5 | */ |
6 | ||
7 | #ifndef __ASM_IRQFLAGS_ARCOMPACT_H | |
8 | #define __ASM_IRQFLAGS_ARCOMPACT_H | |
9 | ||
10 | /* vineetg: March 2010 : local_irq_save( ) optimisation | |
11 | * -Remove explicit mov of current status32 into reg, that is not needed | |
12 | * -Use BIC insn instead of INVERTED + AND | |
13 | * -Conditionally disable interrupts (if they are not enabled, don't disable) | |
14 | */ | |
15 | ||
16 | #include <asm/arcregs.h> | |
17 | ||
18 | /* status32 Reg bits related to Interrupt Handling */ | |
19 | #define STATUS_E1_BIT 1 /* Int 1 enable */ | |
20 | #define STATUS_E2_BIT 2 /* Int 2 enable */ | |
21 | #define STATUS_A1_BIT 3 /* Int 1 active */ | |
22 | #define STATUS_A2_BIT 4 /* Int 2 active */ | |
55a2ae77 | 23 | #define STATUS_AE_BIT 5 /* Exception active */ |
5793e273 VG |
24 | |
25 | #define STATUS_E1_MASK (1<<STATUS_E1_BIT) | |
26 | #define STATUS_E2_MASK (1<<STATUS_E2_BIT) | |
27 | #define STATUS_A1_MASK (1<<STATUS_A1_BIT) | |
28 | #define STATUS_A2_MASK (1<<STATUS_A2_BIT) | |
55a2ae77 | 29 | #define STATUS_AE_MASK (1<<STATUS_AE_BIT) |
5793e273 VG |
30 | #define STATUS_IE_MASK (STATUS_E1_MASK | STATUS_E2_MASK) |
31 | ||
32 | /* Other Interrupt Handling related Aux regs */ | |
33 | #define AUX_IRQ_LEV 0x200 /* IRQ Priority: L1 or L2 */ | |
34 | #define AUX_IRQ_HINT 0x201 /* For generating Soft Interrupts */ | |
35 | #define AUX_IRQ_LV12 0x43 /* interrupt level register */ | |
36 | ||
37 | #define AUX_IENABLE 0x40c | |
38 | #define AUX_ITRIGGER 0x40d | |
39 | #define AUX_IPULSE 0x415 | |
40 | ||
1f6ccfff VG |
41 | #define ISA_INIT_STATUS_BITS STATUS_IE_MASK |
42 | ||
5793e273 VG |
43 | #ifndef __ASSEMBLY__ |
44 | ||
45 | /****************************************************************** | |
46 | * IRQ Control Macros | |
47 | * | |
48 | * All of them have "memory" clobber (compiler barrier) which is needed to | |
ebfc2fd8 | 49 | * ensure that LD/ST requiring irq safety (R-M-W when LLSC is not available) |
5793e273 VG |
50 | * are redone after IRQs are re-enabled (and gcc doesn't reuse stale register) |
51 | * | |
52 | * Noted at the time of Abilis Timer List corruption | |
7e5b06b8 KC |
53 | * |
54 | * Orig Bug + Rejected solution: | |
55 | * https://lore.kernel.org/lkml/1364553218-31255-1-git-send-email-vgupta@synopsys.com | |
56 | * | |
57 | * Reasoning: | |
58 | * https://lore.kernel.org/lkml/CA+55aFyFWjpSVQM6M266tKrG_ZXJzZ-nYejpmXYQXbrr42mGPQ@mail.gmail.com | |
5793e273 VG |
59 | * |
60 | ******************************************************************/ | |
61 | ||
62 | /* | |
63 | * Save IRQ state and disable IRQs | |
64 | */ | |
65 | static inline long arch_local_irq_save(void) | |
66 | { | |
67 | unsigned long temp, flags; | |
68 | ||
69 | __asm__ __volatile__( | |
70 | " lr %1, [status32] \n" | |
71 | " bic %0, %1, %2 \n" | |
72 | " and.f 0, %1, %2 \n" | |
73 | " flag.nz %0 \n" | |
74 | : "=r"(temp), "=r"(flags) | |
75 | : "n"((STATUS_E1_MASK | STATUS_E2_MASK)) | |
76 | : "memory", "cc"); | |
77 | ||
78 | return flags; | |
79 | } | |
80 | ||
81 | /* | |
82 | * restore saved IRQ state | |
83 | */ | |
84 | static inline void arch_local_irq_restore(unsigned long flags) | |
85 | { | |
86 | ||
87 | __asm__ __volatile__( | |
88 | " flag %0 \n" | |
89 | : | |
90 | : "r"(flags) | |
91 | : "memory"); | |
92 | } | |
93 | ||
94 | /* | |
95 | * Unconditionally Enable IRQs | |
96 | */ | |
33b59f16 VG |
97 | #ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS |
98 | extern void arch_local_irq_enable(void); | |
99 | #else | |
9dbd3d9b VG |
100 | static inline void arch_local_irq_enable(void) |
101 | { | |
102 | unsigned long temp; | |
103 | ||
104 | __asm__ __volatile__( | |
105 | " lr %0, [status32] \n" | |
106 | " or %0, %0, %1 \n" | |
107 | " flag %0 \n" | |
108 | : "=&r"(temp) | |
109 | : "n"((STATUS_E1_MASK | STATUS_E2_MASK)) | |
110 | : "cc", "memory"); | |
111 | } | |
33b59f16 | 112 | #endif |
5793e273 VG |
113 | |
114 | /* | |
115 | * Unconditionally Disable IRQs | |
116 | */ | |
117 | static inline void arch_local_irq_disable(void) | |
118 | { | |
119 | unsigned long temp; | |
120 | ||
121 | __asm__ __volatile__( | |
122 | " lr %0, [status32] \n" | |
123 | " and %0, %0, %1 \n" | |
124 | " flag %0 \n" | |
125 | : "=&r"(temp) | |
126 | : "n"(~(STATUS_E1_MASK | STATUS_E2_MASK)) | |
127 | : "memory"); | |
128 | } | |
129 | ||
130 | /* | |
131 | * save IRQ state | |
132 | */ | |
133 | static inline long arch_local_save_flags(void) | |
134 | { | |
135 | unsigned long temp; | |
136 | ||
137 | __asm__ __volatile__( | |
138 | " lr %0, [status32] \n" | |
139 | : "=&r"(temp) | |
140 | : | |
141 | : "memory"); | |
142 | ||
143 | return temp; | |
144 | } | |
145 | ||
146 | /* | |
147 | * Query IRQ state | |
148 | */ | |
149 | static inline int arch_irqs_disabled_flags(unsigned long flags) | |
150 | { | |
151 | return !(flags & (STATUS_E1_MASK | |
152 | #ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS | |
153 | | STATUS_E2_MASK | |
154 | #endif | |
155 | )); | |
156 | } | |
157 | ||
158 | static inline int arch_irqs_disabled(void) | |
159 | { | |
160 | return arch_irqs_disabled_flags(arch_local_save_flags()); | |
161 | } | |
162 | ||
163 | #else | |
164 | ||
165 | #ifdef CONFIG_TRACE_IRQFLAGS | |
166 | ||
167 | .macro TRACE_ASM_IRQ_DISABLE | |
168 | bl trace_hardirqs_off | |
169 | .endm | |
170 | ||
171 | .macro TRACE_ASM_IRQ_ENABLE | |
172 | bl trace_hardirqs_on | |
173 | .endm | |
174 | ||
175 | #else | |
176 | ||
177 | .macro TRACE_ASM_IRQ_DISABLE | |
178 | .endm | |
179 | ||
180 | .macro TRACE_ASM_IRQ_ENABLE | |
181 | .endm | |
182 | ||
183 | #endif | |
184 | ||
185 | .macro IRQ_DISABLE scratch | |
186 | lr \scratch, [status32] | |
187 | bic \scratch, \scratch, (STATUS_E1_MASK | STATUS_E2_MASK) | |
188 | flag \scratch | |
189 | TRACE_ASM_IRQ_DISABLE | |
190 | .endm | |
191 | ||
192 | .macro IRQ_ENABLE scratch | |
18b43e89 | 193 | TRACE_ASM_IRQ_ENABLE |
5793e273 VG |
194 | lr \scratch, [status32] |
195 | or \scratch, \scratch, (STATUS_E1_MASK | STATUS_E2_MASK) | |
196 | flag \scratch | |
5793e273 VG |
197 | .endm |
198 | ||
199 | #endif /* __ASSEMBLY__ */ | |
200 | ||
201 | #endif |