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 */ 38HWI_PROC_FUNC __attribute__((aligned(HWI_ALIGNSIZE))) g_hwiForm[OS_VECTOR_CNT] = {0}; 39 40VOID *ArchGetHwiFrom(VOID) 41{ 42 return g_hwiForm; 43} 44 45UINT32 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 **************************************************************************** */ 54LITE_OS_SEC_TEXT_MINOR VOID HalHwiDefaultHandler(VOID) 55{ 56 PRINT_ERR("%s irqnum:%x\n", __FUNCTION__, ArchIntCurIrqNum()); 57 while (1) {} 58} 59 60WEAK VOID HalPreInterruptHandler(UINT32 arg) 61{ 62 (VOID)arg; 63 return; 64} 65 66WEAK VOID HalAftInterruptHandler(UINT32 arg) 67{ 68 (VOID)arg; 69 return; 70} 71 72STATIC UINT32 HwiNumValid(UINT32 num) 73{ 74 return ((num) >= OS_USER_HWI_MIN) && ((num) <= OS_USER_HWI_MAX); 75} 76 77UINT32 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 91UINT32 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 105UINT32 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 119UINT32 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 133UINT32 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 151UINT32 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 */ 163HWI_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 */ 169VOID 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 */ 183HWI_PROC_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {0}; 184 185/* * 186 * @ingroup los_hwi 187 * Set interrupt vector table. 188 */ 189VOID 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 **************************************************************************** */ 210LITE_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 **************************************************************************** */ 264LITE_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 282UINT32 ArchIsIntActive(VOID) 283{ 284 return (g_intCount > 0); 285} 286