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