• 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:  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