1 /*
2 * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification,
5 * are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific prior written
16 * permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 /* ------------ includes ------------ */
32 #include "los_blackbox_system_adapter.h"
33 #include "los_blackbox_common.h"
34 #include "los_blackbox_detector.h"
35 #ifdef LOSCFG_LIB_LIBC
36 #include "stdlib.h"
37 #include "unistd.h"
38 #endif
39 #include "los_base.h"
40 #include "los_config.h"
41 #ifdef LOSCFG_SAVE_EXCINFO
42 #include "los_excinfo_pri.h"
43 #endif
44 #include "los_hw.h"
45 #include "los_init.h"
46 #include "los_memory.h"
47 #include "los_vm_common.h"
48 #include "los_vm_phys.h"
49 #include "los_vm_zone.h"
50 #include "securec.h"
51
52 /* ------------ local macroes ------------ */
53 #define LOG_FLAG "GOODLOG"
54
55 /* ------------ local prototypes ------------ */
56 struct FaultLogInfo {
57 char flag[8]; /* 8 is the length of the flag */
58 int len; /* length of the fault log saved by the module excinfo */
59 struct ErrorInfo info;
60 };
61
62 /* ------------ local function declarations ------------ */
63 /* ------------ global function declarations ------------ */
64 /* ------------ local variables ------------ */
65 static char *g_logBuffer = NULL;
66
67 /* ------------ function definitions ------------ */
SaveFaultLog(const char * filePath,const char * dataBuf,size_t bufSize,struct ErrorInfo * info)68 static void SaveFaultLog(const char *filePath, const char *dataBuf, size_t bufSize, struct ErrorInfo *info)
69 {
70 (void)SaveBasicErrorInfo(filePath, info);
71 (void)FullWriteFile(filePath, dataBuf, bufSize, 1);
72 }
73
74 #ifdef LOSCFG_SAVE_EXCINFO
WriteExcFile(UINT32 startAddr,UINT32 space,UINT32 rwFlag,char * buf)75 static void WriteExcFile(UINT32 startAddr, UINT32 space, UINT32 rwFlag, char *buf)
76 {
77 (void)startAddr;
78 (void)space;
79 (void)rwFlag;
80 (void)buf;
81 }
82 #endif
83
RegisterExcInfoHook(void)84 static void RegisterExcInfoHook(void)
85 {
86 if (g_logBuffer != NULL) {
87 #ifdef LOSCFG_SAVE_EXCINFO
88 LOS_ExcInfoRegHook(0, LOSCFG_BLACKBOX_LOG_SIZE - sizeof(struct FaultLogInfo),
89 g_logBuffer + sizeof(struct FaultLogInfo), WriteExcFile);
90 #endif
91 } else {
92 BBOX_PRINT_ERR("Alloc mem failed!\n");
93 }
94 }
95
AllocLogBuffer(void)96 static int AllocLogBuffer(void)
97 {
98 if (LOSCFG_BLACKBOX_LOG_SIZE < sizeof(struct FaultLogInfo)) {
99 BBOX_PRINT_ERR("LOSCFG_BLACKBOX_LOG_SIZE [%d] is too short, it must be >= %u\n",
100 LOSCFG_BLACKBOX_LOG_SIZE, sizeof(struct FaultLogInfo));
101 return -1;
102 }
103
104 /*
105 * The physical memory pointed to by LOSCFG_BLACKBOX_RESERVE_MEM_ADDR is
106 * exclusive to blackbox and cannot be occupied by other modules during
107 * system running and cannot overlap with the memory area of other systems
108 * during startup.
109 */
110 g_logBuffer = (char *)MEM_CACHED_ADDR(LOSCFG_BLACKBOX_RESERVE_MEM_ADDR);
111 BBOX_PRINT_INFO("g_logBuffer: %p, len: 0x%x for blackbox!\n", g_logBuffer, (UINT32)LOSCFG_BLACKBOX_LOG_SIZE);
112
113 return (g_logBuffer != NULL) ? 0 : -1;
114 }
115
Dump(const char * logDir,struct ErrorInfo * info)116 static void Dump(const char *logDir, struct ErrorInfo *info)
117 {
118 struct FaultLogInfo *pLogInfo = NULL;
119
120 if (logDir == NULL || info == NULL) {
121 BBOX_PRINT_ERR("logDir: %p, info: %p!\n", logDir, info);
122 return;
123 }
124 if (g_logBuffer == NULL) {
125 BBOX_PRINT_ERR("g_logBuffer is NULL, alloc physical pages failed!\n");
126 return;
127 }
128
129 if (strcmp(info->event, EVENT_PANIC) == 0) {
130 pLogInfo = (struct FaultLogInfo *)g_logBuffer;
131 (void)memset_s(pLogInfo, sizeof(*pLogInfo), 0, sizeof(*pLogInfo));
132 #ifdef LOSCFG_SAVE_EXCINFO
133 pLogInfo->len = GetExcInfoIndex();
134 #else
135 pLogInfo->len = 0;
136 #endif
137 (void)memcpy_s(&pLogInfo->flag, sizeof(pLogInfo->flag), LOG_FLAG, strlen(LOG_FLAG));
138 (void)memcpy_s(&pLogInfo->info, sizeof(pLogInfo->info), info, sizeof(*info));
139 DCacheFlushRange((UINTPTR)g_logBuffer, (UINTPTR)(g_logBuffer + LOSCFG_BLACKBOX_LOG_SIZE));
140 } else {
141 #ifdef LOSCFG_SAVE_EXCINFO
142 SaveFaultLog(USER_FAULT_LOG_PATH, g_logBuffer + sizeof(struct FaultLogInfo),
143 Min(LOSCFG_BLACKBOX_LOG_SIZE - sizeof(struct FaultLogInfo), GetExcInfoIndex()), info);
144 #else
145 SaveFaultLog(USER_FAULT_LOG_PATH, g_logBuffer + sizeof(struct FaultLogInfo), 0, info);
146 #endif
147 }
148 }
149
Reset(struct ErrorInfo * info)150 static void Reset(struct ErrorInfo *info)
151 {
152 if (info == NULL) {
153 BBOX_PRINT_ERR("info is NULL!\n");
154 return;
155 }
156
157 if (strcmp(info->event, EVENT_PANIC) != 0) {
158 BBOX_PRINT_INFO("[%s] starts uploading event [%s]\n", info->module, info->event);
159 (void)UploadEventByFile(USER_FAULT_LOG_PATH);
160 BBOX_PRINT_INFO("[%s] ends uploading event [%s]\n", info->module, info->event);
161 }
162 }
163
GetLastLogInfo(struct ErrorInfo * info)164 static int GetLastLogInfo(struct ErrorInfo *info)
165 {
166 struct FaultLogInfo *pLogInfo = NULL;
167
168 if (info == NULL) {
169 BBOX_PRINT_ERR("info is NULL!\n");
170 return -1;
171 }
172 if (g_logBuffer == NULL) {
173 BBOX_PRINT_ERR("g_logBuffer is NULL, alloc physical pages failed!\n");
174 return -1;
175 }
176
177 pLogInfo = (struct FaultLogInfo *)g_logBuffer;
178 if (memcmp(pLogInfo->flag, LOG_FLAG, strlen(LOG_FLAG)) == 0) {
179 (void)memcpy_s(info, sizeof(*info), &pLogInfo->info, sizeof(pLogInfo->info));
180 return 0;
181 }
182
183 return -1;
184 }
185
SaveLastLog(const char * logDir,struct ErrorInfo * info)186 static int SaveLastLog(const char *logDir, struct ErrorInfo *info)
187 {
188 #ifdef LOSCFG_FS_VFS
189 struct FaultLogInfo *pLogInfo = NULL;
190
191 if (logDir == NULL || info == NULL) {
192 BBOX_PRINT_ERR("logDir: %p, info: %p!\n", logDir, info);
193 return -1;
194 }
195 if (g_logBuffer == NULL) {
196 BBOX_PRINT_ERR("g_logBuffer is NULL, alloc physical pages failed!\n");
197 return -1;
198 }
199
200 pLogInfo = (struct FaultLogInfo *)g_logBuffer;
201 if (memcmp(pLogInfo->flag, LOG_FLAG, strlen(LOG_FLAG)) == 0) {
202 SaveFaultLog(KERNEL_FAULT_LOG_PATH, g_logBuffer + sizeof(*pLogInfo),
203 Min(LOSCFG_BLACKBOX_LOG_SIZE - sizeof(*pLogInfo), pLogInfo->len), info);
204 }
205 (void)memset_s(g_logBuffer, LOSCFG_BLACKBOX_LOG_SIZE, 0, LOSCFG_BLACKBOX_LOG_SIZE);
206 BBOX_PRINT_INFO("[%s] starts uploading event [%s]\n", info->module, info->event);
207 (void)UploadEventByFile(KERNEL_FAULT_LOG_PATH);
208 BBOX_PRINT_INFO("[%s] ends uploading event [%s]\n", info->module, info->event);
209 return 0;
210 #else
211 (VOID)logDir;
212 (VOID)info;
213 BBOX_PRINT_ERR("LOSCFG_FS_VFS isn't defined!\n");
214 return -1;
215 #endif
216 }
217
218 #ifdef LOSCFG_BLACKBOX_TEST
BBoxTest(void)219 static void BBoxTest(void)
220 {
221 struct ModuleOps ops = {
222 .module = "MODULE_TEST",
223 .Dump = NULL,
224 .Reset = NULL,
225 .GetLastLogInfo = NULL,
226 .SaveLastLog = NULL,
227 };
228
229 if (BBoxRegisterModuleOps(&ops) != 0) {
230 BBOX_PRINT_ERR("BBoxRegisterModuleOps failed!\n");
231 return;
232 }
233 BBoxNotifyError("EVENT_TEST1", "MODULE_TEST", "Test BBoxNotifyError111", 0);
234 }
235 #endif
236
OsBBoxSystemAdapterInit(void)237 int OsBBoxSystemAdapterInit(void)
238 {
239 struct ModuleOps ops = {
240 .module = MODULE_SYSTEM,
241 .Dump = Dump,
242 .Reset = Reset,
243 .GetLastLogInfo = GetLastLogInfo,
244 .SaveLastLog = SaveLastLog,
245 };
246
247 /* allocate buffer for kmsg */
248 if (AllocLogBuffer() == 0) {
249 RegisterExcInfoHook();
250 if (BBoxRegisterModuleOps(&ops) != 0) {
251 BBOX_PRINT_ERR("BBoxRegisterModuleOps failed!\n");
252 g_logBuffer = NULL;
253 return LOS_NOK;
254 }
255 } else {
256 BBOX_PRINT_ERR("AllocLogBuffer failed!\n");
257 }
258
259 #ifdef LOSCFG_BLACKBOX_TEST
260 BBoxTest();
261 #endif
262
263 return LOS_OK;
264 }
265 LOS_MODULE_INIT(OsBBoxSystemAdapterInit, LOS_INIT_LEVEL_PLATFORM);
266