• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification,
5  * are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice, this list of
8  *    conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11  *    of conditions and the following disclaimer in the documentation and/or other materials
12  *    provided with the distribution.
13  *
14  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15  *    to endorse or promote products derived from this software without specific prior written
16  *    permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "los_arch_interrupt.h"
32 #include "los_debug.h"
33 
34 #ifdef __ICCARM__
35 #pragma location = ".data.vector"
36 #pragma data_alignment = LOSCFG_ARCH_HWI_VECTOR_ALIGN
37 /* *
38  * @ingroup los_hwi
39  * Hardware interrupt form mapping handling function array.
40  */
41 HWI_PROC_FUNC g_hwiForm[OS_VECTOR_CNT] = {0};
42 #elif defined(__CC_ARM) || defined(__GNUC__)
43 LITE_OS_SEC_VEC
44 /* *
45  * @ingroup los_hwi
46  * Hardware interrupt form mapping handling function array.
47  */
48 HWI_PROC_FUNC __attribute__((aligned(LOSCFG_ARCH_HWI_VECTOR_ALIGN))) g_hwiForm[OS_VECTOR_CNT] = {0};
49 #endif
50 
ArchGetHwiFrom(VOID)51 VOID *ArchGetHwiFrom(VOID)
52 {
53     return g_hwiForm;
54 }
55 
56 UINT32 g_intCount = 0;
57 
58 /* ****************************************************************************
59  Function    : HalHwiDefaultHandler
60  Description : default handler of the hardware interrupt
61  Input       : None
62  Output      : None
63  Return      : None
64  **************************************************************************** */
HalHwiDefaultHandler(VOID)65 LITE_OS_SEC_TEXT_MINOR VOID HalHwiDefaultHandler(VOID)
66 {
67     PRINT_ERR("%s irqnum:%u\n", __FUNCTION__, ArchIntCurIrqNum());
68     while (1) {}
69 }
70 
HalPreInterruptHandler(UINT32 arg)71 WEAK VOID HalPreInterruptHandler(UINT32 arg)
72 {
73     (VOID)arg;
74     return;
75 }
76 
HalAftInterruptHandler(UINT32 arg)77 WEAK VOID HalAftInterruptHandler(UINT32 arg)
78 {
79     (VOID)arg;
80     return;
81 }
82 
83 #if (LOSCFG_DEBUG_TOOLS == 1)
84 STATIC UINT32 g_hwiFormCnt[OS_HWI_MAX_NUM] = {0};
85 STATIC CHAR *g_hwiFormName[OS_HWI_MAX_NUM] = {0};
86 
OsGetHwiFormCnt(UINT32 index)87 UINT32 OsGetHwiFormCnt(UINT32 index)
88 {
89     return g_hwiFormCnt[index];
90 }
91 
OsGetHwiFormName(UINT32 index)92 CHAR *OsGetHwiFormName(UINT32 index)
93 {
94     return g_hwiFormName[index];
95 }
96 
OsHwiIsCreated(UINT32 index)97 BOOL OsHwiIsCreated(UINT32 index)
98 {
99     if (g_hwiForm[index] != (HWI_PROC_FUNC)HalHwiDefaultHandler) {
100         return TRUE;
101     }
102 
103     return FALSE;
104 }
105 #endif
106 
107 #if (LOSCFG_PLATFORM_HWI_WITH_ARG == 1)
108 
109 /* *
110  * @ingroup los_hwi
111  * Hardware interrupt handler form mapping handling function array.
112  */
113 HWI_HANDLER_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {{ (HWI_PROC_FUNC)0, (HWI_ARG_T)0 }};
114 
115 /* *
116  * @ingroup los_hwi
117  * Set interrupt vector table.
118  */
OsSetVector(UINT32 num,HWI_PROC_FUNC vector,VOID * arg)119 VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector, VOID *arg)
120 {
121     if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) {
122         g_hwiForm[num + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalInterrupt;
123         g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pfnHandler = vector;
124         g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pParm = arg;
125     }
126 }
127 #else
128 /* *
129  * @ingroup los_hwi
130  * hardware interrupt handler form mapping handling function array.
131  */
132 HWI_PROC_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {0};
133 
134 /* *
135  * @ingroup los_hwi
136  * Set interrupt vector table.
137  */
OsSetVector(UINT32 num,HWI_PROC_FUNC vector)138 VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector)
139 {
140     if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) {
141         g_hwiForm[num + OS_SYS_VECTOR_CNT] = HalInterrupt;
142         g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT] = vector;
143     }
144 }
145 #endif
146 
ArchIntTrigger(HWI_HANDLE_T hwiNum)147 UINT32 ArchIntTrigger(HWI_HANDLE_T hwiNum)
148 {
149     if (hwiNum >= OS_HWI_MAX_NUM) {
150         return OS_ERRNO_HWI_NUM_INVALID;
151     }
152 
153     HwiControllerOps *hwiOps = ArchIntOpsGet();
154     if (hwiOps->triggerIrq == NULL) {
155         return OS_ERRNO_HWI_OPS_FUNC_NULL;
156     }
157 
158     return hwiOps->triggerIrq(hwiNum);
159 }
160 
ArchIntEnable(HWI_HANDLE_T hwiNum)161 UINT32 ArchIntEnable(HWI_HANDLE_T hwiNum)
162 {
163     if (hwiNum >= OS_HWI_MAX_NUM) {
164         return OS_ERRNO_HWI_NUM_INVALID;
165     }
166 
167     HwiControllerOps *hwiOps = ArchIntOpsGet();
168     if (hwiOps->enableIrq == NULL) {
169         return OS_ERRNO_HWI_OPS_FUNC_NULL;
170     }
171 
172     return hwiOps->enableIrq(hwiNum);
173 }
174 
ArchIntDisable(HWI_HANDLE_T hwiNum)175 UINT32 ArchIntDisable(HWI_HANDLE_T hwiNum)
176 {
177     if (hwiNum >= OS_HWI_MAX_NUM) {
178         return OS_ERRNO_HWI_NUM_INVALID;
179     }
180 
181     HwiControllerOps *hwiOps = ArchIntOpsGet();
182     if (hwiOps->disableIrq == NULL) {
183         return OS_ERRNO_HWI_OPS_FUNC_NULL;
184     }
185 
186     return hwiOps->disableIrq(hwiNum);
187 }
188 
ArchIntClear(HWI_HANDLE_T hwiNum)189 UINT32 ArchIntClear(HWI_HANDLE_T hwiNum)
190 {
191     if (hwiNum >= OS_HWI_MAX_NUM) {
192         return OS_ERRNO_HWI_NUM_INVALID;
193     }
194 
195     HwiControllerOps *hwiOps = ArchIntOpsGet();
196     if (hwiOps->clearIrq == NULL) {
197         return OS_ERRNO_HWI_OPS_FUNC_NULL;
198     }
199 
200     return hwiOps->clearIrq(hwiNum);
201 }
202 
ArchIntSetPriority(HWI_HANDLE_T hwiNum,HWI_PRIOR_T priority)203 UINT32 ArchIntSetPriority(HWI_HANDLE_T hwiNum, HWI_PRIOR_T priority)
204 {
205     if (hwiNum >= OS_HWI_MAX_NUM) {
206         return OS_ERRNO_HWI_NUM_INVALID;
207     }
208 
209     if (priority > OS_HWI_PRIO_LOWEST) {
210         return OS_ERRNO_HWI_PRIO_INVALID;
211     }
212 
213     HwiControllerOps *hwiOps = ArchIntOpsGet();
214     if (hwiOps->setIrqPriority == NULL) {
215         return OS_ERRNO_HWI_OPS_FUNC_NULL;
216     }
217 
218     return hwiOps->setIrqPriority(hwiNum, priority);
219 }
220 
ArchIntCurIrqNum(VOID)221 UINT32 ArchIntCurIrqNum(VOID)
222 {
223     HwiControllerOps *hwiOps = ArchIntOpsGet();
224     return hwiOps->getCurIrqNum();
225 }
226 
227 /* ****************************************************************************
228  Function    : ArchHwiCreate
229  Description : create hardware interrupt
230  Input       : hwiNum   --- hwi num to create
231                hwiPrio  --- priority of the hwi
232                hwiMode  --- unused
233                hwiHandler --- hwi handler
234                irqParam --- param of the hwi handler
235  Output      : None
236  Return      : LOS_OK on success or error code on failure
237  **************************************************************************** */
ArchHwiCreate(HWI_HANDLE_T hwiNum,HWI_PRIOR_T hwiPrio,HWI_MODE_T hwiMode,HWI_PROC_FUNC hwiHandler,HwiIrqParam * irqParam)238 LITE_OS_SEC_TEXT_INIT UINT32 ArchHwiCreate(HWI_HANDLE_T hwiNum, HWI_PRIOR_T hwiPrio,
239                                            HWI_MODE_T hwiMode, HWI_PROC_FUNC hwiHandler,
240                                            HwiIrqParam *irqParam)
241 {
242     (VOID)hwiMode;
243     UINT32 intSave;
244 
245     if (hwiHandler == NULL) {
246         return OS_ERRNO_HWI_PROC_FUNC_NULL;
247     }
248 
249     if (hwiNum >= OS_HWI_MAX_NUM) {
250         return OS_ERRNO_HWI_NUM_INVALID;
251     }
252 
253     if (g_hwiForm[hwiNum + OS_SYS_VECTOR_CNT] != (HWI_PROC_FUNC)HalHwiDefaultHandler) {
254         return OS_ERRNO_HWI_ALREADY_CREATED;
255     }
256 
257     if (hwiPrio > OS_HWI_PRIO_LOWEST) {
258         return OS_ERRNO_HWI_PRIO_INVALID;
259     }
260 
261     intSave = LOS_IntLock();
262 
263 #if (LOSCFG_PLATFORM_HWI_WITH_ARG == 1)
264     if (irqParam != NULL) {
265         OsSetVector(hwiNum, hwiHandler, irqParam->pDevId);
266     } else {
267         OsSetVector(hwiNum, hwiHandler, NULL);
268     }
269 #else
270     (VOID)irqParam;
271     OsSetVector(hwiNum, hwiHandler);
272 #endif
273 
274 #if (LOSCFG_DEBUG_TOOLS == 1)
275     if ((irqParam != NULL) && (irqParam->pName != NULL)) {
276         g_hwiFormName[hwiNum + OS_SYS_VECTOR_CNT] = (CHAR *)irqParam->pName;
277     }
278     g_hwiFormCnt[hwiNum + OS_SYS_VECTOR_CNT] = 0;
279 #endif
280 
281     HwiControllerOps *hwiOps = ArchIntOpsGet();
282     if (hwiOps->createIrq == NULL) {
283         LOS_IntRestore(intSave);
284         return OS_ERRNO_HWI_OPS_FUNC_NULL;
285     }
286     hwiOps->createIrq(hwiNum, hwiPrio);
287 
288     LOS_IntRestore(intSave);
289 
290     return LOS_OK;
291 }
292 
293 /* ****************************************************************************
294  Function    : ArchHwiDelete
295  Description : Delete hardware interrupt
296  Input       : hwiNum   --- hwi num to delete
297                irqParam --- param of the hwi handler
298  Output      : None
299  Return      : LOS_OK on success or error code on failure
300  **************************************************************************** */
ArchHwiDelete(HWI_HANDLE_T hwiNum,HwiIrqParam * irqParam)301 LITE_OS_SEC_TEXT_INIT UINT32 ArchHwiDelete(HWI_HANDLE_T hwiNum, HwiIrqParam *irqParam)
302 {
303     (VOID)irqParam;
304     UINT32 intSave;
305 
306     if (hwiNum >= OS_HWI_MAX_NUM) {
307         return OS_ERRNO_HWI_NUM_INVALID;
308     }
309 
310     ArchIntDisable((IRQn_Type)hwiNum);
311 
312     intSave = LOS_IntLock();
313 
314     g_hwiForm[hwiNum + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalHwiDefaultHandler;
315 
316     LOS_IntRestore(intSave);
317 
318     return LOS_OK;
319 }
320 
ArchIsIntActive(VOID)321 INLINE UINT32 ArchIsIntActive(VOID)
322 {
323     return (g_intCount > 0);
324 }
325