• 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 /* *
35  * @ingroup los_hwi
36  * Hardware interrupt form mapping handling function array.
37  */
38 HWI_PROC_FUNC __attribute__((aligned(HWI_ALIGNSIZE))) g_hwiForm[OS_VECTOR_CNT] = {0};
39 
ArchGetHwiFrom(VOID)40 VOID *ArchGetHwiFrom(VOID)
41 {
42     return g_hwiForm;
43 }
44 
45 UINT32 volatile g_intCount = 0;
46 
47 /* ****************************************************************************
48  Function    : HalHwiDefaultHandler
49  Description : default handler of the hardware interrupt
50  Input       : None
51  Output      : None
52  Return      : None
53  **************************************************************************** */
HalHwiDefaultHandler(VOID)54 LITE_OS_SEC_TEXT_MINOR VOID HalHwiDefaultHandler(VOID)
55 {
56     PRINT_ERR("%s irqnum:%x\n", __FUNCTION__, ArchIntCurIrqNum());
57     while (1) {}
58 }
59 
HalPreInterruptHandler(UINT32 arg)60 WEAK VOID HalPreInterruptHandler(UINT32 arg)
61 {
62     (VOID)arg;
63     return;
64 }
65 
HalAftInterruptHandler(UINT32 arg)66 WEAK VOID HalAftInterruptHandler(UINT32 arg)
67 {
68     (VOID)arg;
69     return;
70 }
71 
HwiNumValid(UINT32 num)72 STATIC UINT32 HwiNumValid(UINT32 num)
73 {
74     return ((num) >= OS_USER_HWI_MIN) && ((num) <= OS_USER_HWI_MAX);
75 }
76 
ArchIntTrigger(HWI_HANDLE_T hwiNum)77 UINT32 ArchIntTrigger(HWI_HANDLE_T hwiNum)
78 {
79     if (!HwiNumValid(hwiNum)) {
80         return LOS_ERRNO_HWI_NUM_INVALID;
81     }
82 
83     HwiControllerOps *hwiOps = ArchIntOpsGet();
84     if (hwiOps->triggerIrq == NULL) {
85         return OS_ERRNO_HWI_OPS_FUNC_NULL;
86     }
87 
88     return hwiOps->triggerIrq(hwiNum);
89 }
90 
ArchIntEnable(HWI_HANDLE_T hwiNum)91 UINT32 ArchIntEnable(HWI_HANDLE_T hwiNum)
92 {
93     if (!HwiNumValid(hwiNum)) {
94         return LOS_ERRNO_HWI_NUM_INVALID;
95     }
96 
97     HwiControllerOps *hwiOps = ArchIntOpsGet();
98     if (hwiOps->enableIrq == NULL) {
99         return OS_ERRNO_HWI_OPS_FUNC_NULL;
100     }
101 
102     return hwiOps->enableIrq(hwiNum);
103 }
104 
ArchIntDisable(HWI_HANDLE_T hwiNum)105 UINT32 ArchIntDisable(HWI_HANDLE_T hwiNum)
106 {
107     if (!HwiNumValid(hwiNum)) {
108         return LOS_ERRNO_HWI_NUM_INVALID;
109     }
110 
111     HwiControllerOps *hwiOps = ArchIntOpsGet();
112     if (hwiOps->disableIrq == NULL) {
113         return OS_ERRNO_HWI_OPS_FUNC_NULL;
114     }
115 
116     return hwiOps->disableIrq(hwiNum);
117 }
118 
ArchIntClear(HWI_HANDLE_T hwiNum)119 UINT32 ArchIntClear(HWI_HANDLE_T hwiNum)
120 {
121     if (!HwiNumValid(hwiNum)) {
122         return LOS_ERRNO_HWI_NUM_INVALID;
123     }
124 
125     HwiControllerOps *hwiOps = ArchIntOpsGet();
126     if (hwiOps->clearIrq == NULL) {
127         return OS_ERRNO_HWI_OPS_FUNC_NULL;
128     }
129 
130     return hwiOps->clearIrq(hwiNum);
131 }
132 
ArchIntSetPriority(HWI_HANDLE_T hwiNum,HWI_PRIOR_T priority)133 UINT32 ArchIntSetPriority(HWI_HANDLE_T hwiNum, HWI_PRIOR_T priority)
134 {
135     if (!HwiNumValid(hwiNum)) {
136         return LOS_ERRNO_HWI_NUM_INVALID;
137     }
138 
139     if (!HWI_PRI_VALID(priority)) {
140         return OS_ERRNO_HWI_PRIO_INVALID;
141     }
142 
143     HwiControllerOps *hwiOps = ArchIntOpsGet();
144     if (hwiOps->setIrqPriority == NULL) {
145         return OS_ERRNO_HWI_OPS_FUNC_NULL;
146     }
147 
148     return hwiOps->setIrqPriority(hwiNum, priority);
149 }
150 
ArchIntCurIrqNum(VOID)151 UINT32 ArchIntCurIrqNum(VOID)
152 {
153     HwiControllerOps *hwiOps = ArchIntOpsGet();
154     return hwiOps->getCurIrqNum();
155 }
156 
157 #if (LOSCFG_PLATFORM_HWI_WITH_ARG == 1)
158 
159 /* *
160  * @ingroup los_hwi
161  * Hardware interrupt handler form mapping handling function array.
162  */
163 HWI_HANDLER_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {{ (HWI_PROC_FUNC)0, (HWI_ARG_T)0 }};
164 
165 /* *
166  * @ingroup los_hwi
167  * Set interrupt vector table.
168  */
OsSetVector(UINT32 num,HWI_PROC_FUNC vector,VOID * arg)169 VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector, VOID *arg)
170 {
171     if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) {
172         g_hwiForm[num + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)IrqEntry;
173         g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pfnHandler = vector;
174         g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pParm = arg;
175         ArchIntEnable(num);
176     }
177 }
178 #else
179 /* *
180  * @ingroup los_hwi
181  * Hardware interrupt handler form mapping handling function array.
182  */
183 HWI_PROC_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {0};
184 
185 /* *
186  * @ingroup los_hwi
187  * Set interrupt vector table.
188  */
OsSetVector(UINT32 num,HWI_PROC_FUNC vector)189 VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector)
190 {
191     if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) {
192         g_hwiForm[num + OS_SYS_VECTOR_CNT] = IrqEntry;
193         g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT] = vector;
194         ArchIntEnable(num);
195     }
196 }
197 #endif
198 
199 /* ****************************************************************************
200  Function    : ArchHwiCreate
201  Description : create hardware interrupt
202  Input       : hwiNum   --- hwi num to create
203                hwiPrio  --- priority of the hwi
204                hwiMode  --- unused
205                hwiHandler  --- hwi handler
206                irqParam --- param of the hwi handler
207  Output      : None
208  Return      : LOS_OK on success or error code on failure
209  **************************************************************************** */
ArchHwiCreate(HWI_HANDLE_T hwiNum,HWI_PRIOR_T hwiPrio,HWI_MODE_T hwiMode,HWI_PROC_FUNC hwiHandler,HwiIrqParam * irqParam)210 LITE_OS_SEC_TEXT_INIT UINT32 ArchHwiCreate(HWI_HANDLE_T hwiNum, HWI_PRIOR_T hwiPrio,
211                                            HWI_MODE_T hwiMode, HWI_PROC_FUNC hwiHandler,
212                                            HwiIrqParam *irqParam)
213 {
214     (VOID)hwiMode;
215     UINT32 intSave;
216 
217     if (hwiHandler == NULL) {
218         return OS_ERRNO_HWI_PROC_FUNC_NULL;
219     }
220     if (hwiNum >= OS_HWI_MAX_NUM) {
221         return OS_ERRNO_HWI_NUM_INVALID;
222     }
223     if (g_hwiHandlerForm[hwiNum + OS_SYS_VECTOR_CNT] != 0) {
224         return OS_ERRNO_HWI_ALREADY_CREATED;
225     }
226     if (g_hwiHandlerForm[hwiNum + OS_SYS_VECTOR_CNT] != 0) {
227         return OS_ERRNO_HWI_ALREADY_CREATED;
228     }
229     if (hwiPrio > OS_HWI_PRIO_LOWEST) {
230         return OS_ERRNO_HWI_PRIO_INVALID;
231     }
232     intSave = LOS_IntLock();
233 #if (LOSCFG_PLATFORM_HWI_WITH_ARG == 1)
234     if (irqParam != NULL) {
235         OsSetVector(hwiNum, hwiHandler, irqParam->pDevId);
236     } else {
237         OsSetVector(hwiNum, hwiHandler, NULL);
238     }
239 #else
240     (VOID)irqParam;
241     OsSetVector(hwiNum, hwiHandler);
242 #endif
243 
244     HwiControllerOps *hwiOps = ArchIntOpsGet();
245     if (hwiOps->createIrq == NULL) {
246         LOS_IntRestore(intSave);
247         return OS_ERRNO_HWI_OPS_FUNC_NULL;
248     }
249     hwiOps->createIrq(hwiNum, hwiPrio);
250 
251     LOS_IntRestore(intSave);
252 
253     return LOS_OK;
254 }
255 
256 /* ****************************************************************************
257  Function    : ArchHwiDelete
258  Description : Delete hardware interrupt
259  Input       : hwiNum   --- hwi num to delete
260                irqParam --- param of the hwi handler
261  Output      : None
262  Return      : LOS_OK on success or error code on failure
263  **************************************************************************** */
ArchHwiDelete(HWI_HANDLE_T hwiNum,HwiIrqParam * irqParam)264 LITE_OS_SEC_TEXT_INIT UINT32 ArchHwiDelete(HWI_HANDLE_T hwiNum, HwiIrqParam *irqParam)
265 {
266     (VOID)irqParam;
267     UINT32 intSave;
268 
269     if (hwiNum >= OS_HWI_MAX_NUM) {
270         return OS_ERRNO_HWI_NUM_INVALID;
271     }
272 
273     ArchIntDisable((IRQn_Type)hwiNum);
274 
275     intSave = LOS_IntLock();
276     g_hwiHandlerForm[hwiNum + OS_SYS_VECTOR_CNT] = 0;
277     LOS_IntRestore(intSave);
278 
279     return LOS_OK;
280 }
281 
ArchIsIntActive(VOID)282 UINT32 ArchIsIntActive(VOID)
283 {
284     return (g_intCount > 0);
285 }
286