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: LOG MODULE
15 * Author:
16 * Create:
17 */
18 #include "log_common.h"
19 #if (USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == NO)
20 #include "tcxo.h"
21 #endif
22 #include "soc_osal.h"
23 #include "non_os.h"
24 #include "log_oam_logger.h"
25 #include "log_system_messages.h"
26 #include "log_oml_exception.h"
27 #include "log_memory_region.h"
28 #ifdef USE_CMSIS_OS
29 #ifdef USE_OSAL_INSTEAD_CMSIS
30 #include "los_sched_pri.h"
31 #else
32 #include "cmsis_os2.h"
33 #endif
34 #endif
35 #ifdef SUPPORT_DFX_PRESERVE
36 #include "preserve.h"
37 #endif
38 #include "log_buffer.h"
39 #include "log_trigger.h"
40 #ifdef SUPPORT_CONNECTIVITY
41 #include "connectivity_log.h"
42 #endif
43 #if (CORE == BT) || (CORE == CONTROL_CORE) || (CORE == SENSOR)
44 #include "log_def.h"
45 #include "log_oam_mem_query.h"
46 #include "log_oam_reg_query.h"
47 #include "log_printf.h"
48 #define LOG_MEMORY_REGION_SECTION_CORE LOG_MEMORY_REGION_SECTION_0
49 #define CORES_THIS_CORE CORES_BT_CORE
50 #elif (CORE == PROTOCOL) && defined(CHIP_CAT1) && (CHIP_CAT1 == 1)
51 #define LOG_MEMORY_REGION_SECTION_CORE LOG_MEMORY_REGION_SECTION_0
52 #define CORES_THIS_CORE CORES_PROTOCOL_CORE
53 #elif CORE == APPS
54 #include "log_oam_mem_query.h"
55 #include "log_oam_reg_query.h"
56 #if CORE_NUMS > 1
57 #define LOG_MEMORY_REGION_SECTION_CORE LOG_MEMORY_REGION_SECTION_1
58 #else
59 #define LOG_MEMORY_REGION_SECTION_CORE LOG_MEMORY_REGION_SECTION_0
60 #endif
61 #define CORES_THIS_CORE CORES_APPS_CORE
62 #elif CORE == GNSS
63 #include "log_def.h"
64 #define LOG_MEMORY_REGION_SECTION_CORE LOG_MEMORY_REGION_SECTION_3
65 #define CORES_THIS_CORE CORES_GNSS_CORE
66 #elif CORE == SECURITY
67 #include "log_def.h"
68 #define LOG_MEMORY_REGION_SECTION_CORE LOG_MEMORY_REGION_SECTION_4
69 #define CORES_THIS_CORE CORES_SEC_CORE
70 #else
71 #error "No core defined"
72 #endif
73
74 #if CORE == BT
75 #define MASS_MEMORY_REGION_SECTION_CORE MASS_MEMORY_REGION_SECTION_0
76 #elif CORE == APPS
77 #if CORE_NUMS == 1
78 #define MASS_MEMORY_REGION_SECTION_CORE MASS_MEMORY_REGION_SECTION_0
79 #else
80 #define MASS_MEMORY_REGION_SECTION_CORE MASS_MEMORY_REGION_SECTION_1
81 #endif
82 #elif CORE == GNSS
83 #define MASS_MEMORY_REGION_SECTION_CORE MASS_MEMORY_REGION_SECTION_0
84 #elif CORE == SECURITY
85 #define MASS_MEMORY_REGION_SECTION_CORE MASS_MEMORY_REGION_SECTION_0
86 #elif CORE == CONTROL_CORE
87 #define MASS_MEMORY_REGION_SECTION_CORE MASS_MEMORY_REGION_SECTION_0
88 #endif
89
90 #if CORE != APPS
91 #include "ipc.h"
92 #endif
93
94 #if CORE == BT
95 #include "log_oam_msg.h"
96 #include "log_oam_ota.h"
97 #include "log_oam_status.h"
98 #endif
99
100 #if (CORE == MASTER_BY_ALL)
101 #if SYS_DEBUG_MODE_ENABLE == YES
102 #include "dfx_feature_config.h"
103 #endif
104 #endif
105
106 #define BT_CORE_INDEX 1
107 #define GNSS_CORE_INDEX 3
108 #define SEC_CORE_INDEX 4
109
110 #ifndef DEFAULT_LOG_LEVEL
111 #define DEFAULT_LOG_LEVEL 3
112 #endif
113 /** Variable storing the number of missed messages since last time it was logged */
114 static uint32_t g_missed_messages = 0;
115 static uint32_t g_cnt_messages = 0;
116
117 /** Variable storing the current logging level */
118 static log_level_e g_log_current_level = (log_level_e)DEFAULT_LOG_LEVEL;
119
120 /* Whether need trigger log uart. */
121 static bool g_trigger_tx = false;
122 static uint16_t g_log_sn_number = 0;
123
124 #if (defined CONFIG_DFX_SUPPORT_CUSTOM_LOG) && (CONFIG_DFX_SUPPORT_CUSTOM_LOG == DFX_YES)
125 #elif CORE != APPS && !defined(IPC_NEW)
126 static bool set_log_level_action_handler(ipc_action_t message,
127 const volatile ipc_payload *payload_p, cores_t src, uint32_t id);
128 #endif
129
get_log_sn_number(void)130 uint16_t get_log_sn_number(void)
131 {
132 return g_log_sn_number++;
133 }
134
log_init(void)135 void log_init(void)
136 {
137 UNUSED(g_missed_messages);
138 log_buffer_init(LOG_MEMORY_REGION_SECTION_CORE);
139 #ifdef SUPPORT_CONNECTIVITY
140 init_log_level();
141 #endif
142 #if (USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == NO)
143 default_register_hal_exception_dump_callback();
144 #else /* USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == YES */
145 compress_log_init();
146 #endif /* end of USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG */
147
148 #if (defined CONFIG_DFX_SUPPORT_CUSTOM_LOG) && (CONFIG_DFX_SUPPORT_CUSTOM_LOG == DFX_YES)
149 #elif (CORE != APPS) && !defined(IPC_NEW)
150 UNUSED(set_log_level_action_handler);
151
152 #if (USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == NO)
153 #if SYS_DEBUG_MODE_ENABLE == YES
154 log_register_oam_msg_callback();
155 #endif /* end of SYS_DEBUG_MODE_ENABLE == YES */
156 #else /* USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == YES */
157 (void)ipc_register_handler(IPC_ACTION_SET_LOG_TIME, set_log_time_action_handler);
158 (void)ipc_register_handler(IPC_ACTION_SET_LOG_SWITCH, set_log_switch_action_handler);
159 #endif /* end of USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG */
160 (void)ipc_register_handler(IPC_ACTION_SET_LOG_LEVEL, (ipc_action_handler)set_log_level_action_handler);
161 #if SYS_DEBUG_MODE_ENABLE == YES
162
163 #endif
164 #endif
165
166 #if SYS_DEBUG_MODE_ENABLE == YES
167 #if CORE == APPS
168 log_register_oam_msg_callback();
169 #elif CORE == BT
170 (void)ipc_register_handler(IPC_ACTION_HCI_INFORM, (ipc_action_handler)get_hci_data_action_handler);
171 #endif
172 #endif
173 }
174
massdata_init(void)175 void massdata_init(void)
176 {
177 #if (USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == YES)
178 mass_buffer_init(MASS_MEMORY_REGION_SECTION_CORE);
179 #endif
180 }
181
182 #ifdef USE_CMSIS_OS
log_init_after_rtos(void)183 void log_init_after_rtos(void)
184 {
185 #if CORE == BT
186 log_oml_ota_init();
187 log_oam_status_store_init();
188 #endif
189 }
190 #endif
191
192 #if (USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == NO)
log_event_trigger(void)193 static void log_event_trigger(void)
194 {
195 #ifdef USE_CMSIS_OS
196 #ifdef USE_OSAL_INSTEAD_CMSIS
197 if (OS_SCHEDULER_ALL_ACTIVE) {
198 #else
199 if (osKernelGetState() == osKernelRunning) {
200 #endif
201 if (g_trigger_tx) {
202 log_trigger();
203 g_trigger_tx = false;
204 }
205 }
206 #else
207 if (g_trigger_tx) {
208 log_trigger();
209 g_trigger_tx = false;
210 }
211 #endif // defined USE_CMSIS_OS
212 }
213 #endif
214 void log_event(const uint8_t *buffer, uint16_t length)
215 {
216 #if (USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == NO)
217 log_ret_t lret;
218 uint32_t lb_available = 0;
219 bool was_empty = false;
220 log_buffer_header_t lb_header;
221
222 #if CORE != APPS
223 if (log_memory_is_init() != true) { return; }
224 #endif
225 if (buffer == NULL || length == 0) { return; }
226
227 uint32_t irq = osal_irq_lock();
228 lb_header.time_us = (uint32_t)uapi_tcxo_get_us();
229
230 // If missed messages pending send notification
231 /* Check if there is space for the missed message indication. */
232 lret = log_buffer_get_available_for_next_message(&lb_available);
233 if (lret != LOG_RET_OK) {
234 osal_irq_restore(irq);
235 return;
236 }
237
238 if (lb_available > length) {
239 lb_header.length = length + (uint16_t)sizeof(lb_header);
240 lb_magic_set(&lb_header);
241 // add message header to log buffer
242 log_buffer_write(&lb_header, (const uint8_t *)buffer, &was_empty);
243 if (!g_trigger_tx) {
244 g_trigger_tx = was_empty;
245 }
246 } else {
247 #if (CORE != MASTER_BY_ALL) || (CORE_NUMS == 1)
248 g_trigger_tx = true;
249 #endif
250 g_missed_messages++;
251 }
252 g_cnt_messages++;
253 osal_irq_restore(irq);
254
255 log_event_trigger();
256
257 #else /* USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == YES */
258 UNUSED(buffer);
259 UNUSED(length);
260 UNUSED(g_trigger_tx);
261 #endif /* USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG */
262 }
263
264 #if (CORE != APPS) && defined(SUPPORT_CONNECTIVITY)
265 void init_log_level(void)
266 {
267 /* Point to the share memory and clear the area */
268 log_level_config_t *log_level_config_p = (log_level_config_t *)(uintptr_t)(SYSTEM_CFG_REGION_START);
269 uint8_t index_data;
270 #if CORE == BT
271 index_data = BT_CORE_INDEX;
272 #elif CORE == GNSS
273 index_data = GNSS_CORE_INDEX;
274 #else
275 index_data = SEC_CORE_INDEX;
276 #endif
277 uint32_t mgc_log_lvl = *((uint32_t *)log_level_config_p + index_data);
278 if ((get_log_level_magic(mgc_log_lvl) != LOG_LEVEL_MAGIC)
279 || (get_real_log_level(mgc_log_lvl) >= LOG_LEVEL_MAX)
280 || (get_real_log_level(mgc_log_lvl) == LOG_LEVEL_NONE)) {
281 /* Set the log level in share memory to default values */
282 mgc_log_lvl = set_log_level_magic((uint32_t)DEFAULT_LOG_LEVEL);
283 *((uint32_t *)log_level_config_p + index_data) = mgc_log_lvl;
284 }
285
286 log_set_local_log_level((log_level_e)get_real_log_level(mgc_log_lvl));
287 }
288 #endif
289
290 /**
291 * Set local log level from system log level
292 * @return none
293 */
294 void log_set_local_log_level(log_level_e log_level)
295 {
296 g_log_current_level = log_level;
297 }
298
299 /**
300 * Get current log level
301 * @return current log level
302 */
303 log_level_e log_get_local_log_level(void)
304 {
305 return g_log_current_level;
306 }
307
308 /**
309 * Get missed messages count
310 * @return missed messages count
311 */
312 uint32_t log_get_missed_messages_count(void)
313 {
314 return g_missed_messages;
315 }
316
317 /**
318 * Get all messages count
319 * @return all messages count
320 */
321 uint32_t log_get_all_messages_count(void)
322 {
323 return g_cnt_messages;
324 }
325 #if (defined CONFIG_DFX_SUPPORT_CUSTOM_LOG) && (CONFIG_DFX_SUPPORT_CUSTOM_LOG == DFX_YES)
326 #elif (CORE != APPS) && !defined(IPC_NEW)
327 /**
328 * This handler gets called when the app core wants to set the log level of other cores
329 * @param message The IPC message
330 * @param payload_p The payload, contains the reset reason
331 * @param src The core who has just started
332 * @param id The message ID (should always be 0 - the first message after starting)
333 * @return
334 */
335 static bool set_log_level_action_handler(ipc_action_t message,
336 const volatile ipc_payload *payload_p, cores_t src, uint32_t id)
337 {
338 if (message != IPC_ACTION_SET_LOG_LEVEL) {
339 oml_pf_log_print1(LOG_BCORE_PLT_LIB_LOG, LOG_NUM_LIB_LOG, LOG_LEVEL_INFO,
340 "[INFO]:Change log level failed, message is %d", message);
341 return true;
342 }
343 UNUSED(message);
344 UNUSED(id);
345 UNUSED(src);
346
347 oml_pf_log_print1(LOG_BCORE_PLT_LIB_LOG, LOG_NUM_LIB_LOG, LOG_LEVEL_INFO, "[INFO]:Change log level to %d", \
348 payload_p->set_log_level.log_level);
349
350 (void)log_set_local_log_level((log_level_e)payload_p->set_log_level.log_level);
351
352 return true;
353 }
354 #endif
355
356 #if SYS_DEBUG_MODE_ENABLE == YES
357 void log_register_oam_msg_callback(void)
358 {
359 #if (CORE == MASTER_BY_ALL)
360 #if defined(CONFIG_DFX_SDT_MEMORY_OPERATE) && (CONFIG_DFX_SDT_MEMORY_OPERATE == DFX_YES)
361 oml_reg_register_callback();
362 oml_mem_register_callback();
363 #endif
364 #endif
365
366 #if MCU_ONLY && (CORE_NUMS > 1)
367 #if CHIP_WS53
368 #else
369 oml_btc_cmd_callback();
370 #endif
371 oml_ssi_reg_register_callback();
372 #ifdef USE_GPIO_SIMULATE_SSI
373 oml_ssi_reg32_register_callback();
374 oml_ssi_block_callback();
375 #endif
376 #endif
377 }
378 #endif /* end of SYS_DEBUG_MODE_ENABLE == YES */
379