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: 异常模块的C文件。 1454568cb3Sopenharmony_ci */ 1554568cb3Sopenharmony_ci#include "prt_clk.h" 1654568cb3Sopenharmony_ci#include "prt_exc_internal.h" 1754568cb3Sopenharmony_ci#include "prt_sys_external.h" 1854568cb3Sopenharmony_ci#include "prt_task_external.h" 1954568cb3Sopenharmony_ci#include "prt_irq_external.h" 2054568cb3Sopenharmony_ci#include "prt_asm_cpu_external.h" 2154568cb3Sopenharmony_ci 2254568cb3Sopenharmony_ciOS_SEC_BSS bool g_excSaveFlag; 2354568cb3Sopenharmony_ciOS_SEC_BSS struct ExcRegInfo g_excInfo; 2454568cb3Sopenharmony_ci 2554568cb3Sopenharmony_ci// 异常时获取当前任务的信息 2654568cb3Sopenharmony_ciOS_SEC_BSS ExcTaskInfoFunc g_excTaskInfoGet; 2754568cb3Sopenharmony_ci 2854568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 OsExcConfigInit(void) 2954568cb3Sopenharmony_ci{ 3054568cb3Sopenharmony_ci return OS_OK; 3154568cb3Sopenharmony_ci} 3254568cb3Sopenharmony_ci 3354568cb3Sopenharmony_ci/* 3454568cb3Sopenharmony_ci * 描述:获取异常线程信息 3554568cb3Sopenharmony_ci */ 3654568cb3Sopenharmony_cistatic OS_SEC_L4_TEXT void OsExcGetThreadInfo(struct ExcInfo *excInfo) 3754568cb3Sopenharmony_ci{ 3854568cb3Sopenharmony_ci struct TskInfo taskInfo; 3954568cb3Sopenharmony_ci U32 threadId = INVALIDPID; 4054568cb3Sopenharmony_ci 4154568cb3Sopenharmony_ci if (memset_s(&taskInfo, sizeof(struct TskInfo), 0, sizeof(struct TskInfo)) != EOK) { 4254568cb3Sopenharmony_ci OS_GOTO_SYS_ERROR1(); 4354568cb3Sopenharmony_ci } 4454568cb3Sopenharmony_ci#if defined(OS_OPTION_TASK_INFO) 4554568cb3Sopenharmony_ci /* 任务存在时 */ 4654568cb3Sopenharmony_ci if ((OsTskMaxNumGet() > 0) && ((UNI_FLAG & OS_FLG_BGD_ACTIVE) != 0)) { 4754568cb3Sopenharmony_ci /* 记录当前任务ID号 */ 4854568cb3Sopenharmony_ci if (PRT_TaskSelf(&threadId) == OS_OK) { 4954568cb3Sopenharmony_ci /* 获取当前任务信息 */ 5054568cb3Sopenharmony_ci OS_ERR_RECORD(PRT_TaskGetInfo(threadId, &taskInfo)); 5154568cb3Sopenharmony_ci } 5254568cb3Sopenharmony_ci } 5354568cb3Sopenharmony_ci#endif 5454568cb3Sopenharmony_ci /* 记录发生异常时的线程ID,发生在任务中,此项具有意义,其他线程中,此项无意义 */ 5554568cb3Sopenharmony_ci excInfo->threadId = INVALIDPID; 5654568cb3Sopenharmony_ci 5754568cb3Sopenharmony_ci /* 设置异常前的线程类型 */ 5854568cb3Sopenharmony_ci if (g_intCount > CUR_NEST_COUNT) { 5954568cb3Sopenharmony_ci excInfo->threadType = EXC_IN_HWI; 6054568cb3Sopenharmony_ci } else if ((UNI_FLAG & OS_FLG_TICK_ACTIVE) != 0) { 6154568cb3Sopenharmony_ci excInfo->threadType = EXC_IN_TICK; 6254568cb3Sopenharmony_ci } else if ((UNI_FLAG & OS_FLG_SYS_ACTIVE) != 0) { 6354568cb3Sopenharmony_ci excInfo->threadType = EXC_IN_SYS; 6454568cb3Sopenharmony_ci } else if ((UNI_FLAG & OS_FLG_BGD_ACTIVE) != 0) { 6554568cb3Sopenharmony_ci excInfo->threadType = EXC_IN_TASK; 6654568cb3Sopenharmony_ci if (OsTskMaxNumGet() > 0) { /* 任务存在时 */ 6754568cb3Sopenharmony_ci excInfo->threadId = threadId; 6854568cb3Sopenharmony_ci } 6954568cb3Sopenharmony_ci } else { // OS_FLG_BGD_ACTIVE没有置位,代表此时还在系统进程中,没有进入业务线程。 7054568cb3Sopenharmony_ci excInfo->threadType = EXC_IN_SYS_BOOT; 7154568cb3Sopenharmony_ci } 7254568cb3Sopenharmony_ci 7354568cb3Sopenharmony_ci /* MSP主堆栈 */ 7454568cb3Sopenharmony_ci if ((excInfo->sp >= OsGetSysStackTop()) && (excInfo->sp <= OsGetSysStackBottom())) { 7554568cb3Sopenharmony_ci excInfo->stackBottom = OsGetSysStackBottom(); 7654568cb3Sopenharmony_ci } else { /* PSP进程堆栈 */ 7754568cb3Sopenharmony_ci excInfo->stackBottom = TRUNCATE((taskInfo.topOfStack + taskInfo.stackSize), OS_TSK_STACK_ADDR_ALIGN); 7854568cb3Sopenharmony_ci } 7954568cb3Sopenharmony_ci} 8054568cb3Sopenharmony_ci 8154568cb3Sopenharmony_ci/* 8254568cb3Sopenharmony_ci * 描述:记录异常信息 8354568cb3Sopenharmony_ci */ 8454568cb3Sopenharmony_ciOS_SEC_L4_TEXT void OsExcSaveInfo(struct ExcRegInfo *regs) 8554568cb3Sopenharmony_ci{ 8654568cb3Sopenharmony_ci struct ExcInfo *excInfo = OS_EXC_INFO_ADDR; 8754568cb3Sopenharmony_ci char *version = NULL; 8854568cb3Sopenharmony_ci U64 count; 8954568cb3Sopenharmony_ci 9054568cb3Sopenharmony_ci /* 记录os版本号 */ 9154568cb3Sopenharmony_ci version = PRT_SysGetOsVersion(); 9254568cb3Sopenharmony_ci if (version != NULL) { 9354568cb3Sopenharmony_ci if (strncpy_s(excInfo->osVer, sizeof(excInfo->osVer), 9454568cb3Sopenharmony_ci version, sizeof(excInfo->osVer) - 1) != EOK) { 9554568cb3Sopenharmony_ci OS_GOTO_SYS_ERROR1(); 9654568cb3Sopenharmony_ci } 9754568cb3Sopenharmony_ci } 9854568cb3Sopenharmony_ci excInfo->osVer[OS_SYS_OS_VER_LEN - 1] = '\0'; 9954568cb3Sopenharmony_ci 10054568cb3Sopenharmony_ci /* 记录异常类型 */ 10154568cb3Sopenharmony_ci excInfo->excCause = regs->excType; 10254568cb3Sopenharmony_ci /* 记录CPU ID */ 10354568cb3Sopenharmony_ci excInfo->coreId = OsGetHwThreadId(); 10454568cb3Sopenharmony_ci 10554568cb3Sopenharmony_ci /* 设置字节序 */ 10654568cb3Sopenharmony_ci excInfo->byteOrder = OS_BYTE_ORDER; 10754568cb3Sopenharmony_ci 10854568cb3Sopenharmony_ci /* 记录CPU类型 */ 10954568cb3Sopenharmony_ci excInfo->cpuType = OsGetCpuType(); 11054568cb3Sopenharmony_ci 11154568cb3Sopenharmony_ci /* 记录CPU TICK值 */ 11254568cb3Sopenharmony_ci count = PRT_ClkGetCycleCount64(); 11354568cb3Sopenharmony_ci excInfo->cpuTick = count; 11454568cb3Sopenharmony_ci 11554568cb3Sopenharmony_ci /* 记录当前异常嵌套次数 */ 11654568cb3Sopenharmony_ci excInfo->nestCnt = CUR_NEST_COUNT; 11754568cb3Sopenharmony_ci 11854568cb3Sopenharmony_ci /* 记录寄存器信息 */ 11954568cb3Sopenharmony_ci excInfo->regInfo = (*regs); 12054568cb3Sopenharmony_ci 12154568cb3Sopenharmony_ci /* 记录异常前栈指针 */ 12254568cb3Sopenharmony_ci excInfo->sp = (regs->context)->sp; 12354568cb3Sopenharmony_ci 12454568cb3Sopenharmony_ci /* 记录异常前栈底 */ 12554568cb3Sopenharmony_ci excInfo->stackBottom = INVALIDSTACKBOTTOM; 12654568cb3Sopenharmony_ci 12754568cb3Sopenharmony_ci OsExcGetThreadInfo(excInfo); 12854568cb3Sopenharmony_ci} 12954568cb3Sopenharmony_ci 13054568cb3Sopenharmony_cistatic OS_SEC_L4_TEXT void OsExcRecordInfo(U32 excType, U32 faultAddr, struct ExcContext *excBufAddr) 13154568cb3Sopenharmony_ci{ 13254568cb3Sopenharmony_ci // 若为1时faultAddr有效 13354568cb3Sopenharmony_ci U16 tmpFlag = (U16)OS_GET_32BIT_HIGH_16BIT(excType); 13454568cb3Sopenharmony_ci 13554568cb3Sopenharmony_ci g_excInfo.excType = excType; 13654568cb3Sopenharmony_ci /* 此掩码在CDA解析时需要判断 */ 13754568cb3Sopenharmony_ci if (((U32)tmpFlag & OS_EXC_FLAG_FAULTADDR_VALID) != 0) { 13854568cb3Sopenharmony_ci g_excInfo.faultAddr = faultAddr; 13954568cb3Sopenharmony_ci } else { 14054568cb3Sopenharmony_ci g_excInfo.faultAddr = OS_EXC_IMPRECISE_ACCESS_ADDR; 14154568cb3Sopenharmony_ci } 14254568cb3Sopenharmony_ci 14354568cb3Sopenharmony_ci /* 异常上下文记录 */ 14454568cb3Sopenharmony_ci g_excInfo.context = excBufAddr; 14554568cb3Sopenharmony_ci} 14654568cb3Sopenharmony_ci 14754568cb3Sopenharmony_cistatic OS_SEC_L4_TEXT void OsReboot(void) 14854568cb3Sopenharmony_ci{ 14954568cb3Sopenharmony_ci while (1) { 15054568cb3Sopenharmony_ci /* Wait for HWWDG to reboot board. */ 15154568cb3Sopenharmony_ci } 15254568cb3Sopenharmony_ci} 15354568cb3Sopenharmony_ci/* 15454568cb3Sopenharmony_ci * 描述:EXC模块的处理分发函数 15554568cb3Sopenharmony_ci */ 15654568cb3Sopenharmony_ciOS_SEC_L4_TEXT void OsExcHandleEntryM4(U32 excType, U32 faultAddr, struct ExcContext *excBufAddr) 15754568cb3Sopenharmony_ci{ 15854568cb3Sopenharmony_ci CUR_NEST_COUNT++; 15954568cb3Sopenharmony_ci g_intCount++; 16054568cb3Sopenharmony_ci UNI_FLAG |= OS_FLG_HWI_ACTIVE; 16154568cb3Sopenharmony_ci 16254568cb3Sopenharmony_ci OsExcRecordInfo(excType, faultAddr, excBufAddr); 16354568cb3Sopenharmony_ci 16454568cb3Sopenharmony_ci if (OS_EXC_MAX_NEST_DEPTH < CUR_NEST_COUNT || g_excSaveFlag == TRUE) { 16554568cb3Sopenharmony_ci OsReboot(); 16654568cb3Sopenharmony_ci } 16754568cb3Sopenharmony_ci 16854568cb3Sopenharmony_ci if (memset_s(OS_EXC_INFO_ADDR, EXC_RECORD_SIZE, 0, EXC_RECORD_SIZE) != EOK) { 16954568cb3Sopenharmony_ci OS_GOTO_SYS_ERROR1(); 17054568cb3Sopenharmony_ci } 17154568cb3Sopenharmony_ci 17254568cb3Sopenharmony_ci /* 没有初始化完成分配异常信息记录空间 */ 17354568cb3Sopenharmony_ci OsExcSaveInfo(&g_excInfo); 17454568cb3Sopenharmony_ci g_excSaveFlag = TRUE; 17554568cb3Sopenharmony_ci 17654568cb3Sopenharmony_ci if (g_excModInfo.excepHook != NULL) { 17754568cb3Sopenharmony_ci (void)g_excModInfo.excepHook(OS_EXC_INFO_ADDR); 17854568cb3Sopenharmony_ci } 17954568cb3Sopenharmony_ci OsReboot(); 18054568cb3Sopenharmony_ci} 181