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 */ 41HWI_PROC_FUNC g_hwiForm[OS_VECTOR_CNT] = {0}; 42#elif defined(__CC_ARM) || defined(__GNUC__) 43LITE_OS_SEC_VEC 44/* * 45 * @ingroup los_hwi 46 * Hardware interrupt form mapping handling function array. 47 */ 48HWI_PROC_FUNC __attribute__((aligned(LOSCFG_ARCH_HWI_VECTOR_ALIGN))) g_hwiForm[OS_VECTOR_CNT] = {0}; 49#endif 50 51VOID *ArchGetHwiFrom(VOID) 52{ 53 return g_hwiForm; 54} 55 56UINT32 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 **************************************************************************** */ 65LITE_OS_SEC_TEXT_MINOR VOID HalHwiDefaultHandler(VOID) 66{ 67 PRINT_ERR("%s irqnum:%u\n", __FUNCTION__, ArchIntCurIrqNum()); 68 while (1) {} 69} 70 71WEAK VOID HalPreInterruptHandler(UINT32 arg) 72{ 73 (VOID)arg; 74 return; 75} 76 77WEAK VOID HalAftInterruptHandler(UINT32 arg) 78{ 79 (VOID)arg; 80 return; 81} 82 83#if (LOSCFG_DEBUG_TOOLS == 1) 84STATIC UINT32 g_hwiFormCnt[OS_HWI_MAX_NUM] = {0}; 85STATIC CHAR *g_hwiFormName[OS_HWI_MAX_NUM] = {0}; 86 87UINT32 OsGetHwiFormCnt(UINT32 index) 88{ 89 return g_hwiFormCnt[index]; 90} 91 92CHAR *OsGetHwiFormName(UINT32 index) 93{ 94 return g_hwiFormName[index]; 95} 96 97BOOL 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 */ 113HWI_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 */ 119VOID 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 */ 132HWI_PROC_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {0}; 133 134/* * 135 * @ingroup los_hwi 136 * Set interrupt vector table. 137 */ 138VOID 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 147UINT32 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 161UINT32 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 175UINT32 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 189UINT32 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 203UINT32 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 221UINT32 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 **************************************************************************** */ 238LITE_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 **************************************************************************** */ 301LITE_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 321INLINE UINT32 ArchIsIntActive(VOID) 322{ 323 return (g_intCount > 0); 324} 325