1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /**
33 * @defgroup los_hwi Hardware interrupt
34 * @ingroup kernel
35 */
36 #ifndef _LOS_HWI_H
37 #define _LOS_HWI_H
38
39 #include "los_base.h"
40 #include "los_hw_cpu.h"
41 #include "hal_hwi.h"
42
43 #ifdef __cplusplus
44 #if __cplusplus
45 extern "C" {
46 #endif /* __cplusplus */
47 #endif /* __cplusplus */
48
49 /**
50 * @ingroup los_hwi
51 * Count of interrupts.
52 */
53 extern size_t g_intCount[];
54
55 /**
56 * @ingroup los_hwi
57 * An interrupt is active.
58 */
59 #define OS_INT_ACTIVE ({ \
60 size_t intCount; \
61 UINT32 intSave_ = LOS_IntLock(); \
62 intCount = g_intCount[ArchCurrCpuid()]; \
63 LOS_IntRestore(intSave_); \
64 intCount; \
65 })
66
67 /**
68 * @ingroup los_hwi
69 * An interrupt is inactive.
70 */
71 #define OS_INT_INACTIVE (!(OS_INT_ACTIVE))
72
73 /**
74 * @ingroup los_hwi
75 * Highest priority of a hardware interrupt.
76 */
77 #define OS_HWI_PRIO_HIGHEST 0
78
79 /**
80 * @ingroup los_hwi
81 * Lowest priority of a hardware interrupt.
82 */
83 #define OS_HWI_PRIO_LOWEST 31
84
85 /**
86 * @ingroup los_hwi
87 * Max name length of a hardware interrupt.
88 */
89 #define OS_HWI_MAX_NAMELEN 10
90
91 /**
92 * @ingroup los_hwi
93 * Hardware interrupt error code: Invalid interrupt number.
94 *
95 * Value: 0x02000900
96 *
97 * Solution: Ensure that the interrupt number is valid.
98 */
99 #define OS_ERRNO_HWI_NUM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x00)
100
101 /**
102 * @ingroup los_hwi
103 * Hardware interrupt error code: Null hardware interrupt handling function.
104 *
105 * Value: 0x02000901
106 *
107 * Solution: Pass in a valid non-null hardware interrupt handling function.
108 */
109 #define OS_ERRNO_HWI_PROC_FUNC_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x01)
110
111 /**
112 * @ingroup los_hwi
113 * Hardware interrupt error code: Insufficient interrupt resources for hardware interrupt creation.
114 *
115 * Value: 0x02000902
116 *
117 * Solution: Increase the configured maximum number of supported hardware interrupts.
118 */
119 #define OS_ERRNO_HWI_CB_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x02)
120
121 /**
122 * @ingroup los_hwi
123 * Hardware interrupt error code: Insufficient memory for hardware interrupt initialization.
124 *
125 * Value: 0x02000903
126 *
127 * Solution: Expand the configured memory.
128 */
129 #define OS_ERRNO_HWI_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x03)
130
131 /**
132 * @ingroup los_hwi
133 * Hardware interrupt error code: The interrupt has already been created.
134 *
135 * Value: 0x02000904
136 *
137 * Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created.
138 */
139 #define OS_ERRNO_HWI_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x04)
140
141 /**
142 * @ingroup los_hwi
143 * Hardware interrupt error code: Invalid interrupt priority.
144 *
145 * Value: 0x02000905
146 *
147 * Solution: Ensure that the interrupt priority is valid.
148 */
149 #define OS_ERRNO_HWI_PRIO_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x05)
150
151 /**
152 * @ingroup los_hwi
153 * Hardware interrupt error code: Incorrect interrupt creation mode.
154 *
155 * Value: 0x02000906
156 *
157 * Solution: The interrupt creation mode can be only set to OS_HWI_MODE_COMM or OS_HWI_MODE_FAST of
158 * which the value can be 0 or 1.
159 */
160 #define OS_ERRNO_HWI_MODE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x06)
161
162 /**
163 * @ingroup los_hwi
164 * Hardware interrupt error code: The interrupt has already been created as a fast interrupt.
165 *
166 * Value: 0x02000907
167 *
168 * Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created.
169 */
170 #define OS_ERRNO_HWI_FASTMODE_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x07)
171
172 /**
173 * @ingroup los_hwi
174 * Hardware interrupt error code: The API is called during an interrupt, which is forbidden.
175 *
176 * Value: 0x02000908
177 *
178 * * Solution: Do not call the API during an interrupt.
179 */
180 #define OS_ERRNO_HWI_INTERR LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x08)
181
182 /**
183 * @ingroup los_hwi
184 * Hardware interrupt error code:the hwi support SHARED error.
185 *
186 * Value: 0x02000909
187 *
188 * * Solution: Check the input params hwiMode and irqParam of LOS_HwiCreate or
189 * LOS_HwiDelete whether adapt the current hwi.
190 */
191 #define OS_ERRNO_HWI_SHARED_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x09)
192
193 /**
194 * @ingroup los_hwi
195 * Hardware interrupt error code:Invalid interrupt Arg when interrupt mode is IRQF_SHARED.
196 *
197 * Value: 0x0200090a
198 *
199 * * Solution: Check the interrupt Arg, Arg should not be NULL and pDevId should not be NULL.
200 */
201 #define OS_ERRNO_HWI_ARG_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x0a)
202
203 /**
204 * @ingroup los_hwi
205 * Hardware interrupt error code:The interrupt corresponded to the hwi number or devid has not been created.
206 *
207 * Value: 0x0200090b
208 *
209 * * Solution: Check the hwi number or devid, make sure the hwi number or devid need to delete.
210 */
211 #define OS_ERRNO_HWI_HWINUM_UNCREATE LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x0b)
212
213 /**
214 * @ingroup los_hwi
215 * Define the type of a hardware interrupt number.
216 */
217 typedef UINT32 HWI_HANDLE_T;
218
219 /**
220 * @ingroup los_hwi
221 * Define the type of a hardware interrupt priority.
222 */
223 typedef UINT16 HWI_PRIOR_T;
224
225 /**
226 * @ingroup los_hwi
227 * Define the type of hardware interrupt mode configurations.
228 */
229 typedef UINT16 HWI_MODE_T;
230
231 /**
232 * @ingroup los_hwi
233 * Define the type of the parameter used for the hardware interrupt creation function.
234 * The function of this parameter varies among platforms.
235 */
236 typedef UINTPTR HWI_ARG_T;
237
238 /**
239 * @ingroup los_hwi
240 * Define the type of a hardware interrupt handling function.
241 */
242 typedef VOID (*HWI_PROC_FUNC)(VOID);
243
244 /*
245 * These flags used only by the kernel as part of the
246 * irq handling routines.
247 *
248 * IRQF_SHARED - allow sharing the irq among several devices
249 */
250 #define IRQF_SHARED 0x8000U
251
252 typedef struct tagHwiHandleForm {
253 HWI_PROC_FUNC pfnHook;
254 HWI_ARG_T uwParam;
255 struct tagHwiHandleForm *pstNext;
256 } HwiHandleForm;
257
258 typedef struct tagIrqParam {
259 int swIrq;
260 VOID *pDevId;
261 const CHAR *pName;
262 } HwiIrqParam;
263
264 extern HwiHandleForm g_hwiForm[OS_HWI_MAX_NUM];
265
266 /**
267 * @ingroup los_hwi
268 * @brief Disable all interrupts.
269 *
270 * @par Description:
271 * <ul>
272 * <li>This API is used to disable all IRQ and FIQ interrupts in the CPSR.</li>
273 * </ul>
274 * @attention
275 * <ul>
276 * <li>None.</li>
277 * </ul>
278 *
279 * @param None.
280 *
281 * @retval #UINT32 CPSR value obtained before all interrupts are disabled.
282 * @par Dependency:
283 * <ul><li>los_hwi.h: the header file that contains the API declaration.</li></ul>
284 * @see LOS_IntRestore
285 */
LOS_IntLock(VOID)286 STATIC INLINE UINT32 LOS_IntLock(VOID)
287 {
288 return ArchIntLock();
289 }
290
291 /**
292 * @ingroup los_hwi
293 * @brief Enable all interrupts.
294 *
295 * @par Description:
296 * <ul>
297 * <li>This API is used to enable all IRQ and FIQ interrupts in the CPSR.</li>
298 * </ul>
299 * @attention
300 * <ul>
301 * <li>None.</li>
302 * </ul>
303 *
304 * @param None.
305 *
306 * @retval #UINT32 CPSR value obtained after all interrupts are enabled.
307 * @par Dependency:
308 * <ul><li>los_hwi.h: the header file that contains the API declaration.</li></ul>
309 * @see LOS_IntLock
310 */
LOS_IntUnLock(VOID)311 STATIC INLINE UINT32 LOS_IntUnLock(VOID)
312 {
313 return ArchIntUnlock();
314 }
315
316 /**
317 * @ingroup los_hwi
318 * @brief Restore interrupts.
319 *
320 * @par Description:
321 * <ul>
322 * <li>This API is used to restore the CPSR value obtained before all interrupts are disabled.</li>
323 * </ul>
324 * @attention
325 * <ul>
326 * <li>This API can be called only after all interrupts are disabled, and the input parameter value should be
327 * the value returned by LOS_IntLock.</li>
328 * </ul>
329 *
330 * @param intSave [IN] Type #UINT32 : CPSR value obtained before all interrupts are disabled.
331 *
332 * @retval None.
333 * @par Dependency:
334 * <ul><li>los_hwi.h: the header file that contains the API declaration.</li></ul>
335 * @see LOS_IntLock
336 */
LOS_IntRestore(UINT32 intSave)337 STATIC INLINE VOID LOS_IntRestore(UINT32 intSave)
338 {
339 ArchIntRestore(intSave);
340 }
341
342 /**
343 * @ingroup los_hwi
344 * @brief Gets the maximum number of interrupts supported by the system.
345 *
346 * @par Description:
347 * <ul>
348 * <li>This API is used to gets the maximum number of interrupts supported by the system.</li>
349 * </ul>
350 *
351 * @param None.
352 *
353 * @retval None.
354 * @par Dependency:
355 * <ul><li>los_hwi.h: the header file that contains the API declaration.</li></ul>
356 */
357 extern UINT32 LOS_GetSystemHwiMaximum(VOID);
358
359 /**
360 * @ingroup los_hwi
361 * @brief Create a hardware interrupt.
362 *
363 * @par Description:
364 * This API is used to configure a hardware interrupt and register a hardware interrupt handling function.
365 *
366 * @attention
367 * <ul>
368 * <li>The hardware interrupt module is usable only when the configuration item for
369 * hardware interrupt tailoring is enabled.</li>
370 * <li>Hardware interrupt number value range: [OS_USER_HWI_MIN,OS_USER_HWI_MAX]. </li>
371 * <li>OS_HWI_MAX_NUM specifies the maximum number of interrupts that can be created.</li>
372 * <li>Before executing an interrupt on a platform, refer to the chip manual of the platform.</li>
373 * <li>The parameter handler of this interface is a interrupt handler, it should be correct, otherwise,
374 * the system may be abnormal.</li>
375 * <li>The input irqParam could be NULL, if not, it should be address which point to a struct HwiIrqParam</li>
376 * </ul>
377 *
378 * @param hwiNum [IN] Type #HWI_HANDLE_T: hardware interrupt number.
379 * for an ARM926 platform is [0,31].
380 * @param hwiPrio [IN] Type #HWI_PRIOR_T: hardware interrupt priority. The value range is
381 * [0, GIC_MAX_INTERRUPT_PREEMPTION_LEVEL - 1] << PRIORITY_SHIFT.
382 * @param hwiMode [IN] Type #HWI_MODE_T: hardware interrupt mode. Ignore this parameter temporarily.
383 * @param hwiHandler [IN] Type #HWI_PROC_FUNC: interrupt handler used when a hardware interrupt is triggered.
384 * @param irqParam [IN] Type #HwiIrqParam: input parameter of the interrupt handler used when
385 * a hardware interrupt is triggered.
386 *
387 * @retval #OS_ERRNO_HWI_PROC_FUNC_NULL Null hardware interrupt handling function.
388 * @retval #OS_ERRNO_HWI_NUM_INVALID Invalid interrupt number.
389 * @retval #OS_ERRNO_HWI_NO_MEMORY Insufficient memory for hardware interrupt creation.
390 * @retval #OS_ERRNO_HWI_ALREADY_CREATED The interrupt handler being created has already been created.
391 * @retval #LOS_OK The interrupt is successfully created.
392 * @par Dependency:
393 * <ul><li>los_hwi.h: the header file that contains the API declaration.</li></ul>
394 * @see None.
395 */
396 extern UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum,
397 HWI_PRIOR_T hwiPrio,
398 HWI_MODE_T hwiMode,
399 HWI_PROC_FUNC hwiHandler,
400 HwiIrqParam *irqParam);
401
402 /**
403 * @ingroup los_hwi
404 * @brief delete a hardware interrupt.
405 *
406 * @par Description:
407 * This API is used to delete a hardware interrupt.
408 *
409 * @attention
410 * <ul>
411 * <li>The hardware interrupt module is usable only when the configuration item for
412 * hardware interrupt tailoring is enabled.</li>
413 * <li>Hardware interrupt number value range: [OS_USER_HWI_MIN,OS_USER_HWI_MAX].</li>
414 * <li>OS_HWI_MAX_NUM specifies the maximum number of interrupts that can be created.</li>
415 * <li>Before executing an interrupt on a platform, refer to the chip manual of the platform.</li>
416 * </ul>
417 *
418 * @param hwiNum [IN] Type #HWI_HANDLE_T: hardware interrupt number.
419 * @param irqParam [IN] Type #HwiIrqParam *: id of hardware interrupt which will base on
420 * when delete the hardware interrupt.
421 *
422 * @retval #OS_ERRNO_HWI_NUM_INVALID Invalid interrupt number.
423 * @retval #OS_ERRNO_HWI_SHARED_ERROR Invalid interrupt mode.
424 * @retval #LOS_OK The interrupt is successfully deleted.
425 * @retval #LOS_NOK The interrupt is failed deleted based on the pDev_ID.
426
427 * @par Dependency:
428 * <ul><li>los_hwi.h: the header file that contains the API declaration.</li></ul>
429 * @see None.
430 */
431 extern UINT32 LOS_HwiDelete(HWI_HANDLE_T hwiNum, HwiIrqParam *irqParam);
432
433 #ifdef __cplusplus
434 #if __cplusplus
435 }
436 #endif /* __cplusplus */
437 #endif /* __cplusplus */
438
439 #endif /* _LOS_HWI_H */
440