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 #include "prt_err_external.h"
17
18 /*
19 * 描述: 获取异常类型
20 */
OsExcGetDefExctype(uintptr_t esr)21 static INIT_SEC_L4_TEXT U32 OsExcGetDefExctype(uintptr_t esr)
22 {
23 U32 excCause;
24 union TagExcEsr excEsr;
25
26 excEsr.esr = esr;
27
28 switch ((U32)excEsr.bits.ec) {
29 case OS_EXC_ESR_UNDEF_INSTR:
30 /* fall through */
31 case OS_EXC_ESR_UNDEF_INSTR + 1:
32 excCause = OS_EXCEPT_UNDEF_INSTR;
33 break;
34 case OS_EXC_ESR_PC_NOT_ALIGN:
35 excCause = OS_EXCEPT_PC_NOT_ALIGN;
36 break;
37 case OS_EXC_ESR_DATA_ABORT:
38 /* fall through */
39 case OS_EXC_ESR_DATA_ABORT + 1:
40 excCause = OS_EXCEPT_DATA_ABORT;
41 break;
42 case OS_EXC_ESR_SP_INSTR:
43 excCause = OS_EXCEPT_SP_NOT_ALIGN;
44 break;
45 default:
46 excCause = OS_EXCEPT_ESR;
47 break;
48 }
49 return excCause;
50 }
51
52 /*
53 * 描述: 记录异常原因
54 */
OsExcSaveCause(uintptr_t esr)55 static INIT_SEC_L4_TEXT void OsExcSaveCause(uintptr_t esr)
56 {
57 U32 preFatalErr;
58 U32 excCause;
59 struct ExcInfo *excInfo = OS_EXC_INFO_ADDR;
60
61 /* 记录异常类型 */
62 preFatalErr = OsFatalErrClr();
63 if (preFatalErr == OS_EXC_DEFAULT_EXC_TYPE) {
64 excCause = OsExcGetDefExctype(esr);
65 } else {
66 excCause = OS_EXCEPT_FATALERROR;
67 }
68
69 excInfo->excCause = excCause;
70 excInfo->fatalErrNo = preFatalErr;
71 return;
72 }
73
74 /*
75 * 描述: EXC钩子处理函数
76 */
OsExcHookHandle(void)77 INIT_SEC_L4_TEXT void OsExcHookHandle(void)
78 {
79 struct ExcInfo *excInfo = OS_EXC_INFO_ADDR;
80
81 if (g_excModInfo.excepHook != NULL) {
82 (void)g_excModInfo.excepHook(excInfo); // 目前不支持异常返回
83 }
84
85 PRT_SysReboot();
86 }
87
88 /*
89 * 描述: FIQ异常处理
90 */
OsExcFiqProc(U32 excType)91 OS_SEC_ALW_INLINE INLINE void OsExcFiqProc(U32 excType)
92 {
93 struct ExcInfo excInfo = {0};
94 excInfo.excCause = excType;
95
96 if (g_excModInfo.excepHook != NULL) {
97 (void)g_excModInfo.excepHook(&excInfo);
98 }
99
100 PRT_SysReboot();
101 }
102
103 /*
104 * 描述: EXC模块的处理分发函数
105 */
OsExcHandleEntry(U32 excType,struct ExcRegInfo * excRegs)106 INIT_SEC_L4_TEXT void OsExcHandleEntry(U32 excType, struct ExcRegInfo *excRegs)
107 {
108 U32 coreID = THIS_CORE();
109 struct ExcInfo *excInfo = OS_EXC_INFO_ADDR;
110
111 UNI_FLAG |= (OS_FLG_HWI_ACTIVE | OS_FLG_EXC_ACTIVE);
112 if (excType == OS_EXCEPT_FIQ) {
113 OsExcFiqProc(excType);
114 return;
115 }
116
117 OsExcSaveCause(excRegs->esr);
118
119 CUR_NEST_COUNT++;
120
121 /* 记录异常信息 */
122 OsExcSaveInfo(excInfo, excRegs);
123
124 /* 回调异常钩子函数 */
125 OsExcHookHandle();
126 }
127
128 /*
129 * 描述: EXC模块的初始化
130 */
OsExcConfigInit(void)131 OS_SEC_L4_TEXT U32 OsExcConfigInit(void)
132 {
133 #if defined(OS_OPTION_CDA)
134 OsCdaExcInit();
135 #endif
136 return OS_OK;
137 }
138
139 /*
140 * 描述: 切换到系统栈
141 */
OsSwitchToSysStack(uintptr_t sp)142 INIT_SEC_L4_TEXT uintptr_t OsSwitchToSysStack(uintptr_t sp)
143 {
144 uintptr_t sysStackHigh;
145 uintptr_t sysStackLow;
146 uintptr_t dstSp;
147
148 sysStackHigh = OsGetSysStackEnd();
149 sysStackLow = OsGetSysStackStart();
150 if (sp <= sysStackHigh && sp >= sysStackLow) {
151 return sp;
152 }
153
154 RUNNING_TASK->stackPointer = (void *)sp;
155 dstSp = sysStackHigh - sizeof(struct TskContext);
156
157 if (memcpy_s((void *)dstSp, sizeof(struct TskContext), (void *)sp, sizeof(struct TskContext)) != EOK) {
158 OS_GOTO_SYS_ERROR();
159 }
160
161 return dstSp;
162 }
163