• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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