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
19
20/*
21 * Call these functions to enable the specified interrupts.
22 *
23 * mask - Bit mask of interrupts to be enabled.
24 */
25static inline void z_xt_ints_on(unsigned int mask)
26{
27 int val;
28
29 __asm__ volatile("rsr.intenable %0" : "=r"(val));
30 val |= mask;
31 __asm__ volatile("wsr.intenable %0; rsync" : : "r"(val));
32}
33#if XCHAL_NUM_INTERRUPTS > 32
34static inline void z_xt_ints1_on(unsigned int mask)
35{
36 int val;
37
38 __asm__ volatile("rsr.intenable1 %0" : "=r"(val));
39 val |= mask;
40 __asm__ volatile("wsr.intenable1 %0; rsync" : : "r"(val));
41}
42#endif
43#if XCHAL_NUM_INTERRUPTS > 64
44static inline void z_xt_ints2_on(unsigned int mask)
45{
46 int val;
47
48 __asm__ volatile("rsr.intenable2 %0" : "=r"(val));
49 val |= mask;
50 __asm__ volatile("wsr.intenable2 %0; rsync" : : "r"(val));
51}
52#endif
53#if XCHAL_NUM_INTERRUPTS > 96
54static inline void z_xt_ints3_on(unsigned int mask)
55{
56 int val;
57
58 __asm__ volatile("rsr.intenable3 %0" : "=r"(val));
59 val |= mask;
60 __asm__ volatile("wsr.intenable3 %0; rsync" : : "r"(val));
61}
62#endif
63
64
65/*
66 * Call these functions to disable the specified interrupts.
67 *
68 * mask - Bit mask of interrupts to be disabled.
69 */
70static inline void z_xt_ints_off(unsigned int mask)
71{
72 int val;
73
74 __asm__ volatile("rsr.intenable %0" : "=r"(val));
75 val &= ~mask;
76 __asm__ volatile("wsr.intenable %0; rsync" : : "r"(val));
77}
78#if XCHAL_NUM_INTERRUPTS > 32
79static inline void z_xt_ints1_off(unsigned int mask)
80{
81 int val;
82
83 __asm__ volatile("rsr.intenable1 %0" : "=r"(val));
84 val &= ~mask;
85 __asm__ volatile("wsr.intenable1 %0; rsync" : : "r"(val));
86}
87#endif
88#if XCHAL_NUM_INTERRUPTS > 64
89static inline void z_xt_ints2_off(unsigned int mask)
90{
91 int val;
92
93 __asm__ volatile("rsr.intenable2 %0" : "=r"(val));
94 val &= ~mask;
95 __asm__ volatile("wsr.intenable2 %0; rsync" : : "r"(val));
96}
97#endif
98#if XCHAL_NUM_INTERRUPTS > 96
99static inline void z_xt_ints3_off(unsigned int mask)
100{
101 int val;
102
103 __asm__ volatile("rsr.intenable3 %0" : "=r"(val));
104 val &= ~mask;
105 __asm__ volatile("wsr.intenable3 %0; rsync" : : "r"(val));
106}
107#endif
108
109
110/*
111 * Call these functions to set the specified (s/w) interrupt.
112 */
113static inline void z_xt_set_intset(unsigned int arg)
114{
115#if XCHAL_HAVE_INTERRUPTS
116 __asm__ volatile("wsr.intset %0; rsync" : : "r"(arg));
117#else
118 ARG_UNUSED(arg);
119#endif
120}
121#if XCHAL_NUM_INTERRUPTS > 32
122static inline void z_xt_set_intset1(unsigned int arg)
123{
124 __asm__ volatile("wsr.intset1 %0; rsync" : : "r"(arg));
125}
126#endif
127#if XCHAL_NUM_INTERRUPTS > 64
128static inline void z_xt_set_intset2(unsigned int arg)
129{
130 __asm__ volatile("wsr.intset2 %0; rsync" : : "r"(arg));
131}
132#endif
133#if XCHAL_NUM_INTERRUPTS > 96
134static inline void z_xt_set_intset3(unsigned int arg)
135{
136 __asm__ volatile("wsr.intset3 %0; rsync" : : "r"(arg));
137}
138#endif
139
140
144
145#ifdef CONFIG_MULTI_LEVEL_INTERRUPTS
146
147/* for _soc_irq_*() */
148#include <soc.h>
149
150#ifdef CONFIG_2ND_LEVEL_INTERRUPTS
151#ifdef CONFIG_3RD_LEVEL_INTERRUPTS
152#define CONFIG_NUM_IRQS (XCHAL_NUM_INTERRUPTS +\
153 (CONFIG_NUM_2ND_LEVEL_AGGREGATORS +\
154 CONFIG_NUM_3RD_LEVEL_AGGREGATORS) *\
155 CONFIG_MAX_IRQ_PER_AGGREGATOR)
156#else
157#define CONFIG_NUM_IRQS (XCHAL_NUM_INTERRUPTS +\
158 CONFIG_NUM_2ND_LEVEL_AGGREGATORS *\
159 CONFIG_MAX_IRQ_PER_AGGREGATOR)
160#endif /* CONFIG_3RD_LEVEL_INTERRUPTS */
161#else
162#define CONFIG_NUM_IRQS XCHAL_NUM_INTERRUPTS
163#endif /* CONFIG_2ND_LEVEL_INTERRUPTS */
164
165void z_soc_irq_init(void);
166void z_soc_irq_enable(unsigned int irq);
167void z_soc_irq_disable(unsigned int irq);
168int z_soc_irq_is_enabled(unsigned int irq);
169
170#define arch_irq_enable(irq) z_soc_irq_enable(irq)
171#define arch_irq_disable(irq) z_soc_irq_disable(irq)
172
173#define arch_irq_is_enabled(irq) z_soc_irq_is_enabled(irq)
174
175#else
176
177#define CONFIG_NUM_IRQS XCHAL_NUM_INTERRUPTS
178
179#define arch_irq_enable(irq) xtensa_irq_enable(irq)
180#define arch_irq_disable(irq) xtensa_irq_disable(irq)
181
182#define arch_irq_is_enabled(irq) xtensa_irq_is_enabled(irq)
183
184#endif
185
192{
193#if XCHAL_NUM_INTERRUPTS > 32
194 switch (irq >> 5) {
195 case 0:
196 z_xt_ints_on(1 << (irq & 0x1f));
197 break;
198 case 1:
199 z_xt_ints1_on(1 << (irq & 0x1f));
200 break;
201#if XCHAL_NUM_INTERRUPTS > 64
202 case 2:
203 z_xt_ints2_on(1 << (irq & 0x1f));
204 break;
205#endif
206#if XCHAL_NUM_INTERRUPTS > 96
207 case 3:
208 z_xt_ints3_on(1 << (irq & 0x1f));
209 break;
210#endif
211 default:
212 break;
213 }
214#else
215 z_xt_ints_on(1 << irq);
216#endif
217}
218
225{
226#if XCHAL_NUM_INTERRUPTS > 32
227 switch (irq >> 5) {
228 case 0:
229 z_xt_ints_off(1 << (irq & 0x1f));
230 break;
231 case 1:
232 z_xt_ints1_off(1 << (irq & 0x1f));
233 break;
234#if XCHAL_NUM_INTERRUPTS > 64
235 case 2:
236 z_xt_ints2_off(1 << (irq & 0x1f));
237 break;
238#endif
239#if XCHAL_NUM_INTERRUPTS > 96
240 case 3:
241 z_xt_ints3_off(1 << (irq & 0x1f));
242 break;
243#endif
244 default:
245 break;
246 }
247#else
248 z_xt_ints_off(1 << irq);
249#endif
250}
251
253static ALWAYS_INLINE unsigned int arch_irq_lock(void)
254{
255 unsigned int key;
256
257 __asm__ volatile("rsil %0, %1"
258 : "=r"(key) : "i"(XCHAL_EXCM_LEVEL) : "memory");
259 return key;
260}
261
263static ALWAYS_INLINE void arch_irq_unlock(unsigned int key)
264{
265 __asm__ volatile("wsr.ps %0; rsync"
266 :: "r"(key) : "memory");
267}
268
270static ALWAYS_INLINE bool arch_irq_unlocked(unsigned int key)
271{
272 return (key & 0xf) == 0; /* INTLEVEL field */
273}
274
277{
278 unsigned int ps;
279
280 /*
281 * Force an 'rsync' before reading PS. This ensures that we get the
282 * current value of PS and not a stale value.
283 */
284
285 __asm__ volatile("rsync; rsr.ps %0" : "=r" (ps));
286 return (ps & 0xf) == 0; /* INTLEVEL field */
287}
288
296int xtensa_irq_is_enabled(unsigned int irq);
297
298#include <zephyr/irq.h>
299
300#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:224
static ALWAYS_INLINE void xtensa_irq_enable(uint32_t irq)
Enable interrupt on Xtensa core.
Definition irq.h:191
int xtensa_irq_is_enabled(unsigned int irq)
Query if an interrupt is enabled on Xtensa core.
#define ALWAYS_INLINE
Definition common.h:161
Public interface for configuring interrupts.
__UINT32_TYPE__ uint32_t
Definition stdint.h:90
Macros to abstract toolchain specific capabilities.