1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 * Description: crash data
15 * Author:
16 * Create:
17 */
18
19 #include "crash_data.h"
20 #include "preserve.h"
21 #ifdef SAVE_EXC_INFO
22 #include "dfx_adapt_layer.h"
23 #if CONFIG_DFX_SUPPORT_FILE_SYSTEM == DFX_YES
24 #include "fcntl.h"
25 #include "unistd.h"
26 #include "dfx_file_operation.h"
27 #include "sys/stat.h"
28 #ifdef CFG_DRIVERS_NANDFLASH
29 #include "nandflash_config.h"
30 #endif /* CFG_DRIVERS_NANDFLASH */
31 #ifdef CFG_DRIVERS_MMC
32 #include "block.h"
33 #endif /* CFG_DRIVERS_MMC */
34 #endif /* #if CONFIG_DFX_SUPPORT_FILE_SYSTEM == DFX_YES */
35 #endif /* SAVE_EXC_INFO */
36
37 #ifdef SUPPORT_CRASH_DATA_RAM
38 #include "systick.h"
39 #include "securec.h"
40
41 #define APP_CORE_CRASH_OFFSET 0x0
42 #define BT_CORE_CRASH_OFFSET (APP_CORE_CRASH_OFFSET + 0x400)
43
44 #ifdef SAVE_EXC_INFO
45 #ifdef CFG_DRIVERS_MMC
46 #define ONE_SECTOR_SIZE 512
47 #define SECTOR_NUM 16
48 #define START_SECTOR_NUM 4445186
49 #endif
50
51 #if CONFIG_DFX_SUPPORT_FILE_SYSTEM == DFX_YES
52 static const char *g_exc_info_path = "/user/exc/exc_info.bin";
53 #else
54 #define DUMP_INFO_OFFSET 0x0
55 #endif
56 #endif /* SAVE_EXC_INFO */
57
crash_data_get_by_core(uint8_t core)58 static crash_data_t *crash_data_get_by_core(uint8_t core)
59 {
60 if (core == APPS) {
61 return (crash_data_t *)(uintptr_t)(CRASH_MEM_REGION_START + APP_CORE_CRASH_OFFSET);
62 } else if (core == BT) {
63 return (crash_data_t *)(uintptr_t)(CRASH_MEM_REGION_START + BT_CORE_CRASH_OFFSET);
64 }
65 return NULL;
66 }
67
68 #ifdef SAVE_EXC_INFO
69 #if CONFIG_DFX_SUPPORT_FILE_SYSTEM == DFX_YES
crash_data_write(const char * path,uint32_t offset,const uint8_t * buf,uint32_t size)70 int32_t crash_data_write(const char *path, uint32_t offset, const uint8_t *buf, uint32_t size)
71 {
72 int fd;
73 int ret;
74 ssize_t length;
75 fd = open(path, O_RDWR | O_CREAT, 0);
76 if (fd < 0) {
77 if (dfx_file_mkdir(path) != 0) {
78 return -1;
79 }
80 fd = open(path, O_RDWR | O_CREAT, 0);
81 if (fd < 0) {
82 return -1;
83 }
84 }
85 int file_pos = (int)lseek(fd, offset, SEEK_SET);
86 if (file_pos < 0) {
87 close(fd);
88 return -1;
89 }
90 length = write(fd, buf, size);
91 if (length < 0) {
92 close(fd);
93 return -1;
94 }
95 ret = close(fd);
96 if (ret < 0) {
97 return -1;
98 }
99 return length;
100 }
101 #endif
102 #ifdef CFG_DRIVERS_MMC
crash_data_write_emmc(void)103 errcode_t crash_data_write_emmc(void)
104 {
105 char *buffer = (char *)dfx_malloc(0, ONE_SECTOR_SIZE * SECTOR_NUM);
106 uint32_t sector_num = mmc_direct_read(0, buffer, START_SECTOR_NUM, SECTOR_NUM);
107 if (sector_num == 0) {
108 return ERRCODE_FAIL;
109 }
110 if (is_preserve_data_saved((uintptr_t)buffer)) {
111 return ERRCODE_SUCC;
112 }
113 int32_t ret = crash_data_write(g_exc_info_path, 0, (const uint8_t *)buffer, ONE_SECTOR_SIZE * SECTOR_NUM);
114 if (ret < 0) {
115 return ERRCODE_FAIL;
116 }
117 return ERRCODE_SUCC;
118 }
119 #endif
crash_data_save(void)120 errcode_t crash_data_save(void)
121 {
122 int32_t ret;
123 #if (CONFIG_DFX_SUPPORT_FILE_SYSTEM == DFX_YES) && defined(CFG_DRIVERS_MMC)
124 uint32_t len = ONE_SECTOR_SIZE * SECTOR_NUM;
125 #else
126 uint32_t len = PRESERVED_REGION_LENGTH + APP_PRESERVED_REGION_LENGTH + CRASH_MEM_REGION_LENGTH;
127 #endif
128 uint8_t *buffer = (uint8_t *)dfx_zalloc(0, len);
129 if (memcpy_s(buffer, len, (uint8_t *)(uintptr_t)PRESERVED_REGION_ORIGIN, PRESERVED_REGION_LENGTH) != EOK) {
130 dfx_free(0, buffer);
131 return ERRCODE_FAIL;
132 }
133 if (memcpy_s(buffer + PRESERVED_REGION_LENGTH, len - PRESERVED_REGION_LENGTH,
134 (uint8_t *)(uintptr_t)APP_PRESERVED_REGION_ORIGIN, APP_PRESERVED_REGION_LENGTH) != EOK) {
135 dfx_free(0, buffer);
136 return ERRCODE_FAIL;
137 }
138 if (memcpy_s(buffer + PRESERVED_REGION_LENGTH + APP_PRESERVED_REGION_LENGTH,
139 len - PRESERVED_REGION_LENGTH - APP_PRESERVED_REGION_LENGTH,
140 (uint8_t *)(uintptr_t)CRASH_MEM_REGION_START, CRASH_MEM_REGION_LENGTH) != EOK) {
141 dfx_free(0, buffer);
142 return ERRCODE_FAIL;
143 }
144 #if CONFIG_DFX_SUPPORT_FILE_SYSTEM == DFX_YES
145 #ifdef CFG_DRIVERS_NANDFLASH
146 nand_driver_init(SPEED_SLOW);
147 set_trans_type(TRANS_BY_CPU_SINGLE_LINE);
148 ret = crash_data_write(g_exc_info_path, 0, buffer, len);
149 #endif
150 #ifdef CFG_DRIVERS_MMC
151 ret = (int32_t)mmc_write_in_exception(0, buffer, START_SECTOR_NUM, SECTOR_NUM);
152 #endif
153 #else
154 ret = dfx_flash_erase(FLASH_OP_TYPE_DUMP_INFO, DUMP_INFO_OFFSET, len);
155 if (ret == ERRCODE_SUCC) {
156 ret = dfx_flash_write(FLASH_OP_TYPE_DUMP_INFO, DUMP_INFO_OFFSET, buffer, len, 0);
157 }
158 #endif /* CONFIG_DFX_SUPPORT_FILE_SYSTEM == DFX_YES */
159 dfx_free(0, buffer);
160 if (ret <= 0) {
161 return ERRCODE_FAIL;
162 }
163 memset_s((void *)(uintptr_t)(APP_PRESERVED_REGION_ORIGIN), APP_PRESERVED_REGION_LENGTH, 0,
164 APP_PRESERVED_REGION_LENGTH);
165 PRINT("save crash data done!\r\n");
166 return ERRCODE_SUCC;
167 }
168 #endif
169
crash_data_clear(void)170 void crash_data_clear(void)
171 {
172 crash_data_t *crash_data = crash_data_get_by_core(CORE);
173 memset_s(crash_data, sizeof(crash_data_t), 0, sizeof(crash_data_t));
174 crash_data->core = CORE;
175 }
176
crash_data_set_save_after_reboot(void)177 void crash_data_set_save_after_reboot(void)
178 {
179 crash_data_t *crash_data = crash_data_get_by_core(CORE);
180 crash_data->save_after_reboot = 1;
181 }
182
crash_data_set_time_s(void)183 void crash_data_set_time_s(void)
184 {
185 crash_data_t *crash_data = crash_data_get_by_core(CORE);
186 crash_data->time_s = (uint32_t)uapi_systick_get_s();
187 }
188
crash_data_get_exc_info_save(void)189 exc_info_save_t *crash_data_get_exc_info_save(void)
190 {
191 crash_data_t *crash_data = crash_data_get_by_core(CORE);
192 return &crash_data->exc_info_save;
193 }
194
crash_data_set_exc_info_save(exc_info_save_t * exc_info_save,uint16_t stack_size)195 void crash_data_set_exc_info_save(exc_info_save_t *exc_info_save, uint16_t stack_size)
196 {
197 crash_data_t *crash_data = crash_data_get_by_core(CORE);
198 memcpy_s(&crash_data->exc_info_save, EXC_INFO_SAVE_SIZE + CRASH_MAX_CALL_STACK * EXC_STACK_INFO_SIZE,
199 exc_info_save, EXC_INFO_SAVE_SIZE + stack_size * EXC_STACK_INFO_SIZE);
200 }
201
crash_data_get_exception_info(void)202 exception_info_t *crash_data_get_exception_info(void)
203 {
204 crash_data_t *crash_data = crash_data_get_by_core(CORE);
205 return &crash_data->exception_info;
206 }
207
crash_data_set_exception_info(exception_info_t * exception_info)208 void crash_data_set_exception_info(exception_info_t *exception_info)
209 {
210 crash_data_t *crash_data = crash_data_get_by_core(CORE);
211 memcpy_s(&crash_data->exception_info, sizeof(exception_info_t), exception_info, sizeof(exception_info_t));
212 }
213
crash_data_get_panic(void)214 panic_desc_t *crash_data_get_panic(void)
215 {
216 crash_data_t *crash_data = crash_data_get_by_core(CORE);
217 return &crash_data->panic;
218 }
219
crash_data_set_panic(panic_desc_t * panic)220 void crash_data_set_panic(panic_desc_t *panic)
221 {
222 crash_data_t *crash_data = crash_data_get_by_core(CORE);
223 memcpy_s(&crash_data->panic, sizeof(panic_desc_t), panic, sizeof(panic_desc_t));
224 }
225 #endif /* SUPPORT_CRASH_DATA_RAM */
226