Zephyr Project API 4.4.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
irq.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2016 Cadence Design Systems, Inc.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6#ifndef ZEPHYR_INCLUDE_ARCH_XTENSA_IRQ_H_
7#define ZEPHYR_INCLUDE_ARCH_XTENSA_IRQ_H_
8
9#include <stdint.h>
10
11#include <zephyr/toolchain.h>
12#include <xtensa/config/core-isa.h>
13
14#define CONFIG_GEN_IRQ_START_VECTOR 0
15
16#ifdef __cplusplus
17extern "C" {
18#endif
19
23
24/*
25 * Call these functions to enable the specified interrupts.
26 *
27 * mask - Bit mask of interrupts to be enabled.
28 */
29static inline void z_xt_ints_on(unsigned int mask)
30{
31 int val;
32
33 __asm__ volatile("rsr.intenable %0" : "=r"(val));
34 val |= mask;
35 __asm__ volatile("wsr.intenable %0; rsync" : : "r"(val));
36}
37#if XCHAL_NUM_INTERRUPTS > 32
38static inline void z_xt_ints1_on(unsigned int mask)
39{
40 int val;
41
42 __asm__ volatile("rsr.intenable1 %0" : "=r"(val));
43 val |= mask;
44 __asm__ volatile("wsr.intenable1 %0; rsync" : : "r"(val));
45}
46#endif
47#if XCHAL_NUM_INTERRUPTS > 64
48static inline void z_xt_ints2_on(unsigned int mask)
49{
50 int val;
51
52 __asm__ volatile("rsr.intenable2 %0" : "=r"(val));
53 val |= mask;
54 __asm__ volatile("wsr.intenable2 %0; rsync" : : "r"(val));
55}
56#endif
57#if XCHAL_NUM_INTERRUPTS > 96
58static inline void z_xt_ints3_on(unsigned int mask)
59{
60 int val;
61
62 __asm__ volatile("rsr.intenable3 %0" : "=r"(val));
63 val |= mask;
64 __asm__ volatile("wsr.intenable3 %0; rsync" : : "r"(val));
65}
66#endif
67
68
69/*
70 * Call these functions to disable the specified interrupts.
71 *
72 * mask - Bit mask of interrupts to be disabled.
73 */
74static inline void z_xt_ints_off(unsigned int mask)
75{
76 int val;
77
78 __asm__ volatile("rsr.intenable %0" : "=r"(val));
79 val &= ~mask;
80 __asm__ volatile("wsr.intenable %0; rsync" : : "r"(val));
81}
82#if XCHAL_NUM_INTERRUPTS > 32
83static inline void z_xt_ints1_off(unsigned int mask)
84{
85 int val;
86
87 __asm__ volatile("rsr.intenable1 %0" : "=r"(val));
88 val &= ~mask;
89 __asm__ volatile("wsr.intenable1 %0; rsync" : : "r"(val));
90}
91#endif
92#if XCHAL_NUM_INTERRUPTS > 64
93static inline void z_xt_ints2_off(unsigned int mask)
94{
95 int val;
96
97 __asm__ volatile("rsr.intenable2 %0" : "=r"(val));
98 val &= ~mask;
99 __asm__ volatile("wsr.intenable2 %0; rsync" : : "r"(val));
100}
101#endif
102#if XCHAL_NUM_INTERRUPTS > 96
103static inline void z_xt_ints3_off(unsigned int mask)
104{
105 int val;
106
107 __asm__ volatile("rsr.intenable3 %0" : "=r"(val));
108 val &= ~mask;
109 __asm__ volatile("wsr.intenable3 %0; rsync" : : "r"(val));
110}
111#endif
112
113
114/*
115 * Call these functions to set the specified (s/w) interrupt.
116 */
117static inline void z_xt_set_intset(unsigned int arg)
118{
119#if XCHAL_HAVE_INTERRUPTS
120 __asm__ volatile("wsr.intset %0; rsync" : : "r"(arg));
121#else
122 ARG_UNUSED(arg);
123#endif
124}
125#if XCHAL_NUM_INTERRUPTS > 32
126static inline void z_xt_set_intset1(unsigned int arg)
127{
128 __asm__ volatile("wsr.intset1 %0; rsync" : : "r"(arg));
129}
130#endif
131#if XCHAL_NUM_INTERRUPTS > 64
132static inline void z_xt_set_intset2(unsigned int arg)
133{
134 __asm__ volatile("wsr.intset2 %0; rsync" : : "r"(arg));
135}
136#endif
137#if XCHAL_NUM_INTERRUPTS > 96
138static inline void z_xt_set_intset3(unsigned int arg)
139{
140 __asm__ volatile("wsr.intset3 %0; rsync" : : "r"(arg));
141}
142#endif
143
144
148
149#ifdef CONFIG_MULTI_LEVEL_INTERRUPTS
150
151/* for _soc_irq_*() */
152#include <soc.h>
153
154#ifdef CONFIG_2ND_LEVEL_INTERRUPTS
155#ifdef CONFIG_3RD_LEVEL_INTERRUPTS
156#define CONFIG_NUM_IRQS (XCHAL_NUM_INTERRUPTS +\
157 (CONFIG_NUM_2ND_LEVEL_AGGREGATORS +\
158 CONFIG_NUM_3RD_LEVEL_AGGREGATORS) *\
159 CONFIG_MAX_IRQ_PER_AGGREGATOR)
160#else
161#define CONFIG_NUM_IRQS (XCHAL_NUM_INTERRUPTS +\
162 CONFIG_NUM_2ND_LEVEL_AGGREGATORS *\
163 CONFIG_MAX_IRQ_PER_AGGREGATOR)
164#endif /* CONFIG_3RD_LEVEL_INTERRUPTS */
165#else
166#define CONFIG_NUM_IRQS XCHAL_NUM_INTERRUPTS
167#endif /* CONFIG_2ND_LEVEL_INTERRUPTS */
168
169void z_soc_irq_init(void);
170void z_soc_irq_enable(unsigned int irq);
171void z_soc_irq_disable(unsigned int irq);
172int z_soc_irq_is_enabled(unsigned int irq);
173
174#define arch_irq_enable(irq) z_soc_irq_enable(irq)
175#define arch_irq_disable(irq) z_soc_irq_disable(irq)
176
177#define arch_irq_is_enabled(irq) z_soc_irq_is_enabled(irq)
178
179#else
180
181#define CONFIG_NUM_IRQS XCHAL_NUM_INTERRUPTS
182
183#define arch_irq_enable(irq) xtensa_irq_enable(irq)
184#define arch_irq_disable(irq) xtensa_irq_disable(irq)
185
186#define arch_irq_is_enabled(irq) xtensa_irq_is_enabled(irq)
187
188#endif
189
196{
197#if XCHAL_NUM_INTERRUPTS > 32
198 switch (irq >> 5) {
199 case 0:
200 z_xt_ints_on(1 << (irq & 0x1f));
201 break;
202 case 1:
203 z_xt_ints1_on(1 << (irq & 0x1f));
204 break;
205#if XCHAL_NUM_INTERRUPTS > 64
206 case 2:
207 z_xt_ints2_on(1 << (irq & 0x1f));
208 break;
209#endif
210#if XCHAL_NUM_INTERRUPTS > 96
211 case 3:
212 z_xt_ints3_on(1 << (irq & 0x1f));
213 break;
214#endif
215 default:
216 break;
217 }
218#else
219 z_xt_ints_on(1 << irq);
220#endif
221}
222
229{
230#if XCHAL_NUM_INTERRUPTS > 32
231 switch (irq >> 5) {
232 case 0:
233 z_xt_ints_off(1 << (irq & 0x1f));
234 break;
235 case 1:
236 z_xt_ints1_off(1 << (irq & 0x1f));
237 break;
238#if XCHAL_NUM_INTERRUPTS > 64
239 case 2:
240 z_xt_ints2_off(1 << (irq & 0x1f));
241 break;
242#endif
243#if XCHAL_NUM_INTERRUPTS > 96
244 case 3:
245 z_xt_ints3_off(1 << (irq & 0x1f));
246 break;
247#endif
248 default:
249 break;
250 }
251#else
252 z_xt_ints_off(1 << irq);
253#endif
254}
255
257static ALWAYS_INLINE unsigned int arch_irq_lock(void)
258{
259 unsigned int key;
260
261 __asm__ volatile("rsil %0, %1"
262 : "=r"(key) : "i"(XCHAL_EXCM_LEVEL) : "memory");
263 return key;
264}
265
267static ALWAYS_INLINE void arch_irq_unlock(unsigned int key)
268{
269 __asm__ volatile("wsr.ps %0; rsync"
270 :: "r"(key) : "memory");
271}
272
274static ALWAYS_INLINE bool arch_irq_unlocked(unsigned int key)
275{
276 return (key & 0xf) == 0; /* INTLEVEL field */
277}
278
281{
282 unsigned int ps;
283
284 /*
285 * Force an 'rsync' before reading PS. This ensures that we get the
286 * current value of PS and not a stale value.
287 */
288
289 __asm__ volatile("rsync; rsr.ps %0" : "=r" (ps));
290 return (ps & 0xf) == 0; /* INTLEVEL field */
291}
292
300int xtensa_irq_is_enabled(unsigned int irq);
301
302#ifdef __cplusplus
303}
304#endif
305
306#include <zephyr/irq.h>
307
308#endif /* ZEPHYR_INCLUDE_ARCH_XTENSA_IRQ_H_ */
static ALWAYS_INLINE unsigned int arch_irq_lock(void)
Disable all interrupts on the local CPU.
Definition irq.h:168
static ALWAYS_INLINE void arch_irq_unlock(unsigned int key)
Definition irq.h:176
static ALWAYS_INLINE bool arch_cpu_irqs_are_enabled(void)
Implementation of arch_cpu_irqs_are_enabled.
Definition irq.h:191
static ALWAYS_INLINE bool arch_irq_unlocked(unsigned int key)
Definition irq.h:181
static ALWAYS_INLINE void xtensa_irq_disable(uint32_t irq)
Disable interrupt on Xtensa core.
Definition irq.h:228
static ALWAYS_INLINE void xtensa_irq_enable(uint32_t irq)
Enable interrupt on Xtensa core.
Definition irq.h:195
int xtensa_irq_is_enabled(unsigned int irq)
Query if an interrupt is enabled on Xtensa core.
#define ALWAYS_INLINE
Definition common.h:186
Public interface for configuring interrupts.
__UINT32_TYPE__ uint32_t
Definition stdint.h:90
Macros to abstract toolchain specific capabilities.