154568cb3Sopenharmony_ci/* 254568cb3Sopenharmony_ci * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved. 354568cb3Sopenharmony_ci * 454568cb3Sopenharmony_ci * UniProton is licensed under Mulan PSL v2. 554568cb3Sopenharmony_ci * You can use this software according to the terms and conditions of the Mulan PSL v2. 654568cb3Sopenharmony_ci * You may obtain a copy of Mulan PSL v2 at: 754568cb3Sopenharmony_ci * http://license.coscl.org.cn/MulanPSL2 854568cb3Sopenharmony_ci * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 954568cb3Sopenharmony_ci * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 1054568cb3Sopenharmony_ci * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 1154568cb3Sopenharmony_ci * See the Mulan PSL v2 for more details. 1254568cb3Sopenharmony_ci * Create: 2009-12-22 1354568cb3Sopenharmony_ci * Description: Hardware interrupt implementation 1454568cb3Sopenharmony_ci */ 1554568cb3Sopenharmony_ci#include "prt_hook_external.h" 1654568cb3Sopenharmony_ci#include "prt_lib_external.h" 1754568cb3Sopenharmony_ci#include "prt_task_external.h" 1854568cb3Sopenharmony_ci#include "prt_hwi_internal.h" 1954568cb3Sopenharmony_ci 2054568cb3Sopenharmony_ci#if defined(OS_OPTION_HWI_MAX_NUM_CONFIG) 2154568cb3Sopenharmony_ciOS_SEC_BSS U32 g_hwiMaxNumConfig; 2254568cb3Sopenharmony_ci#endif 2354568cb3Sopenharmony_ciOS_SEC_BSS OsVoidFunc g_excTrap; 2454568cb3Sopenharmony_ci/* 2554568cb3Sopenharmony_ci * 重定位以后的向量表, 2654568cb3Sopenharmony_ci * 其最后一个四字节表示当前运行的中断号,初始化系统定义异常向量,以便初始化阶段异常接管 2754568cb3Sopenharmony_ci */ 2854568cb3Sopenharmony_ciVEC_SEC_DATA HwiPubintFunc g_hwiTable[OS_MX_VECTOR_CNT + 1] = { 2954568cb3Sopenharmony_ci (HwiPubintFunc)MSTACK_VECTOR, 3054568cb3Sopenharmony_ci (HwiPubintFunc)OsResetVector, 3154568cb3Sopenharmony_ci}; 3254568cb3Sopenharmony_ci 3354568cb3Sopenharmony_ciOS_SEC_L4_TEXT void OsScheduleInit(void) 3454568cb3Sopenharmony_ci{ 3554568cb3Sopenharmony_ci OS_SET_VECTOR(OS_EXC_PEND_SV, OsPendSv); 3654568cb3Sopenharmony_ci OS_SET_VECTOR(OS_EXC_SVC_CALL, OsSvchandler); 3754568cb3Sopenharmony_ci 3854568cb3Sopenharmony_ci NVIC_SET_EXC_PRI(OS_EXC_PEND_SV, OS_HWI_PRI_LOWEST); 3954568cb3Sopenharmony_ci NVIC_SET_EXC_PRI(OS_EXC_SVC_CALL, OS_HWI_PRI_HIGHEST); 4054568cb3Sopenharmony_ci} 4154568cb3Sopenharmony_ci 4254568cb3Sopenharmony_ciOS_SEC_L4_TEXT void OsHwiGICInit(void) 4354568cb3Sopenharmony_ci{ 4454568cb3Sopenharmony_ci U32 loop; 4554568cb3Sopenharmony_ci /* 系统中断向量表初始化 */ 4654568cb3Sopenharmony_ci for (loop = 0; loop < OS_MX_SYS_VECTOR_CNT; loop++) { 4754568cb3Sopenharmony_ci g_hwiTable[loop] = (HwiPubintFunc)OsHwiDefaultHandler; 4854568cb3Sopenharmony_ci } 4954568cb3Sopenharmony_ci OS_SET_VECTOR(0, (HwiPubintFunc)MSTACK_VECTOR); 5054568cb3Sopenharmony_ci OS_SET_VECTOR(OS_EXC_RESET, OsResetVector); 5154568cb3Sopenharmony_ci OS_SET_VECTOR(OS_EXC_NMI, OsExcNmi); 5254568cb3Sopenharmony_ci OS_SET_VECTOR(OS_EXC_HARD_FAULT, OsExcHardFault); 5354568cb3Sopenharmony_ci OS_SET_VECTOR(OS_EXC_MPU_FAULT, OsExcMemFault); 5454568cb3Sopenharmony_ci OS_SET_VECTOR(OS_EXC_BUS_FAULT, OsExcBusFault); 5554568cb3Sopenharmony_ci OS_SET_VECTOR(OS_EXC_USAGE_FAULT, OsExcUsageFault); 5654568cb3Sopenharmony_ci g_excTrap = (OsVoidFunc)OsExcSvcCall; 5754568cb3Sopenharmony_ci OsScheduleInit(); 5854568cb3Sopenharmony_ci OS_SET_VECTOR(OS_EXC_SYS_TICK, OsTickIsr); 5954568cb3Sopenharmony_ci // 将Tick的优先级置为最低 6054568cb3Sopenharmony_ci NVIC_SET_EXC_PRI(OS_EXC_SYS_TICK, OS_HWI_PRI_LOWEST); 6154568cb3Sopenharmony_ci 6254568cb3Sopenharmony_ci /* 用户中断向量表初始化 */ 6354568cb3Sopenharmony_ci for (loop = OS_MX_SYS_VECTOR_CNT; loop < OS_MX_VECTOR_CNT; loop++) { 6454568cb3Sopenharmony_ci g_hwiTable[loop] = OsInterrupt; 6554568cb3Sopenharmony_ci } 6654568cb3Sopenharmony_ci 6754568cb3Sopenharmony_ci /* 中断向量表定位 */ 6854568cb3Sopenharmony_ci *(volatile U32 *)OS_NVIC_VTOR = (U32)(uintptr_t)g_hwiTable; 6954568cb3Sopenharmony_ci /* 7054568cb3Sopenharmony_ci * 访问钥匙:任何对该寄存器的写操作都必须同时把0x05FA写入此段,否则写操作被忽略 7154568cb3Sopenharmony_ci * 位段10:8为优先级分组 7254568cb3Sopenharmony_ci */ 7354568cb3Sopenharmony_ci *(volatile U32 *)OS_NVIC_AIRCR = (OS_NVIC_AIRCR_REG_ACCESS_PSW | 7454568cb3Sopenharmony_ci (OS_NVIC_AIRCR_PRIGROUP << OS_NVIC_AIRCR_PRIGOUP_BIT_OFFSET)); 7554568cb3Sopenharmony_ci} 7654568cb3Sopenharmony_ci 7754568cb3Sopenharmony_ci/* 7854568cb3Sopenharmony_ci * 描述:默认外部中断处理函数 7954568cb3Sopenharmony_ci */ 8054568cb3Sopenharmony_ciOS_SEC_TEXT void OsInterrupt(void) 8154568cb3Sopenharmony_ci{ 8254568cb3Sopenharmony_ci HwiHandle hwiNum; 8354568cb3Sopenharmony_ci uintptr_t intSave; 8454568cb3Sopenharmony_ci 8554568cb3Sopenharmony_ci /* 操作basepri 设置成关中断 */ 8654568cb3Sopenharmony_ci intSave = PRT_HwiLock(); 8754568cb3Sopenharmony_ci UNI_FLAG |= OS_FLG_HWI_ACTIVE; 8854568cb3Sopenharmony_ci g_intCount++; 8954568cb3Sopenharmony_ci 9054568cb3Sopenharmony_ci /* 取外部中断号,中断号减去系统中断号 */ 9154568cb3Sopenharmony_ci hwiNum = OsIntNumGet() - OS_MX_SYS_VECTOR_CNT; 9254568cb3Sopenharmony_ci#ifdef OS_OPTION_HWI_MAX_NUM_CONFIG 9354568cb3Sopenharmony_ci if (hwiNum > g_hwiMaxNumConfig) { 9454568cb3Sopenharmony_ci PRT_HwiRestore(intSave); 9554568cb3Sopenharmony_ci return; 9654568cb3Sopenharmony_ci } 9754568cb3Sopenharmony_ci#endif 9854568cb3Sopenharmony_ci OsTskHighestSet(); 9954568cb3Sopenharmony_ci 10054568cb3Sopenharmony_ci (void)PRT_HwiUnLock(); 10154568cb3Sopenharmony_ci // ISR执行(这里一处开中断) 10254568cb3Sopenharmony_ci OsHwiHookDispatcher(hwiNum); 10354568cb3Sopenharmony_ci 10454568cb3Sopenharmony_ci (void)PRT_HwiLock(); 10554568cb3Sopenharmony_ci 10654568cb3Sopenharmony_ci g_intCount--; 10754568cb3Sopenharmony_ci 10854568cb3Sopenharmony_ci if (g_intCount == 0) { 10954568cb3Sopenharmony_ci UNI_FLAG &= ~OS_FLG_HWI_ACTIVE; 11054568cb3Sopenharmony_ci } 11154568cb3Sopenharmony_ci 11254568cb3Sopenharmony_ci /* 恢复 basepri */ 11354568cb3Sopenharmony_ci PRT_HwiRestore(intSave); 11454568cb3Sopenharmony_ci 11554568cb3Sopenharmony_ci if ((UNI_FLAG & OS_FLG_TSK_REQ) != 0) { 11654568cb3Sopenharmony_ci OsHwiTrap(); 11754568cb3Sopenharmony_ci } 11854568cb3Sopenharmony_ci} 11954568cb3Sopenharmony_ci 12054568cb3Sopenharmony_ci/* 12154568cb3Sopenharmony_ci * 描述:硬中断模式设置 12254568cb3Sopenharmony_ci */ 12354568cb3Sopenharmony_ciOS_SEC_L4_TEXT void OsHwiPrioritySet(HwiHandle hwiNum, HwiPrior hwiPrio) 12454568cb3Sopenharmony_ci{ 12554568cb3Sopenharmony_ci /* 设置优先级,当前芯片高4位有效,左移4位 */ 12654568cb3Sopenharmony_ci NVIC_SET_IRQ_PRI(hwiNum, OS_HWI_GET_HWI_PRIO(hwiPrio)); 12754568cb3Sopenharmony_ci} 12854568cb3Sopenharmony_ci 12954568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 OsHwiPriorityGet(HwiHandle hwiNum) 13054568cb3Sopenharmony_ci{ 13154568cb3Sopenharmony_ci return (U32)OS_HWI_GET_USER_PRIO((*((volatile U8 *)((uintptr_t)OS_NVIC_PRI_BASE + (hwiNum))))); 13254568cb3Sopenharmony_ci} 13354568cb3Sopenharmony_ci 13454568cb3Sopenharmony_ci/* 13554568cb3Sopenharmony_ci * 描述:使能指定中断号 13654568cb3Sopenharmony_ci */ 13754568cb3Sopenharmony_ciOS_SEC_L2_TEXT U32 PRT_HwiEnable(HwiHandle hwiNum) 13854568cb3Sopenharmony_ci{ 13954568cb3Sopenharmony_ci uintptr_t intSave; 14054568cb3Sopenharmony_ci 14154568cb3Sopenharmony_ci if (hwiNum > OS_HWI_MAX) { 14254568cb3Sopenharmony_ci return OS_ERRNO_HWI_NUM_INVALID; 14354568cb3Sopenharmony_ci } 14454568cb3Sopenharmony_ci 14554568cb3Sopenharmony_ci intSave = PRT_HwiLock(); 14654568cb3Sopenharmony_ci 14754568cb3Sopenharmony_ci NVIC_SET_IRQ(hwiNum); 14854568cb3Sopenharmony_ci PRT_HwiRestore(intSave); 14954568cb3Sopenharmony_ci 15054568cb3Sopenharmony_ci return OS_OK; 15154568cb3Sopenharmony_ci} 15254568cb3Sopenharmony_ci 15354568cb3Sopenharmony_ci/* 15454568cb3Sopenharmony_ci * 描述:清除所有的中断请求位 15554568cb3Sopenharmony_ci */ 15654568cb3Sopenharmony_ciOS_SEC_L2_TEXT void PRT_HwiClearAllPending(void) 15754568cb3Sopenharmony_ci{ 15854568cb3Sopenharmony_ci uintptr_t intSave; 15954568cb3Sopenharmony_ci U32 loop; 16054568cb3Sopenharmony_ci 16154568cb3Sopenharmony_ci intSave = PRT_HwiLock(); 16254568cb3Sopenharmony_ci 16354568cb3Sopenharmony_ci for (loop = 0; loop < OS_HWI_CLRPEND_REG_NUM; loop += sizeof(U32)) { 16454568cb3Sopenharmony_ci *(volatile U32 *)((uintptr_t)OS_NVIC_CLRPEND_BASE + loop) = OS_MAX_U32; 16554568cb3Sopenharmony_ci } 16654568cb3Sopenharmony_ci PRT_HwiRestore(intSave); 16754568cb3Sopenharmony_ci return; 16854568cb3Sopenharmony_ci} 16954568cb3Sopenharmony_ci 17054568cb3Sopenharmony_ci/* 17154568cb3Sopenharmony_ci * 描述:清除单个硬中断的Pending位 17254568cb3Sopenharmony_ci */ 17354568cb3Sopenharmony_ciOS_SEC_L2_TEXT U32 PRT_HwiClearPendingBit(HwiHandle hwiNum) 17454568cb3Sopenharmony_ci{ 17554568cb3Sopenharmony_ci uintptr_t intSave; 17654568cb3Sopenharmony_ci if (hwiNum > OS_HWI_MAX) { 17754568cb3Sopenharmony_ci return OS_ERRNO_HWI_NUM_INVALID; 17854568cb3Sopenharmony_ci } 17954568cb3Sopenharmony_ci 18054568cb3Sopenharmony_ci intSave = PRT_HwiLock(); 18154568cb3Sopenharmony_ci NVIC_CLR_IRQ_PEND(hwiNum); 18254568cb3Sopenharmony_ci PRT_HwiRestore(intSave); 18354568cb3Sopenharmony_ci return OS_OK; 18454568cb3Sopenharmony_ci} 18554568cb3Sopenharmony_ci 18654568cb3Sopenharmony_ci/* 18754568cb3Sopenharmony_ci * 描述:触发指定硬中断号 18854568cb3Sopenharmony_ci */ 18954568cb3Sopenharmony_ciOS_SEC_L2_TEXT U32 PRT_HwiTrigger(U32 dstCore, HwiHandle hwiNum) 19054568cb3Sopenharmony_ci{ 19154568cb3Sopenharmony_ci uintptr_t intSave; 19254568cb3Sopenharmony_ci 19354568cb3Sopenharmony_ci if (hwiNum > OS_HWI_MAX) { 19454568cb3Sopenharmony_ci return OS_ERRNO_HWI_NUM_INVALID; 19554568cb3Sopenharmony_ci } 19654568cb3Sopenharmony_ci 19754568cb3Sopenharmony_ci if (OsGetHwThreadId() != dstCore) { 19854568cb3Sopenharmony_ci return OS_ERRNO_HWI_CORE_ID_INVALID; 19954568cb3Sopenharmony_ci } 20054568cb3Sopenharmony_ci 20154568cb3Sopenharmony_ci intSave = PRT_HwiLock(); 20254568cb3Sopenharmony_ci 20354568cb3Sopenharmony_ci NVIC_SET_IRQ_PEND(hwiNum); 20454568cb3Sopenharmony_ci 20554568cb3Sopenharmony_ci PRT_HwiRestore(intSave); 20654568cb3Sopenharmony_ci 20754568cb3Sopenharmony_ci return OS_OK; 20854568cb3Sopenharmony_ci} 20954568cb3Sopenharmony_ci 21054568cb3Sopenharmony_ci/* 21154568cb3Sopenharmony_ci * 描述:禁止指定中断号 21254568cb3Sopenharmony_ci */ 21354568cb3Sopenharmony_ciOS_SEC_L2_TEXT U32 PRT_HwiDisable(HwiHandle hwiNum) 21454568cb3Sopenharmony_ci{ 21554568cb3Sopenharmony_ci uintptr_t intSave; 21654568cb3Sopenharmony_ci 21754568cb3Sopenharmony_ci if (hwiNum > OS_HWI_MAX) { 21854568cb3Sopenharmony_ci return OS_ERRNO_HWI_NUM_INVALID; 21954568cb3Sopenharmony_ci } 22054568cb3Sopenharmony_ci 22154568cb3Sopenharmony_ci intSave = PRT_HwiLock(); 22254568cb3Sopenharmony_ci 22354568cb3Sopenharmony_ci NVIC_CLR_IRQ(hwiNum); 22454568cb3Sopenharmony_ci PRT_HwiRestore(intSave); 22554568cb3Sopenharmony_ci 22654568cb3Sopenharmony_ci return OS_OK; 22754568cb3Sopenharmony_ci} 22854568cb3Sopenharmony_ci 22954568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 PRT_HwiDelExitHook(HwiExitHook hook) 23054568cb3Sopenharmony_ci{ 23154568cb3Sopenharmony_ci return OsHookDel(OS_HOOK_HWI_EXIT, (OsVoidFunc)hook); 23254568cb3Sopenharmony_ci} 23354568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 PRT_HwiAddExitHook(HwiExitHook hook) 23454568cb3Sopenharmony_ci{ 23554568cb3Sopenharmony_ci return OsHookAdd(OS_HOOK_HWI_EXIT, (OsVoidFunc)hook); 23654568cb3Sopenharmony_ci} 23754568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 PRT_HwiDelEntryHook(HwiEntryHook hook) 23854568cb3Sopenharmony_ci{ 23954568cb3Sopenharmony_ci return OsHookDel(OS_HOOK_HWI_ENTRY, (OsVoidFunc)hook); 24054568cb3Sopenharmony_ci} 24154568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 PRT_HwiAddEntryHook(HwiEntryHook hook) 24254568cb3Sopenharmony_ci{ 24354568cb3Sopenharmony_ci return OsHookAdd(OS_HOOK_HWI_ENTRY, (OsVoidFunc)hook); 24454568cb3Sopenharmony_ci} 245