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