1 /*
2 * Copyright (c) 2022-2022 Huawei Technologies Co., Ltd. All rights reserved.
3 *
4 * UniProton is licensed under Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 * http://license.coscl.org.cn/MulanPSL2
8 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11 * See the Mulan PSL v2 for more details.
12 * Create: 2022-11-22
13 * Description: 异常处理。
14 */
15 #include "prt_exc_internal.h"
16
17 // 异常时获取当前任务的信息
18 OS_SEC_BSS ExcTaskInfoFunc g_excTaskInfoGet;
19
20 /*
21 * 描述: 获取异常前的线程信息
22 */
OsExcSetThreadInfo(struct ExcInfo * excInfo)23 OS_SEC_ALW_INLINE INLINE void OsExcSetThreadInfo(struct ExcInfo *excInfo)
24 {
25 U32 threadId = INVALIDPID;
26 struct TskInfo taskInfo = {0};
27
28 if (g_excTaskInfoGet != NULL) {
29 g_excTaskInfoGet(&threadId, &taskInfo);
30 }
31
32 /* 记录发生异常时的线程ID,发生在任务和软中断中,此项具有意义,其他线程中,此项无意义 */
33 excInfo->threadId = INVALIDPID;
34
35 /* 设置异常前的线程类型 */
36 if (OS_INT_COUNT > 0) {
37 excInfo->threadType = EXC_IN_HWI;
38 } else if ((UNI_FLAG & OS_FLG_TICK_ACTIVE) != 0) {
39 excInfo->threadType = EXC_IN_TICK;
40 } else if ((UNI_FLAG & OS_FLG_SYS_ACTIVE) != 0) {
41 excInfo->threadType = EXC_IN_SYS;
42 } else if ((UNI_FLAG & OS_FLG_BGD_ACTIVE) != 0) {
43 excInfo->threadType = EXC_IN_TASK;
44 if (OsTskMaxNumGet() > 0) { /* 任务存在时 */
45 excInfo->threadId = threadId;
46 }
47 } else { /* OS_FLG_BGD_ACTIVE没有置位,代表此时还在系统进程中,没有进入业务线程 */
48 excInfo->threadType = EXC_IN_SYS_BOOT;
49 }
50
51 /* 任务栈栈底 */
52 if (excInfo->threadType == EXC_IN_TASK) {
53 excInfo->stackBottom = TRUNCATE((taskInfo.topOfStack + taskInfo.stackSize), OS_EXC_STACK_ALIGN);
54 }
55 }
56
57 /*
58 * 描述: 记录异常信息
59 */
OsExcSaveInfo(struct ExcInfo * excInfo,struct ExcRegInfo * regs)60 INIT_SEC_L4_TEXT void OsExcSaveInfo(struct ExcInfo *excInfo, struct ExcRegInfo *regs)
61 {
62 U64 cycle;
63
64 /* 记录异常嵌套计数 */
65 excInfo->nestCnt = CUR_NEST_COUNT;
66
67 /* 记录os版本号 */
68 if (strncpy_s(excInfo->osVer, sizeof(excInfo->osVer), PRT_SysGetOsVersion(), (sizeof(excInfo->osVer) - 1)) != EOK) {
69 OS_GOTO_SYS_ERROR();
70 }
71 excInfo->osVer[OS_SYS_OS_VER_LEN - 1] = '\0';
72
73 /* 记录CPU ID */
74 excInfo->coreId = 0x0U;
75
76 /* 设置字节序 */
77 /* 魔术字 */
78 excInfo->byteOrder = OS_BYTE_ORDER;
79
80 /* 记录CPU类型 */
81 excInfo->cpuType = OsGetCpuType();
82
83 /* 记录CPU TICK值 */
84 cycle = OsCurCycleGet64();
85 excInfo->cpuTick.cntHi = OS_GET_64BIT_HIGH_32BIT(cycle);
86 excInfo->cpuTick.cntLo = (U32)cycle;
87
88 /* 记录寄存器信息 */
89 excInfo->regInfo = *regs;
90
91 /* 记录异常前栈指针 */
92 excInfo->sp = regs->sp;
93
94 /* 记录异常前栈底,系统栈栈底 */
95 excInfo->stackBottom = (uintptr_t)&__os_sys_sp_end;
96
97 OsExcSetThreadInfo(excInfo);
98 }
99