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: BT CPU UTILS Module
15 * Author:
16 * Create:
17 */
18
19 #include "cpu_utils.h"
20 #if defined(SUPPORT_IPC)
21 #include "ipc_actions.h"
22 #include "ipc.h"
23 #elif defined(IPC_NEW)
24 #include "ipc.h"
25 #include "ipc_porting.h"
26 #endif
27 #ifdef SUPPORT_CPU_TRACE
28 #include "cpu_trace.h"
29 #endif
30 #include "chip_io.h"
31 #include "debug_print.h"
32 #include "non_os_reboot.h"
33 #include "hal_reboot.h"
34 #include "preserve.h"
35 #ifdef SUPPORT_PARTITION_INFO
36 #include "partition.h"
37 #endif
38 #include "preserve.h"
39 #if EXCEPTION_TEST_ENABLE == YES
40 #include "non_os.h"
41 #endif
42 #if defined(BUILD_APPLICATION_STANDARD) && (USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == NO)
43 #include "log_def_pf.h"
44 #include "diag_log.h"
45 #endif
46 #ifdef SUPPORT_CRASH_DATA_RAM
47 #include "crash_data.h"
48 #endif
49 #if MCU_ONLY && defined(USE_CMSIS_OS)
50 #include "log_oml_exception.h"
51 #endif
52
53 #if MCU_ONLY
54 static cpu_utils_reboot_cb g_reboot_mcu_cb = NULL;
55 #endif
56
cpu_utils_set_system_status_by_cause(reboot_cause_t cause)57 void cpu_utils_set_system_status_by_cause(reboot_cause_t cause)
58 {
59 #if (CORE == MASTER_BY_ALL)
60 set_cpu_utils_reset_cause(cause);
61 set_cpu_utils_system_boot_magic();
62 #else
63 UNUSED(cause);
64 #endif
65 }
66
cpu_utils_reset_chip_with_log(cores_t core,reboot_cause_t cause)67 void cpu_utils_reset_chip_with_log(cores_t core, reboot_cause_t cause)
68 {
69 #if defined(BUILD_APPLICATION_STANDARD) && (USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == NO)
70 PRINT("Reboot core:%d cause 0x%x", core, cause);
71 #endif
72 UNUSED(core);
73 UNUSED(cause);
74
75 #if (CORE == MASTER_BY_ALL)
76 set_update_reset_cause_on_boot(false);
77 #endif
78 cpu_utils_set_system_status_by_cause(cause);
79 #if (WAIT_APPS_DUMP_FOREVER == NO)
80 hal_reboot_chip();
81 #endif
82 }
83
cpu_utils_reset_chip_with_cause(reboot_cause_t cause)84 void cpu_utils_reset_chip_with_cause(reboot_cause_t cause)
85 {
86 #if (CORE == MASTER_BY_ALL)
87 set_update_reset_cause_on_boot(false);
88 #endif
89 cpu_utils_set_system_status_by_cause(cause);
90 hal_reboot_chip();
91 }
92
cpu_utils_sec_rebooted(void)93 static inline void cpu_utils_sec_rebooted(void)
94 {
95 #if (CORE == MASTER_BY_ALL)
96 if (get_update_reset_cause_on_boot()) {
97 set_cpu_utils_reset_cause(reboot_get_security_reboot_reason());
98 }
99 #endif
100 }
101
102 #if EXCEPTION_TEST_ENABLE == YES && defined(SUPPORT_IPC)
exception_test_handler(ipc_action_t message,const volatile ipc_payload * payload_p,cores_t src,uint32_t id)103 static bool exception_test_handler(ipc_action_t message, const volatile ipc_payload *payload_p,
104 cores_t src, uint32_t id)
105 {
106 UNUSED(message);
107 UNUSED(src);
108 UNUSED(id);
109
110 uint16_t exception_cause = payload_p->exception_test_cmd.command;
111 volatile uint16_t i = true;
112 switch (exception_cause) {
113 case EXCEPTION_TEST_COMMAND_BT_WDT_REBOOT:
114 case EXCEPTION_TEST_COMMAND_GNSS_WDT_REBOOT:
115 while (i == true) {}
116 break;
117 case EXCEPTION_TEST_COMMAND_BT_HARDFAULT:
118 case EXCEPTION_TEST_COMMAND_GNSS_HARDFAULT:
119 // tscancode-suppress *
120 writel(0xFFFFFFFF, 0xFF);
121 break;
122 case EXCEPTION_TEST_COMMAND_BT_PANIC:
123 case EXCEPTION_TEST_COMMAND_GNSS_PANIC:
124 panic(PANIC_EXCEPTION_TEST, __LINE__);
125 break;
126 case EXCEPTION_TEST_COMMAND_BT_STD_CHIP_WDT_FRST:
127 non_os_enter_critical();
128 while (i == true) {}
129 non_os_exit_critical();
130 break;
131 default:
132 break;
133 }
134
135 return true;
136 }
137 #endif
138
exception_test_init(void)139 static void exception_test_init(void)
140 {
141 #if EXCEPTION_TEST_ENABLE == YES && defined(SUPPORT_IPC)
142 (void)ipc_register_handler(IPC_ACTION_EXCEPTION_TEST, exception_test_handler);
143 #endif
144 }
145
146 #ifdef SUPPORT_IPC
cpu_utils_sys_reboot_req(ipc_action_t message,const volatile ipc_payload * payload_p,cores_t src,uint32_t id)147 static bool cpu_utils_sys_reboot_req(ipc_action_t message, const volatile ipc_payload *payload_p,
148 cores_t src, uint32_t id)
149 {
150 UNUSED(message);
151 UNUSED(src);
152 UNUSED(id);
153 uint16_t reboot_reason = payload_p->request_reboot.requested_reboot_reason;
154 set_cpu_utils_reset_cause((reboot_cause_t)reboot_reason);
155
156 #ifdef SUPPORT_CPU_TRACE
157 cpu_trace_disable();
158 #endif
159 #if (BTH_WITH_SMART_WEAR == YES)
160 set_cpu_utils_system_boot_magic();
161 #endif
162 set_update_reset_cause_on_boot(false);
163 #if MCU_ONLY && defined(USE_CMSIS_OS)
164 log_oml_memory_dump();
165 #endif
166 #if MCU_ONLY
167 if (g_reboot_mcu_cb != NULL) { // when registering g_reboot_mcu_cb, need to restart chip by yourself.
168 g_reboot_mcu_cb(src);
169 return true;
170 }
171 #if (defined(SUPPORT_CRASH_DATA_RAM) && defined(SAVE_EXC_INFO))
172 crash_data_save();
173 #endif
174
175 #endif
176 cpu_utils_reset_chip_with_log(src, (reboot_cause_t)reboot_reason);
177
178 return true;
179 }
180 #elif defined(IPC_NEW)
cpu_utils_sys_reboot_req(uint8_t * payload_addr,uint32_t payload_len)181 static void cpu_utils_sys_reboot_req(uint8_t *payload_addr, uint32_t payload_len)
182 {
183 UNUSED(payload_len);
184 req_reboot_msg *msg = (req_reboot_msg *)payload_addr;
185 uint16_t reboot_reason = msg->req_reboot_reason;
186 cores_t src = (cores_t)msg->core;
187 set_cpu_utils_reset_cause((reboot_cause_t)reboot_reason);
188 #ifdef SUPPORT_CPU_TRACE
189 cpu_trace_disable();
190 #endif
191 #if (BTH_WITH_SMART_WEAR == YES)
192 set_cpu_utils_system_boot_magic();
193 #endif
194 set_update_reset_cause_on_boot(false);
195 #if MCU_ONLY && defined(USE_CMSIS_OS)
196 log_oml_memory_dump();
197 #endif
198 #if MCU_ONLY
199 if (g_reboot_mcu_cb != NULL) { // when registering g_reboot_mcu_cb, need to restart chip by yourself.
200 g_reboot_mcu_cb(src);
201 return;
202 }
203 #endif
204 cpu_utils_reset_chip_with_log(src, (reboot_cause_t)reboot_reason);
205 }
206 #endif
207
cpu_utils_init(void)208 void cpu_utils_init(void)
209 {
210 cpu_utils_sec_rebooted();
211 set_update_reset_cause_on_boot(true);
212 #ifdef SUPPORT_IPC
213 (void)ipc_register_handler(IPC_ACTION_SYS_REBOOT_REQ, cpu_utils_sys_reboot_req);
214 #elif defined(IPC_NEW)
215 ipc_rx_handler_info_t handler_info = {0};
216 handler_info.msg_id = IPC_MSG_SYS_REBOOT_REQ;
217 handler_info.cb = cpu_utils_sys_reboot_req;
218 uapi_ipc_register_rx_handler(&handler_info);
219 #endif
220 exception_test_init();
221 }
222
cpu_utils_core_images_to_cores(core_images_e cimage)223 cores_t cpu_utils_core_images_to_cores(core_images_e cimage)
224 {
225 switch (cimage) {
226 case (CORE_IMAGES_BT):
227 case (CORE_IMAGES_RECOVERY):
228 return CORES_BT_CORE;
229 case (CORE_IMAGES_PROTOCOL):
230 return CORES_PROTOCOL_CORE;
231 case (CORE_IMAGES_APPS):
232 return CORES_APPS_CORE;
233 #if CORE_NUMS >= 2 && CORE_NUMS < 5
234 case (CORE_IMAGES_EXTERN0):
235 return CORES_EXTERN0_CORE;
236 #elif CORE_NUMS >= 5
237 case (CORE_IMAGES_EXTERN0):
238 return CORES_EXTERN0_CORE;
239 case (CORE_IMAGES_EXTERN1):
240 case (CORE_IMAGES_EXTERN1_SSB):
241 return CORES_EXTERN1_CORE;
242 #endif
243 default:
244 return CORES_UNKNOWN;
245 }
246 }
247
cpu_utils_set_mcu_callback(cpu_utils_reboot_cb cb)248 void cpu_utils_set_mcu_callback(cpu_utils_reboot_cb cb)
249 {
250 #if MCU_ONLY
251 if (cb != NULL) {
252 g_reboot_mcu_cb = cb;
253 }
254 #else
255 UNUSED(cb);
256 #endif
257 }
258
259 #ifdef SUPPORT_PARTITION_INFO
cpu_utils_core_iamge_to_partition_id(core_images_e cimage)260 partition_ids_t cpu_utils_core_iamge_to_partition_id(core_images_e cimage)
261 {
262 switch (cimage) {
263 case (CORE_IMAGES_BT):
264 return PARTITION_BT_IMAGE;
265 case (CORE_IMAGES_APPS):
266 return PARTITION_ACPU_IMAGE;
267 case (CORE_IMAGES_PROTOCOL):
268 return PARTITION_DSP0_IMAGE;
269 case (CORE_IMAGES_EXTERN0):
270 return PARTITION_DSP1_IMAGE;
271 case (CORE_IMAGES_RECOVERY):
272 return PARTITION_FOTA_DATA;
273 default:
274 return PARTITION_MAX_CNT;
275 }
276 }
277 #endif