Zephyr API Documentation  2.7.0-rc2
A Scalable Open Source RTOS
arcv2_irq_unit.h
Go to the documentation of this file.
1/* arcv2_irq_unit.h - ARCv2 Interrupt Unit device driver */
2
3/*
4 * Copyright (c) 2014 Wind River Systems, Inc.
5 * Copyright (c) 2020 Synopsys.
6 *
7 * SPDX-License-Identifier: Apache-2.0
8 */
9
10#ifndef ZEPHYR_INCLUDE_ARCH_ARC_V2_ARCV2_IRQ_UNIT_H_
11#define ZEPHYR_INCLUDE_ARCH_ARC_V2_ARCV2_IRQ_UNIT_H_
12
13#ifdef __cplusplus
14extern "C" {
15#endif
16
17/* configuration flags for interrupt unit */
18#define _ARC_V2_INT_PRIO_MASK 0xf
19#define _ARC_V2_INT_DISABLE 0
20#define _ARC_V2_INT_ENABLE 1
21
22#define _ARC_V2_INT_LEVEL 0
23#define _ARC_V2_INT_PULSE 1
24
25#ifndef _ASMLANGUAGE
26
27/*
28 * NOTE:
29 *
30 * All APIs provided by this file are protected with INTERRUPTS LOCKED. The
31 * APIs themselves are writing the IRQ_SELECT, selecting which IRQ's registers
32 * it wants to write to, then write to them: THIS IS NOT AN ATOMIC OPERATION.
33 *
34 * Locking the interrupts inside of the APIs are some kind of self-protection
35 * to guarantee the correctness of operation if the callers don't lock
36 * the interrupt.
37 *
38 */
39
40/*
41 * @brief Enable/disable interrupt
42 *
43 * Enables or disables the specified interrupt
44 *
45 * @return N/A
46 */
47
48static ALWAYS_INLINE
49void z_arc_v2_irq_unit_irq_enable_set(
50 int irq,
51 unsigned char enable
52 )
53{
54 unsigned int key = arch_irq_lock();
55
56 z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
57 z_arc_v2_aux_reg_write(_ARC_V2_IRQ_ENABLE, enable);
58
60}
61
62/*
63 * @brief Enable interrupt
64 *
65 * Enables the specified interrupt
66 *
67 * @return N/A
68 */
69
70static ALWAYS_INLINE
71void z_arc_v2_irq_unit_int_enable(int irq)
72{
73 z_arc_v2_irq_unit_irq_enable_set(irq, _ARC_V2_INT_ENABLE);
74}
75
76/*
77 * @brief Disable interrupt
78 *
79 * Disables the specified interrupt
80 *
81 * @return N/A
82 */
83
84static ALWAYS_INLINE
85void z_arc_v2_irq_unit_int_disable(int irq)
86{
87 z_arc_v2_irq_unit_irq_enable_set(irq, _ARC_V2_INT_DISABLE);
88}
89
90/*
91 * @brief Poll the enable status of interrupt
92 *
93 * Polls the enable status of the specified interrupt
94 *
95 * @return 1 enabled, 0 disabled
96 */
97
98static ALWAYS_INLINE
99bool z_arc_v2_irq_unit_int_enabled(int irq)
100{
101 bool ret;
102 unsigned int key = arch_irq_lock();
103
104 z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
105 ret = z_arc_v2_aux_reg_read(_ARC_V2_IRQ_ENABLE) & 0x1;
106
108
109 return ret;
110}
111
112
113/*
114 * @brief Set interrupt priority
115 *
116 * Set the priority of the specified interrupt
117 *
118 * @return N/A
119 */
120
121static ALWAYS_INLINE
122void z_arc_v2_irq_unit_prio_set(int irq, unsigned char prio)
123{
124
125 unsigned int key = arch_irq_lock();
126
127 z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
128#if defined(CONFIG_ARC_SECURE_FIRMWARE)
129 z_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY,
130 (z_arc_v2_aux_reg_read(_ARC_V2_IRQ_PRIORITY) & (~_ARC_V2_INT_PRIO_MASK))
131 | prio);
132#else
133 z_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY, prio);
134#endif
136}
137
138#if defined(CONFIG_ARC_SECURE_FIRMWARE)
139/*
140 * @brief Configure the secure state of interrupt
141 *
142 * Configure the secure state of the specified interrupt
143 *
144 * @return N/A
145 */
146static ALWAYS_INLINE
147void z_arc_v2_irq_uinit_secure_set(int irq, bool secure)
148{
149 unsigned int key = arch_irq_lock();
150
151 z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
152
153 if (secure) {
154 z_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY,
155 z_arc_v2_aux_reg_read(_ARC_V2_IRQ_PRIORITY) |
156 _ARC_V2_IRQ_PRIORITY_SECURE);
157 } else {
158 z_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY,
159 z_arc_v2_aux_reg_read(_ARC_V2_IRQ_PRIORITY) &
160 _ARC_V2_INT_PRIO_MASK);
161 }
162
164}
165#endif
166
167/*
168 * @brief Set interrupt sensitivity
169 *
170 * Set the sensitivity of the specified interrupt to either
171 * _ARC_V2_INT_LEVEL or _ARC_V2_INT_PULSE. Level interrupts will remain
172 * asserted until the interrupt handler clears the interrupt at the peripheral.
173 * Pulse interrupts self-clear as the interrupt handler is entered.
174 *
175 * @return N/A
176 */
177
178static ALWAYS_INLINE
179void z_arc_v2_irq_unit_sensitivity_set(int irq, int s)
180{
181 unsigned int key = arch_irq_lock();
182
183 z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
184 z_arc_v2_aux_reg_write(_ARC_V2_IRQ_TRIGGER, s);
185
187}
188
189/*
190 * @brief Check whether processor in interrupt/exception state
191 *
192 * Check whether processor in interrupt/exception state
193 *
194 * @return 1 in interrupt/exception state; 0 not in
195 */
196static ALWAYS_INLINE
197bool z_arc_v2_irq_unit_is_in_isr(void)
198{
199 uint32_t act = z_arc_v2_aux_reg_read(_ARC_V2_AUX_IRQ_ACT);
200
201 /* in exception ?*/
202 if (z_arc_v2_aux_reg_read(_ARC_V2_STATUS32) & _ARC_V2_STATUS32_AE) {
203 return true;
204 }
205
206 return ((act & 0xffff) != 0U);
207}
208
209/*
210 * @brief Sets an IRQ line to level/pulse trigger
211 *
212 * Sets the IRQ line <irq> to trigger an interrupt based on the level or the
213 * edge of the signal. Valid values for <trigger> are _ARC_V2_INT_LEVEL and
214 * _ARC_V2_INT_PULSE.
215 *
216 * @return N/A
217 */
218static ALWAYS_INLINE
219void z_arc_v2_irq_unit_trigger_set(int irq, unsigned int trigger)
220{
221 unsigned int key = arch_irq_lock();
222
223 z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
224 z_arc_v2_aux_reg_write(_ARC_V2_IRQ_TRIGGER, trigger);
225
227}
228
229/*
230 * @brief Returns an IRQ line trigger type
231 *
232 * Gets the IRQ line <irq> trigger type.
233 * Valid values for <trigger> are _ARC_V2_INT_LEVEL and _ARC_V2_INT_PULSE.
234 *
235 * @return trigger state
236 */
237static ALWAYS_INLINE
238unsigned int z_arc_v2_irq_unit_trigger_get(int irq)
239{
240 unsigned int ret;
241 unsigned int key = arch_irq_lock();
242
243 z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
244 ret = z_arc_v2_aux_reg_read(_ARC_V2_IRQ_TRIGGER);
245
247
248 return ret;
249}
250
251/*
252 * @brief Send EOI signal to interrupt unit
253 *
254 * This routine sends an EOI (End Of Interrupt) signal to the interrupt unit
255 * to clear a pulse-triggered interrupt.
256 *
257 * @return N/A
258 */
259static ALWAYS_INLINE
260void z_arc_v2_irq_unit_int_eoi(int irq)
261{
262 unsigned int key = arch_irq_lock();
263
264 z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
265 z_arc_v2_aux_reg_write(_ARC_V2_IRQ_PULSE_CANCEL, 1);
266
268}
269
270#endif /* _ASMLANGUAGE */
271
272#ifdef __cplusplus
273}
274#endif
275
276#endif /* ZEPHYR_INCLUDE_ARCH_ARC_V2_ARCV2_IRQ_UNIT_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
irp nz macro MOVR cc s mov cc s endm endr irp aw macro LDR aa s
Definition: asm-macro-32-bit-gnu.h:17
#define ALWAYS_INLINE
Definition: common.h:116
static ZTEST_BMEM volatile int ret
Definition: k_float_disable.c:28
static k_spinlock_key_t key
Definition: spinlock_error_case.c:14
__UINT32_TYPE__ uint32_t
Definition: stdint.h:60