1 /*
2 * Copyright (c) 2021 Bestechnic (Shanghai) Co., Ltd. All rights reserved.
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 */
15 #if !(defined(DEBUG) || defined(REL_TRACE_ENABLE))
16 // Implement a local copy of dummy trace functions for library linking (which might be built with DEBUG enabled)
17 #define TRACE_FUNC_SPEC
18 #endif
19 #include "hal_trace.h"
20 #include "cmsis_nvic.h"
21 #ifdef RTOS
22 #include "cmsis_os.h"
23 #endif
24 #include "hal_bootmode.h"
25 #include "hal_cmu.h"
26 #include "hal_chipid.h"
27 #include "hal_codec.h"
28 #include "hal_dma.h"
29 #include "hal_iomux.h"
30 #include "hal_location.h"
31 #include "hal_memsc.h"
32 #include "hal_sysfreq.h"
33 #include "hal_timer.h"
34 #include "hal_uart.h"
35 #include "pmu.h"
36 #include "stdarg.h"
37 #include "stdio.h"
38 #include "string.h"
39
40 #ifdef CORE_DUMP
41 #include "CrashCatcherApi.h"
42 #endif
43
44 #if (defined(CHIP_BEST2001) || defined(CHIP_BEST2003)) && !defined(PROGRAMMER)
45 #include "transq_msg.h"
46 #ifdef __ARM_ARCH_ISA_ARM
47 #include "mcu_audio.h"
48 #endif
49 #endif
50
51 #if defined(NUTTX_BUILD)
52 #undef CP_BUILD
53 #undef CP_BOOT
54 #endif
55
56 #if defined(CP_BOOT) || defined(CP_BUILD)
57 #include "cp_ipc.h"
58 #endif
59
60 extern const char sys_build_info[];
61
62 #ifdef FAULT_DUMP
63 void hal_trace_fault_dump(const uint32_t *regs, const uint32_t *extra, uint32_t extra_len);
64 #ifndef __ARM_ARCH_ISA_ARM
65 static void hal_trace_fault_handler(void);
66 #endif
67 #endif
68
69 #if (!(defined(ROM_BUILD) || defined(PROGRAMMER))) || defined(ROM_IN_FLASH) || defined(PROGRAMMER_INFLASH)
70 #define ASSERT_VERBOSE_DUMP
71 #endif
72
73 #if !(defined(ROM_BUILD) || defined(PROGRAMMER))
74 #define ASSERT_MUTE_CODEC
75 #define CRASH_DUMP_ENABLE
76 #if !(defined(NO_TRACE_TIME_STAMP) || defined(AUDIO_DEBUG))
77 #define TRACE_TIME_STAMP
78 #endif
79 #if (defined(DUMP_LOG_ENABLE) || defined(DUMP_CRASH_LOG) || defined(RESUME_MUSIC_AFTER_CRASH_REBOOT))
80 #define TRACE_TO_APP
81 #endif
82 #if defined(CHIP_HAS_CP) && !defined(CP_BOOT) && !defined(CP_BUILD) && !defined(CONFIG_SMP) && !defined(CONFIG_BES_DUALCORE_AMP) && !defined(I2C_PA_CHANNEL_SUPPORT)
83 #define CP_TRACE_ENABLE
84 #define CP_MEMSC_TIMEOUT_CHECK
85 #endif
86 #else
87 #ifdef __ARM_ARCH_ISA_ARM
88 #define TRACE_TIME_STAMP
89 #endif
90 #endif
91
92 #define TRACE_IDLE_OUTPUT 0
93
94 #ifndef TRACE_BAUD_RATE
95 #define TRACE_BAUD_RATE (921600)
96 #endif
97
98 #ifndef TRACE_BUF_SIZE
99 #define TRACE_BUF_SIZE (4 * 1024)
100 #endif
101
102 #ifdef AUDIO_DEBUG
103 // Fix baudrate and buffer size
104 #if TRACE_BAUD_RATE < 2000000
105 #undef TRACE_BAUD_RATE
106 #define TRACE_BAUD_RATE 2000000
107 #endif
108 #if TRACE_BUF_SIZE < (16 * 1024)
109 #undef TRACE_BUF_SIZE
110 #define TRACE_BUF_SIZE (16 * 1024)
111 #endif
112 #endif
113
114
115 #ifndef TRACE_PRINTF_LEN
116 #define TRACE_PRINTF_LEN (120)
117 #endif
118
119 #ifndef TRACE_DUMP_LEN
120 #define TRACE_DUMP_LEN (250)
121 #endif
122
123 #define CRASH_BUF_SIZE 100
124 #define CRASH_BUF_ATTR ALIGNED(4) USED
125
126 #ifndef TRACE_STACK_DUMP_PREV_WORD
127 #define TRACE_STACK_DUMP_PREV_WORD 16
128 #endif
129 #ifndef TRACE_STACK_DUMP_WORD
130 #define TRACE_STACK_DUMP_WORD 32
131 #endif
132 #ifndef TRACE_BACKTRACE_NUM
133 #define TRACE_BACKTRACE_NUM 20
134 #endif
135 #ifndef TRACE_BACKTRACE_SEARCH_WORD
136 #define TRACE_BACKTRACE_SEARCH_WORD 1024
137 #endif
138
139 #define STACK_DUMP_CNT_PER_LEN 4
140 #define STACK_DUMP_CNT_PREV ((TRACE_STACK_DUMP_PREV_WORD + STACK_DUMP_CNT_PER_LEN - 1) / STACK_DUMP_CNT_PER_LEN * STACK_DUMP_CNT_PER_LEN)
141 #define STACK_DUMP_CNT ((TRACE_STACK_DUMP_WORD + STACK_DUMP_CNT_PER_LEN - 1) / STACK_DUMP_CNT_PER_LEN * STACK_DUMP_CNT_PER_LEN)
142
143 #define ASSERT_STACK_ARG_WORD 8
144 #define ASSERT_STACK_RESERVED (STACK_DUMP_CNT_PREV + ASSERT_STACK_ARG_WORD)
145
146 #define TRACE_FLUSH_TIMEOUT MS_TO_TICKS(2000)
147
148 #define TRACE_NEAR_FULL_THRESH 200
149
150 #ifdef TRACE_CRLF
151 #define NEW_LINE_STR "\r\n"
152 #else
153 #define NEW_LINE_STR "\n"
154 #endif
155
156 #define HAL_TRACE_ASSERT_ID 0xBE57AAAA
157 #define HAL_TRACE_EXCEPTION_ID 0xBE57EEEE
158
159 #define TRACE_BUF_LOC SYNC_FLAGS_LOC
160
161 struct ASSERT_INFO_T {
162 uint32_t ID;
163 uint32_t CPU_ID;
164 const char *FILE;
165 const char *FUNC;
166 uint32_t LINE;
167 const char *FMT;
168 uint32_t R[15];
169 #ifndef __ARM_ARCH_ISA_ARM
170 uint32_t MSP;
171 uint32_t PSP;
172 uint32_t CONTROL;
173 #ifdef __ARM_ARCH_8M_MAIN__
174 uint32_t MSPLIM;
175 uint32_t PSPLIM;
176 #endif
177 #endif
178 };
179
180 struct EXCEPTION_INFO_T {
181 uint32_t ID;
182 uint32_t CPU_ID;
183 const uint32_t *REGS;
184 #ifdef __ARM_ARCH_ISA_ARM
185 const uint32_t *extra;
186 uint32_t extra_len;
187 #else
188 uint32_t MSP;
189 uint32_t PSP;
190 uint8_t PRIMASK;
191 uint8_t FAULTMASK;
192 uint8_t BASEPRI;
193 uint8_t CONTROL;
194 uint32_t ICSR;
195 uint32_t AIRCR;
196 uint32_t SCR;
197 uint32_t CCR;
198 uint32_t SHCSR;
199 uint32_t CFSR;
200 uint32_t HFSR;
201 uint32_t AFSR;
202 uint32_t DFSR;
203 uint32_t MMFAR;
204 uint32_t BFAR;
205 #ifdef __ARM_ARCH_8M_MAIN__
206 uint32_t MSPLIM;
207 uint32_t PSPLIM;
208 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
209 uint32_t SFSR;
210 uint32_t SFAR;
211 uint32_t MSP_NS;
212 uint32_t PSP_NS;
213 uint32_t MSPLIM_NS;
214 uint32_t PSPLIM_NS;
215 uint8_t PRIMASK_NS;
216 uint8_t FAULTMASK_NS;
217 uint8_t BASEPRI_NS;
218 uint8_t CONTROL_NS;
219 #endif
220 #endif
221 #endif
222 };
223
224 bool carsh_occurs[2]={0};
225 static CRASH_BUF_ATTR char crash_buf[CRASH_BUF_SIZE];
226
227 STATIC_ASSERT(sizeof(crash_buf) >= sizeof(((struct ASSERT_INFO_T *)0)->R), "crash_buf too small to hold assert registers");
228
229 static uint32_t g_trace_onoff = 0;
230
hal_trace_set_onoff(uint32_t onoff)231 int hal_trace_set_onoff(uint32_t onoff)
232 {
233 if (onoff < 0) {
234 return 1;
235 }
236 g_trace_onoff = onoff;
237 return 0;
238 }
239
get_hal_trace_onoff()240 static int get_hal_trace_onoff()
241 {
242 return g_trace_onoff;
243 }
244
245 #if (defined(DEBUG) || defined(REL_TRACE_ENABLE))
246
247 #if (TRACE_BUF_SIZE > 0)
248 struct HAL_TRACE_BUF_T {
249 unsigned char buf[TRACE_BUF_SIZE];
250 unsigned short wptr;
251 unsigned short rptr;
252 unsigned short discards;
253 bool sending;
254 bool in_trace;
255 bool wrapped;
256 uint8_t pause_cnt;
257 #if (TRACE_IDLE_OUTPUT == 0)
258 unsigned short sends[2];
259 #endif
260 #if defined(CRASH_DUMP_ENABLE) && defined(TRACE_TO_APP) && defined(CP_TRACE_ENABLE)
261 unsigned short app_rptr;
262 #endif
263 };
264
265 STATIC_ASSERT(TRACE_BUF_SIZE < (1 << (8 * sizeof(((struct HAL_TRACE_BUF_T *)0)->wptr))), "TRACE_BUF_SIZE is too large to fit in wptr/rptr variable");
266
267 #if (TRACE_IDLE_OUTPUT == 0)
268 static const enum HAL_DMA_PERIPH_T uart_periph[] = {
269 HAL_GPDMA_UART0_TX,
270 #if (CHIP_HAS_UART >= 2)
271 HAL_GPDMA_UART1_TX,
272 #endif
273 #if (CHIP_HAS_UART >= 3)
274 HAL_GPDMA_UART2_TX,
275 #endif
276 };
277
278 static struct HAL_DMA_CH_CFG_T dma_cfg;
279 //TRACE_BUF_LOC static struct HAL_DMA_DESC_T dma_desc[2];
280 #endif
281
282 #ifdef __ARM_ARCH_ISA_ARM
283 #ifdef A7_ALLOC_TRANSQ_BUF
284 TRACE_BUF_LOC static struct HAL_TRACE_BUF_T trace;
285 static struct HAL_TRACE_BUF_T *p_trace = &trace;
286 #else
287 static struct HAL_TRACE_BUF_T *p_trace = NULL;
288 #endif
289 #else
290 #if !defined(PROGRAMMER)
291 TRACE_BUF_LOC
292 #endif
293 static struct HAL_TRACE_BUF_T trace;
294 static struct HAL_TRACE_BUF_T *p_trace = &trace;
295 #endif
296
297 static const char discards_prefix[] = NEW_LINE_STR "LOST ";
298 static const uint32_t max_discards = 99999;
299 // 5 digits + "\r\n" = 7 chars
300 static char discards_buf[sizeof(discards_prefix) - 1 + 7];
301 static const unsigned char discards_digit_start = sizeof(discards_prefix) - 1;
302 #endif // TRACE_BUF_SIZE > 0
303
304 static const struct HAL_UART_CFG_T uart_cfg = {
305 .parity = HAL_UART_PARITY_NONE,
306 .stop = HAL_UART_STOP_BITS_1,
307 .data = HAL_UART_DATA_BITS_8,
308 .flow = HAL_UART_FLOW_CONTROL_NONE,//HAL_UART_FLOW_CONTROL_RTSCTS,
309 .tx_level = HAL_UART_FIFO_LEVEL_1_2,
310 .rx_level = HAL_UART_FIFO_LEVEL_1_2,
311 .baud = TRACE_BAUD_RATE,
312 #ifndef CP_BUILD
313 .dma_rx = true,
314 #if (TRACE_IDLE_OUTPUT == 0)
315 .dma_tx = true,
316 #else
317 .dma_tx = false,
318 #endif
319 .dma_rx_stop_on_err = false,
320 #endif
321 };
322
323 #if (TRACE_BUF_SIZE > 0) && (TRACE_IDLE_OUTPUT == 0)
324 #ifdef __ARM_ARCH_ISA_ARM
325 #ifdef A7_ALLOC_TRANSQ_BUF
326 TRACE_BUF_LOC static struct HAL_DMA_DESC_T dma_desc[2];
327 static struct HAL_DMA_DESC_T *p_dma_desc[2] = {&dma_desc[0], &dma_desc[1]};
328 #ifdef __A7_DSP_ENABLE__
329 TRACE_BUF_LOC static TRANSQ_MSG_T trace_transq_msg;
330 static TRANSQ_MSG_T *p_trace_transq_msg = &trace_transq_msg;
331 #endif
332 #else
333 static struct HAL_DMA_DESC_T *p_dma_desc[2] = {NULL, NULL};
334 static TRANSQ_MSG_T *p_trace_transq_msg = NULL;
335 #endif
336 #else
337 TRACE_BUF_LOC static struct HAL_DMA_DESC_T dma_desc[2];
338 static struct HAL_DMA_DESC_T *p_dma_desc[2] = {&dma_desc[0], &dma_desc[1]};
339 #if defined(__A7_DSP_ENABLE__)
340 TRACE_BUF_LOC static TRANSQ_MSG_T trace_transq_msg;
341 static TRANSQ_MSG_T *p_trace_transq_msg = &trace_transq_msg;
342 #endif
343 #endif
344
345 #ifdef CP_BUILD
346 static CP_IPC_MSG_HDR cpipc_trace_msg;
347 #endif
348 #endif
349 static enum HAL_TRACE_TRANSPORT_T trace_transport = HAL_TRACE_TRANSPORT_QTY;
350 static enum HAL_UART_ID_T trace_uart;
351
352 POSSIBLY_UNUSED
353 static const char newline[] = NEW_LINE_STR;
354
355 #ifdef CRASH_DUMP_ENABLE
356 static HAL_TRACE_CRASH_DUMP_CB_T crash_dump_cb_list[HAL_TRACE_CRASH_DUMP_MODULE_END];
357 static bool in_crash_dump = false;
358 #ifdef TRACE_TO_APP
359 static HAL_TRACE_APP_NOTIFY_T app_notify_cb[HAL_TRACE_APP_REG_ID_QTY];
360 static HAL_TRACE_APP_OUTPUT_T app_output_cb[HAL_TRACE_APP_REG_ID_QTY];
361 static HAL_TRACE_APP_OUTPUT_T app_crash_custom_cb = NULL;
362 static bool app_output_cb_valid = false;
363 static bool app_output_enabled =
364 #ifdef DUMP_LOG_ENABLE
365 true;
366 #else
367 false;
368 #endif
369
370 static void hal_trace_app_output_callback(const unsigned char *buf, unsigned int buf_len);
371 #endif // TRACE_TO_APP
372 #endif // CRASH_DUMP_ENABLE
373
374 #ifdef CP_TRACE_ENABLE
375 static uint8_t memsc_lock_cnt[2];
376 #ifdef CP_MEMSC_TIMEOUT_CHECK
377 static uint8_t memsc_timeout[2];
378 #endif
379 static HAL_TRACE_BUF_CTRL_T cp_buffer_cb = NULL;
380 static bool cp_buffer_cb_running;
381 #ifdef CRASH_DUMP_ENABLE
382 static HAL_TRACE_APP_NOTIFY_T cp_notify_cb = NULL;
383 #endif
384 #endif
385
386 #ifdef TRACE_GLOBAL_TAG
387 static HAL_TRACE_GLOBAL_TAG_CB_T gbl_tag_cb = NULL;
388 #endif
389
390 #ifdef AUDIO_DEBUG
391 static const char trace_head_buf[] = "[trace]";
392 #endif
393
394 static enum TR_LEVEL_T trace_max_level;
395
396 static uint32_t trace_mod_map[(TR_MODULE_QTY + 31) / 32];
397
398 #if (defined(CHIP_BEST2001) || defined(CHIP_BEST2003)) && defined(__A7_DSP_ENABLE__) && !defined(PROGRAMMER)
hal_trace_is_transq_transport(enum HAL_TRACE_TRANSPORT_T transport)399 static bool hal_trace_is_transq_transport(enum HAL_TRACE_TRANSPORT_T transport)
400 {
401 if (transport == HAL_TRACE_TRANSPORT_TRANSQ1) {
402 return true;
403 }
404 return false;
405 }
406
407 #if (TRACE_IDLE_OUTPUT == 0)
hal_trace_transq_msg_send(uint32_t addr,uint32_t len)408 static void hal_trace_transq_msg_send(uint32_t addr, uint32_t len)
409 {
410 memset(p_trace_transq_msg, 0, sizeof(TRANSQ_MSG_T));
411 p_trace_transq_msg->type = TRANSQ_MSG_TYPE_TRACE;
412 p_trace_transq_msg->pri = HAL_TRANSQ_PRI_HIGH;
413 p_trace_transq_msg->msg.trace.addr = addr;
414 p_trace_transq_msg->msg.trace.len = len;
415 transq_msg_tx(p_trace_transq_msg);
416 }
417
hal_trace_transq_send(void)418 static void hal_trace_transq_send(void)
419 {
420 uint32_t sends[2];
421 uint32_t int_state;
422
423 int_state = int_lock();
424
425 // There is a race condition if we do not check s/w flag, but only check the h/w status.
426 // [e.g., hal_gpdma_chan_busy(dma_cfg.ch)]
427 // When the DMA is done, but DMA IRQ handler is still pending due to interrupt lock
428 // or higher priority IRQ, it will have a chance to send the same content twice.
429 if (p_trace->wptr != p_trace->rptr && !p_trace->sending) {
430 p_trace->sending = true;
431
432 if (p_trace->wptr > p_trace->rptr) {
433 sends[0] = p_trace->wptr - p_trace->rptr;
434 } else {
435 sends[0] = TRACE_BUF_SIZE - p_trace->rptr;
436 }
437 p_trace->sends[0] = sends[0];
438 hal_trace_transq_msg_send((uint32_t)&p_trace->buf[p_trace->rptr], sends[0]);
439 }
440
441 int_unlock(int_state);
442 }
443
hal_trace_transq_xfer_done(void * param)444 static void hal_trace_transq_xfer_done(void *param)
445 {
446 p_trace->rptr += p_trace->sends[0];
447 if (p_trace->rptr >= TRACE_BUF_SIZE) {
448 p_trace->rptr -= TRACE_BUF_SIZE;
449 }
450 p_trace->sends[0] = 0;
451 p_trace->sends[1] = 0;
452 p_trace->sending = false;
453
454 if (p_trace->wptr != p_trace->rptr) {
455 hal_trace_transq_send();
456 }
457 }
458 #endif
459 #endif
460
461 #ifdef CP_BUILD
hal_trace_is_cpipc_transport(enum HAL_TRACE_TRANSPORT_T transport)462 static bool hal_trace_is_cpipc_transport(enum HAL_TRACE_TRANSPORT_T transport)
463 {
464 if (transport == HAL_TRACE_TRANSPORT_CPIPC) {
465 return true;
466 }
467 return false;
468 }
469
470 #if (TRACE_IDLE_OUTPUT == 0)
471 #include "reg_uart.h"
hal_trace_cp_block_send(uint32_t addr,uint32_t len)472 static void hal_trace_cp_block_send(uint32_t addr, uint32_t len)
473 {
474 int i;
475 uint8_t *ptr;
476 uint32_t int_state;
477 int_state = int_lock();
478 struct UART_T *base = (struct UART_T *)UART0_BASE;
479 ptr = (uint8_t *)addr;
480 for (i = 0; i < len; i++) {
481 while ((base->UARTFR & (1 << 5)) != 0);
482 base->UARTDR = ptr[i];
483 }
484 p_trace->rptr += p_trace->sends[0];
485 if (p_trace->rptr >= TRACE_BUF_SIZE) {
486 p_trace->rptr -= TRACE_BUF_SIZE;
487 }
488 p_trace->sends[0] = 0;
489 p_trace->sends[1] = 0;
490 p_trace->sending = false;
491 int_unlock(int_state);
492 }
hal_trace_cpipc_msg_send(uint32_t addr,uint32_t len)493 static void hal_trace_cpipc_msg_send(uint32_t addr, uint32_t len)
494 {
495 cpipc_trace_msg.id = CP_IPC_MSG_TRACE;
496 cpipc_trace_msg.len = len;
497 cpipc_trace_msg.data = (void *)addr;
498 cp_ipc_send(&cpipc_trace_msg);
499 }
hal_trace_cpipc_send(void)500 static void hal_trace_cpipc_send(void)
501 {
502 uint32_t sends[2];
503 uint32_t int_state;
504 int_state = int_lock();
505
506 // There is a race condition if we do not check s/w flag, but only check the h/w status.
507 // [e.g., hal_gpdma_chan_busy(dma_cfg.ch)]
508 // When the DMA is done, but DMA IRQ handler is still pending due to interrupt lock
509 // or higher priority IRQ, it will have a chance to send the same content twice.
510 if (p_trace->wptr != p_trace->rptr && !p_trace->sending) {
511 p_trace->sending = true;
512
513 if (p_trace->wptr > p_trace->rptr) {
514 sends[0] = p_trace->wptr - p_trace->rptr;
515 } else {
516 sends[0] = TRACE_BUF_SIZE - p_trace->rptr;
517 }
518 p_trace->sends[0] = sends[0];
519 if (carsh_occurs[1])
520 hal_trace_cp_block_send((uint32_t)&p_trace->buf[p_trace->rptr], sends[0]);
521 else
522 hal_trace_cpipc_msg_send((uint32_t)&p_trace->buf[p_trace->rptr], sends[0]);
523 }
524
525 int_unlock(int_state);
526 }
527
hal_trace_cpipc_xfer_done(void * param)528 static void hal_trace_cpipc_xfer_done(void *param)
529 {
530 p_trace->rptr += p_trace->sends[0];
531 if (p_trace->rptr >= TRACE_BUF_SIZE) {
532 p_trace->rptr -= TRACE_BUF_SIZE;
533 }
534 p_trace->sends[0] = 0;
535 p_trace->sends[1] = 0;
536 p_trace->sending = false;
537
538 if (p_trace->wptr != p_trace->rptr)
539 hal_trace_cpipc_send();
540 }
541 #endif
542 #endif
543
544 #ifdef CP_BOOT
545 #define CP_TRACE_TAG "CP:"
546 static HAL_TRACE_OUTPUT_HOOK_T _hal_trace_printf_cp_hook = NULL;
hal_trace_register_cp_hook(HAL_TRACE_OUTPUT_HOOK_T hook)547 void hal_trace_register_cp_hook(HAL_TRACE_OUTPUT_HOOK_T hook)
548 {
549 _hal_trace_printf_cp_hook = hook;
550 }
551
hal_trace_unregister_cp_hook(HAL_TRACE_OUTPUT_HOOK_T hook)552 void hal_trace_unregister_cp_hook(HAL_TRACE_OUTPUT_HOOK_T hook)
553 {
554 if (_hal_trace_printf_cp_hook == hook) {
555 _hal_trace_printf_cp_hook = NULL;
556 }
557 }
558
hal_trace_printf_cp_hook(const char * tag,const char * fmt,uint32_t len)559 int hal_trace_printf_cp_hook(const char *tag, const char *fmt, uint32_t len)
560 {
561 int ret = 0;
562 if (_hal_trace_printf_cp_hook) {
563 ret = _hal_trace_printf_cp_hook(tag, fmt, len);
564 }
565 return ret;
566 }
567
hal_trace_cpipc_recv(void * param)568 void hal_trace_cpipc_recv(void *param)
569 {
570 CP_IPC_MSG_HDR *msg = param;
571
572 if (msg && _hal_trace_printf_cp_hook &&
573 _hal_trace_printf_cp_hook(NULL, (const char *)msg->data, msg->len))
574 return;
575
576 if (msg && (get_hal_trace_onoff() == 0) ) {
577 unsigned char tag_cp[32];
578 unsigned int timestamp = (unsigned)TICKS_TO_MS(hal_sys_timer_get());
579 char len = sprintf((char *)tag_cp, "%s[%u]", CP_TRACE_TAG, timestamp);
580 REL_LOG_RAW_OUTPUT(tag_cp, len);
581 REL_LOG_RAW_OUTPUT(msg->data, msg->len);
582 }
583 }
584 #endif
585
hal_trace_is_uart_transport(enum HAL_TRACE_TRANSPORT_T transport)586 static bool hal_trace_is_uart_transport(enum HAL_TRACE_TRANSPORT_T transport)
587 {
588 if (transport == HAL_TRACE_TRANSPORT_UART0
589 #if (CHIP_HAS_UART >= 2)
590 || transport == HAL_TRACE_TRANSPORT_UART1
591 #endif
592 #if (CHIP_HAS_UART >= 3)
593 || transport == HAL_TRACE_TRANSPORT_UART2
594 #endif
595 ) {
596 return true;
597 }
598 return false;
599 }
600
601 #if (TRACE_BUF_SIZE > 0)
602 #if (TRACE_IDLE_OUTPUT)
603
hal_trace_uart_idle_send(void)604 static void hal_trace_uart_idle_send(void)
605 {
606 int i;
607 uint32_t lock;
608 unsigned short wptr, rptr;
609
610 lock = int_lock();
611 wptr = p_trace->wptr;
612 rptr = p_trace->rptr;
613 int_unlock(lock);
614
615 if (wptr == rptr) {
616 return;
617 }
618
619 if (wptr < rptr) {
620 for (i = rptr; i < TRACE_BUF_SIZE; i++) {
621 hal_uart_blocked_putc(trace_uart, p_trace->buf[i]);
622 }
623 rptr = 0;
624 }
625
626 for (i = rptr; i < wptr; i++) {
627 hal_uart_blocked_putc(trace_uart, p_trace->buf[i]);
628 }
629
630 p_trace->rptr = wptr;
631 if (p_trace->rptr >= TRACE_BUF_SIZE) {
632 p_trace->rptr -= TRACE_BUF_SIZE;
633 }
634 }
635
636 #else // TRACE_IDLE_OUTPUT
637
hal_trace_uart_send(void)638 static void hal_trace_uart_send(void)
639 {
640 uint32_t wptr, rptr;
641 uint32_t sends[2];
642 uint32_t lock;
643
644 lock = int_lock();
645
646 wptr = p_trace->wptr;
647 rptr = p_trace->rptr;
648
649 // There is a race condition if we do not check s/w flag, but only check the h/w status.
650 // [e.g., hal_dma_chan_busy(dma_cfg.ch)]
651 // When the DMA is done, but DMA IRQ handler is still pending due to interrupt lock
652 // or higher priority IRQ, it will have a chance to send the same content twice.
653 if (!p_trace->sending && wptr != rptr) {
654 p_trace->sending = true;
655
656 sends[1] = 0;
657 if (wptr > rptr) {
658 sends[0] = wptr - rptr;
659 } else {
660 sends[0] = TRACE_BUF_SIZE - rptr;
661 if (sends[0] <= HAL_DMA_MAX_DESC_XFER_SIZE) {
662 sends[1] = wptr;
663 }
664 }
665 if (sends[0] > HAL_DMA_MAX_DESC_XFER_SIZE) {
666 sends[1] = sends[0] - HAL_DMA_MAX_DESC_XFER_SIZE;
667 sends[0] = HAL_DMA_MAX_DESC_XFER_SIZE;
668 }
669 if (sends[1] > HAL_DMA_MAX_DESC_XFER_SIZE) {
670 sends[1] = HAL_DMA_MAX_DESC_XFER_SIZE;
671 }
672
673 dma_cfg.src = (uint32_t)&p_trace->buf[rptr];
674 if (sends[1] == 0) {
675 dma_cfg.src_tsize = sends[0];
676 hal_dma_init_desc(p_dma_desc[0], &dma_cfg, NULL, 1);
677 } else {
678 dma_cfg.src_tsize = sends[0];
679 hal_dma_init_desc(p_dma_desc[0], &dma_cfg, p_dma_desc[1], 0);
680
681 if (rptr + sends[0] < TRACE_BUF_SIZE) {
682 dma_cfg.src = (uint32_t)&p_trace->buf[rptr + sends[0]];
683 } else {
684 dma_cfg.src = (uint32_t)&p_trace->buf[0];
685 }
686 dma_cfg.src_tsize = sends[1];
687 hal_dma_init_desc(p_dma_desc[1], &dma_cfg, NULL, 1);
688 }
689 p_trace->sends[0] = sends[0];
690 p_trace->sends[1] = sends[1];
691
692 hal_dma_sg_start(p_dma_desc[0], &dma_cfg);
693 }
694
695 int_unlock(lock);
696 }
697
hal_trace_uart_xfer_done(uint8_t chan,uint32_t remain_tsize,uint32_t error,struct HAL_DMA_DESC_T * lli)698 static void hal_trace_uart_xfer_done(uint8_t chan, uint32_t remain_tsize, uint32_t error, struct HAL_DMA_DESC_T *lli)
699 {
700 uint32_t sends[2];
701 uint32_t lock;
702
703 lock = int_lock();
704
705 sends[0] = p_trace->sends[0];
706 sends[1] = p_trace->sends[1];
707
708 if (error) {
709 if (lli || sends[1] == 0) {
710 if (sends[0] > remain_tsize) {
711 sends[0] -= remain_tsize;
712 } else {
713 sends[0] = 0;
714 }
715 sends[1] = 0;
716 } else {
717 if (sends[1] > remain_tsize) {
718 sends[1] -= remain_tsize;
719 } else {
720 sends[1] = 0;
721 }
722 }
723 }
724
725 p_trace->rptr += sends[0] + sends[1];
726 if (p_trace->rptr >= TRACE_BUF_SIZE) {
727 p_trace->rptr -= TRACE_BUF_SIZE;
728 }
729 p_trace->sends[0] = 0;
730 p_trace->sends[1] = 0;
731 p_trace->sending = false;
732
733 if (p_trace->pause_cnt == 0) {
734 hal_trace_uart_send();
735 }
736
737 int_unlock(lock);
738 }
739
hal_trace_uart_stop_dma_send(void)740 static void hal_trace_uart_stop_dma_send(void)
741 {
742 uint32_t lock;
743 uint32_t remain;
744
745 lock = int_lock();
746
747 if (hal_dma_chan_busy(dma_cfg.ch)) {
748 hal_dma_cancel(dma_cfg.ch);
749
750 remain = hal_dma_get_sg_remain_size(dma_cfg.ch);
751
752 p_trace->rptr += remain;
753 if (p_trace->rptr >= TRACE_BUF_SIZE) {
754 p_trace->rptr -= TRACE_BUF_SIZE;
755 }
756 p_trace->sends[0] = 0;
757 p_trace->sends[1] = 0;
758 p_trace->sending = false;
759 }
760
761 int_unlock(lock);
762 }
763
764 #endif // TRACE_IDLE_OUTPUT
765
hal_trace_send(void)766 void hal_trace_send(void)
767 {
768 #ifdef CP_TRACE_ENABLE
769 if (get_cpu_id()) {
770 return;
771 }
772 #endif
773
774 if (p_trace->pause_cnt) {
775 return;
776 }
777
778 #if (defined(CHIP_BEST2001_DSP) || defined(CHIP_BEST2003_DSP)) && defined(__A7_DSP_ENABLE__) && !defined(PROGRAMMER)
779 if (hal_trace_is_transq_transport(trace_transport)) {
780 hal_trace_transq_send();
781 }
782 #endif
783
784 #ifdef CP_BUILD
785 if (hal_trace_is_cpipc_transport(trace_transport)) {
786 hal_trace_cpipc_send();
787 }
788 #endif
789
790 if (hal_trace_is_uart_transport(trace_transport)) {
791 #if (TRACE_IDLE_OUTPUT)
792 hal_trace_uart_idle_send();
793 #else
794 hal_trace_uart_send();
795 #endif
796 }
797 }
798
799 #endif // TRACE_BUF_SIZE > 0
800
hal_trace_output_linefeed(void)801 static void hal_trace_output_linefeed(void)
802 {
803 hal_trace_output((const unsigned char *)newline, sizeof(newline) - 1);
804 }
805
hal_trace_open(enum HAL_TRACE_TRANSPORT_T transport)806 int hal_trace_open(enum HAL_TRACE_TRANSPORT_T transport)
807 {
808 #if (CHIP_HAS_UART >= 2)
809 #ifdef FORCE_TRACE_UART1
810 transport = HAL_TRACE_TRANSPORT_UART1;
811 #endif
812 #endif
813
814 #if (CHIP_HAS_UART >= 3)
815 #ifdef FORCE_TRACE_UART2
816 transport = HAL_TRACE_TRANSPORT_UART2;
817 #endif
818 #endif
819
820 if (transport >= HAL_TRACE_TRANSPORT_QTY) {
821 return 1;
822 }
823 #ifdef CHIP_HAS_USB
824 if (transport == HAL_TRACE_TRANSPORT_USB) {
825 return 1;
826 }
827 #endif
828 #if !defined(CONFIG_CONSOLE_USE_CHAR)
829 if (trace_transport != HAL_TRACE_TRANSPORT_QTY) {
830 return hal_trace_switch(transport);
831 }
832
833 #if (TRACE_BUF_SIZE > 0)
834 memcpy(discards_buf, discards_prefix, discards_digit_start);
835
836 p_trace->wptr = 0;
837 p_trace->rptr = 0;
838 p_trace->discards = 0;
839 p_trace->sending = false;
840 p_trace->in_trace = false;
841 p_trace->wrapped = false;
842 p_trace->pause_cnt = 0;
843
844 #ifdef __ARM_ARCH_ISA_ARM
845 #ifdef __A7_DSP_ENABLE__
846 #if !defined(NUTTX_BUILD)
847 if (p_dma_desc[0] == NULL) {
848 p_dma_desc[0] = (struct HAL_DMA_DESC_T *)a7_dsp_heap_alloc(sizeof(struct HAL_DMA_DESC_T));
849 p_dma_desc[1] = (struct HAL_DMA_DESC_T *)a7_dsp_heap_alloc(sizeof(struct HAL_DMA_DESC_T));
850 }
851 if (p_trace_transq_msg == NULL) {
852 p_trace_transq_msg = (TRANSQ_MSG_T *)a7_dsp_heap_alloc(sizeof(TRANSQ_MSG_T));
853 }
854 #endif
855 #endif
856 #endif
857
858 if (hal_trace_is_uart_transport(transport)) {
859 int ret;
860
861 trace_uart = HAL_UART_ID_0 + (transport - HAL_TRACE_TRANSPORT_UART0);
862 ret = hal_uart_open(trace_uart, &uart_cfg);
863 if (ret) {
864 return ret;
865 }
866
867 #if (TRACE_IDLE_OUTPUT == 0)
868 if (uart_cfg.dma_tx) {
869 p_trace->sends[0] = 0;
870 p_trace->sends[1] = 0;
871 memset(&dma_cfg, 0, sizeof(dma_cfg));
872 dma_cfg.dst = 0; // useless
873 dma_cfg.dst_bsize = HAL_DMA_BSIZE_8;
874 dma_cfg.dst_periph = uart_periph[trace_uart - HAL_UART_ID_0];
875 dma_cfg.dst_width = HAL_DMA_WIDTH_BYTE;
876 dma_cfg.handler = hal_trace_uart_xfer_done;
877 dma_cfg.src_bsize = HAL_DMA_BSIZE_32;
878 dma_cfg.src_periph = 0; // useless
879 dma_cfg.src_width = HAL_DMA_WIDTH_BYTE;
880 dma_cfg.type = HAL_DMA_FLOW_M2P_DMA;
881 dma_cfg.try_burst = 0;
882 dma_cfg.ch = hal_dma_get_chan(dma_cfg.dst_periph, HAL_DMA_HIGH_PRIO);
883
884 ASSERT(dma_cfg.ch != HAL_DMA_CHAN_NONE, "Failed to get DMA channel");
885 }
886 #endif
887 }
888 #endif // TRACE_BUF_SIZE > 0
889 #endif
890
891 #if (defined(CHIP_BEST2001) || defined(CHIP_BEST2003)) && defined(__A7_DSP_ENABLE__) && !defined(PROGRAMMER) && !defined(NUTTX_BUILD)
892 if (hal_trace_is_transq_transport(transport)) {
893 transq_msg_init();
894 transq_msg_register(TRANSQ_MSG_TYPE_TRACE, hal_trace_transq_xfer_done, true);
895 }
896 #endif
897
898 #ifdef CP_BUILD
899 if (hal_trace_is_cpipc_transport(transport)) {
900 cp_ipc_cb_set(CP_IPC_MSG_TRACE, hal_trace_cpipc_xfer_done, true);
901 }
902 #endif
903
904 #ifdef CP_BOOT
905 cp_ipc_cb_set(CP_IPC_MSG_TRACE, hal_trace_cpipc_recv, 0);
906 #endif
907
908 #ifdef FAULT_DUMP
909 #ifdef __ARM_ARCH_ISA_ARM
910 GIC_SetFaultDumpHandler(hal_trace_fault_dump);
911 #elif defined(CP_BUILD)
912 NVIC_SetDefaultFaultHandler_cp(hal_trace_fault_handler);
913 #else
914 NVIC_SetDefaultFaultHandler(hal_trace_fault_handler);
915 #endif
916 #endif
917
918 #ifdef CRASH_DUMP_ENABLE
919 in_crash_dump = false;
920 #endif
921
922 trace_max_level = TR_LEVEL_INFO;
923 for (int i = 0; i < ARRAY_SIZE(trace_mod_map); i++) {
924 trace_mod_map[i] = ~0;
925 }
926 #if !defined(CONFIG_CONSOLE_USE_CHAR)
927 trace_transport = transport;
928 #else
929 trace_transport = HAL_TRACE_TRANSPORT_QTY;
930 #endif
931
932 // Show build info
933 hal_trace_output_linefeed();
934 hal_trace_output_linefeed();
935 hal_trace_output((unsigned char *)sys_build_info, strlen(sys_build_info));
936
937 #if !(defined(CHIP_SUBSYS_DSP) || \
938 defined(CHIP_SUBSYS_SENS) || \
939 (defined(CHIP_SUBSYS_BTH) && defined(BTH_AS_MAIN_MCU)))
940 char buf[50];
941 int len;
942 len = snprintf(buf, sizeof(buf),
943 NEW_LINE_STR NEW_LINE_STR "------" NEW_LINE_STR "METAL_ID: %d" NEW_LINE_STR "------" NEW_LINE_STR NEW_LINE_STR,
944 hal_get_chip_metal_id());
945 hal_trace_output((unsigned char *)buf, len);
946 #endif
947
948 return 0;
949 }
950
hal_trace_switch(enum HAL_TRACE_TRANSPORT_T transport)951 int hal_trace_switch(enum HAL_TRACE_TRANSPORT_T transport)
952 {
953 int ret = 0;
954
955 #if (CHIP_HAS_UART >= 2)
956 #ifdef FORCE_TRACE_UART1
957 transport = HAL_TRACE_TRANSPORT_UART1;
958 #endif
959 #endif
960
961 #if (CHIP_HAS_UART >= 3)
962 #ifdef FORCE_TRACE_UART2
963 transport = HAL_TRACE_TRANSPORT_UART2;
964 #endif
965 #endif
966
967 #ifdef CHIP_HAS_USB
968 if (transport == HAL_TRACE_TRANSPORT_USB) {
969 return 1;
970 }
971 #endif
972 if (transport >= HAL_TRACE_TRANSPORT_QTY) {
973 return 1;
974 }
975 if (trace_transport >= HAL_TRACE_TRANSPORT_QTY) {
976 return 1;
977 }
978 if (trace_transport == transport) {
979 return 0;
980 }
981
982 #if (CHIP_HAS_UART >= 2)
983 uint32_t lock;
984
985 lock = int_lock();
986
987 #if (TRACE_BUF_SIZE > 0)
988 if (hal_trace_is_uart_transport(trace_transport)) {
989 #if (TRACE_IDLE_OUTPUT == 0)
990 if (dma_cfg.ch != HAL_DMA_CHAN_NONE) {
991 hal_dma_cancel(dma_cfg.ch);
992 }
993 #endif
994 hal_uart_close(trace_uart);
995 }
996
997 if (hal_trace_is_uart_transport(transport)) {
998 trace_uart = HAL_UART_ID_0 + (transport - HAL_TRACE_TRANSPORT_UART0);
999 #if (TRACE_IDLE_OUTPUT == 0)
1000 if (dma_cfg.ch != HAL_DMA_CHAN_NONE)
1001 hal_dma_free_chan(dma_cfg.ch);
1002 if (uart_cfg.dma_tx) {
1003 dma_cfg.dst_periph = uart_periph[trace_uart - HAL_UART_ID_0];
1004 dma_cfg.ch = hal_dma_get_chan(dma_cfg.dst_periph, HAL_DMA_HIGH_PRIO);
1005 }
1006 p_trace->sends[0] = 0;
1007 p_trace->sends[1] = 0;
1008 #endif
1009 ret = hal_uart_open(trace_uart, &uart_cfg);
1010 if (ret) {
1011 #if (TRACE_IDLE_OUTPUT == 0)
1012 hal_dma_free_chan(dma_cfg.ch);
1013 dma_cfg.ch = HAL_DMA_CHAN_NONE;
1014 #endif
1015 trace_transport = HAL_TRACE_TRANSPORT_QTY;
1016 goto _exit;
1017 }
1018 }
1019
1020 p_trace->sending = false;
1021 #endif // TRACE_BUF_SIZE > 0
1022
1023 trace_transport = transport;
1024
1025 _exit: POSSIBLY_UNUSED;
1026 int_unlock(lock);
1027 #endif // (CHIP_HAS_UART >= 2)
1028
1029 return ret;
1030 }
1031
hal_trace_close(void)1032 int hal_trace_close(void)
1033 {
1034 #if (TRACE_BUF_SIZE > 0)
1035 if (trace_transport >= HAL_TRACE_TRANSPORT_QTY) {
1036 goto _exit;
1037 }
1038 #ifdef CHIP_HAS_USB
1039 if (trace_transport == HAL_TRACE_TRANSPORT_USB) {
1040 goto _exit;
1041 }
1042 #endif
1043
1044 if (hal_trace_is_uart_transport(trace_transport)) {
1045 #if (TRACE_IDLE_OUTPUT == 0)
1046 if (dma_cfg.ch != HAL_DMA_CHAN_NONE) {
1047 hal_dma_cancel(dma_cfg.ch);
1048 hal_dma_free_chan(dma_cfg.ch);
1049 dma_cfg.ch = HAL_DMA_CHAN_NONE;
1050 }
1051 #endif
1052 hal_uart_close(trace_uart);
1053 }
1054
1055 _exit:
1056 trace_transport = HAL_TRACE_TRANSPORT_QTY;
1057 #endif // TRACE_BUF_SIZE > 0
1058
1059 return 0;
1060 }
1061
hal_trace_get_transport(void)1062 enum HAL_TRACE_TRANSPORT_T hal_trace_get_transport(void)
1063 {
1064 #if (TRACE_BUF_SIZE > 0)
1065 return trace_transport;
1066 #else
1067 return HAL_TRACE_TRANSPORT_QTY;
1068 #endif
1069 }
1070
hal_trace_enable_log_module(enum TR_MODULE_T module)1071 int hal_trace_enable_log_module(enum TR_MODULE_T module)
1072 {
1073 if (module >= TR_MODULE_QTY) {
1074 return 1;
1075 }
1076
1077 trace_mod_map[module >> 5] |= (1 << (module & 0x1F));
1078 return 0;
1079 }
1080
hal_trace_disable_log_module(enum TR_MODULE_T module)1081 int hal_trace_disable_log_module(enum TR_MODULE_T module)
1082 {
1083 if (module >= TR_MODULE_QTY) {
1084 return 1;
1085 }
1086
1087 trace_mod_map[module >> 5] &= ~(1 << (module & 0x1F));
1088 return 0;
1089 }
1090
hal_trace_set_log_module(const uint32_t * map,uint32_t word_cnt)1091 int hal_trace_set_log_module(const uint32_t *map, uint32_t word_cnt)
1092 {
1093 if (map == NULL || word_cnt == 0) {
1094 return 1;
1095 }
1096
1097 if (word_cnt > ARRAY_SIZE(trace_mod_map)) {
1098 word_cnt = ARRAY_SIZE(trace_mod_map);
1099 }
1100 for (int i = 0; i < word_cnt; i++) {
1101 trace_mod_map[i] = map[i];
1102 }
1103 return 0;
1104 }
1105
hal_trace_set_log_level(enum TR_LEVEL_T level)1106 int hal_trace_set_log_level(enum TR_LEVEL_T level)
1107 {
1108 if (level >= TR_LEVEL_QTY) {
1109 return 1;
1110 }
1111
1112 trace_max_level = level;
1113 return 0;
1114 }
1115
hal_trace_get_history_buffer(const uint8_t ** buf1,uint32_t * len1,const uint8_t ** buf2,uint32_t * len2)1116 void hal_trace_get_history_buffer(const uint8_t **buf1, uint32_t *len1, const uint8_t **buf2, uint32_t *len2)
1117 {
1118 uint8_t *b1, *b2;
1119 uint32_t l1, l2;
1120
1121 b1 = b2 = NULL;
1122 l1 = l2 = 0;
1123
1124 #if (TRACE_BUF_SIZE > 0)
1125 uint32_t lock;
1126
1127 lock = int_lock();
1128
1129 if (TRACE_BUF_SIZE > p_trace->wptr) {
1130 if (p_trace->wrapped) {
1131 b1 = &p_trace->buf[p_trace->wptr];
1132 l1 = TRACE_BUF_SIZE - p_trace->wptr;
1133 b2 = &p_trace->buf[0];
1134 l2 = p_trace->wptr;
1135 } else {
1136 b1 = &p_trace->buf[0];
1137 l1 = p_trace->wptr;
1138 b2 = NULL;
1139 l2 = 0;
1140 }
1141 }
1142
1143 int_unlock(lock);
1144 #endif
1145
1146 if (buf1) {
1147 *buf1 = b1;
1148 }
1149 if (len1) {
1150 *len1 = l1;
1151 }
1152 if (buf2) {
1153 *buf2 = b2;
1154 }
1155 if (len2) {
1156 *len2 = l2;
1157 }
1158 }
1159
hal_trace_print_unsigned(char * buf,uint32_t len,uint32_t val)1160 static uint32_t hal_trace_print_unsigned(char *buf, uint32_t len, uint32_t val)
1161 {
1162 const uint8_t base = 10;
1163 char digit[10];
1164 char *d;
1165 uint32_t cnt = 0;
1166
1167 if (len == 0) {
1168 return 0;
1169 }
1170
1171 d = &digit[0];
1172 do {
1173 *d++ = (val % base) + '0';
1174 } while (val /= base);
1175
1176 do {
1177 *buf++ = *--d;
1178 if (++cnt >= len) {
1179 break;
1180 }
1181 } while (d > &digit[0]);
1182
1183 return cnt;
1184 }
1185
1186 #if (TRACE_BUF_SIZE > 0)
hal_trace_print_discards(uint32_t discards)1187 static void hal_trace_print_discards(uint32_t discards)
1188 {
1189 char *out;
1190 uint16_t len;
1191 uint16_t size;
1192
1193 if (discards > max_discards) {
1194 discards = max_discards;
1195 }
1196
1197 len = hal_trace_print_unsigned(&discards_buf[discards_digit_start], 5, discards);
1198 out = &discards_buf[discards_digit_start + len];
1199 #ifdef TRACE_CRLF
1200 *out++ = '\r';
1201 #endif
1202 *out++ = '\n';
1203 len = out - &discards_buf[0];
1204
1205 size = TRACE_BUF_SIZE - p_trace->wptr;
1206 if (size >= len) {
1207 size = len;
1208 }
1209 memcpy(&p_trace->buf[p_trace->wptr], &discards_buf[0], size);
1210 if (size < len) {
1211 memcpy(&p_trace->buf[0], &discards_buf[size], len - size);
1212 }
1213 p_trace->wptr += len;
1214 if (p_trace->wptr >= TRACE_BUF_SIZE) {
1215 p_trace->wptr -= TRACE_BUF_SIZE;
1216 }
1217 }
1218 #endif
1219
1220 #ifdef AUDIO_DEBUG
hal_trace_print_head(void)1221 static void hal_trace_print_head(void)
1222 {
1223 uint16_t len;
1224 uint16_t size;
1225
1226 len = sizeof(trace_head_buf) - 1;
1227
1228 size = TRACE_BUF_SIZE - p_trace->wptr;
1229 if (size >= len) {
1230 size = len;
1231 }
1232 memcpy(&p_trace->buf[p_trace->wptr], &trace_head_buf[0], size);
1233 if (size < len) {
1234 memcpy(&p_trace->buf[0], &trace_head_buf[size], len - size);
1235 }
1236 p_trace->wptr += len;
1237 if (p_trace->wptr >= TRACE_BUF_SIZE) {
1238 p_trace->wptr -= TRACE_BUF_SIZE;
1239 }
1240 }
1241 #endif
1242
1243 #ifdef CP_TRACE_ENABLE
hal_trace_cp_lock(uint8_t cpu_id)1244 static void hal_trace_cp_lock(uint8_t cpu_id)
1245 {
1246 // Avoid CPU hangup when the function is re-entered due to hal_trace_app_output_callback()
1247 #ifdef CP_MEMSC_TIMEOUT_CHECK
1248 uint32_t start_time;
1249 const uint32_t timeout = MS_TO_TICKS(500);
1250
1251 if (memsc_lock_cnt[cpu_id] == 0 && memsc_timeout[cpu_id] == 0) {
1252 start_time = hal_sys_timer_get();
1253 while (hal_memsc_lock(HAL_MEMSC_ID_TRACE) == 0) {
1254 if (hal_sys_timer_get() - start_time >= timeout) {
1255 memsc_timeout[cpu_id] = 1;
1256 break;
1257 }
1258 }
1259 }
1260 #else
1261 if (memsc_lock_cnt[cpu_id] == 0) {
1262 while (hal_memsc_lock(HAL_MEMSC_ID_TRACE) == 0);
1263 }
1264 #endif
1265 memsc_lock_cnt[cpu_id]++;
1266 }
1267
hal_trace_cp_unlock(uint8_t cpu_id)1268 static void hal_trace_cp_unlock(uint8_t cpu_id)
1269 {
1270 memsc_lock_cnt[cpu_id]--;
1271 if (memsc_lock_cnt[cpu_id] == 0) {
1272 hal_memsc_unlock(HAL_MEMSC_ID_TRACE);
1273 }
1274 }
1275
hal_trace_cp_force_unlock(void)1276 static void hal_trace_cp_force_unlock(void)
1277 {
1278 uint8_t cpu_id = get_cpu_id() ? 1 : 0;
1279
1280 if (memsc_lock_cnt[cpu_id]) {
1281 memsc_lock_cnt[cpu_id] = 0;
1282 hal_memsc_unlock(HAL_MEMSC_ID_TRACE);
1283 }
1284 }
1285 #endif
1286
1287 static HAL_TRACE_OUTPUT_HOOK_T _hal_trace_output_hook = NULL;
hal_trace_register_hook(HAL_TRACE_OUTPUT_HOOK_T hook)1288 void hal_trace_register_hook(HAL_TRACE_OUTPUT_HOOK_T hook)
1289 {
1290 _hal_trace_output_hook = hook;
1291 }
1292
hal_trace_unregister_hook(HAL_TRACE_OUTPUT_HOOK_T hook)1293 void hal_trace_unregister_hook(HAL_TRACE_OUTPUT_HOOK_T hook)
1294 {
1295 if (_hal_trace_output_hook == hook) {
1296 _hal_trace_output_hook = NULL;
1297 }
1298 }
1299
hal_trace_output_hook(const char * tag,const char * fmt,uint32_t len)1300 int hal_trace_output_hook(const char *tag, const char *fmt, uint32_t len)
1301 {
1302 int ret = 0;
1303 if (_hal_trace_output_hook) {
1304 ret = _hal_trace_output_hook(tag, fmt, len);
1305 }
1306 return ret;
1307 }
1308
1309 bool crash_occurs[2];
hal_trace_output(const unsigned char * buf,unsigned int buf_len)1310 int hal_trace_output(const unsigned char *buf, unsigned int buf_len)
1311 {
1312 int ret;
1313 uint32_t lock;
1314 POSSIBLY_UNUSED uint32_t app_wptr = 0;
1315 #ifdef CP_TRACE_ENABLE
1316 uint8_t cpu_id = get_cpu_id() ? 1 : 0;
1317 #endif
1318 #if defined(NUTTX_BUILD)
1319 #ifdef CP_TRACE_ENABLE
1320 if (cpu_id == 0 && !hal_trace_is_uart_transport(trace_transport))
1321 #else
1322 if (!hal_trace_is_uart_transport(trace_transport))
1323 #endif
1324 {
1325 #ifdef __ARM_ARCH_ISA_ARM
1326 #if defined(CONFIG_BES_LPUART)
1327 hal_uart_output(buf,buf_len);
1328 #else
1329 syslog(LOG_ERR,"%s\n",buf);
1330 #endif
1331 #else
1332 hal_uart_output(buf,buf_len);
1333 #endif
1334 return buf_len;
1335 }
1336 #endif
1337
1338 #ifdef CP_BUILD
1339 if (hal_trace_is_uart_transport(trace_transport)) {
1340 hal_uart_output(buf,buf_len);
1341 return buf_len;
1342 } else if (crash_occurs[1]) {
1343 /* exec trace redirect to uart0 */
1344 for (int i = 0; i < buf_len; i++) {
1345 hal_uart_blocked_putc(HAL_UART_ID_0, buf[i]);
1346 }
1347 return buf_len;
1348 }
1349 #endif
1350
1351 /* output trace by hook */
1352 if (hal_trace_output_hook(NULL, (const char *)buf, buf_len)) {
1353 return buf_len;
1354 }
1355
1356 ret = 0;
1357
1358 lock = int_lock();
1359
1360 #ifdef CP_TRACE_ENABLE
1361 hal_trace_cp_lock(cpu_id);
1362 #endif
1363
1364 #if (TRACE_BUF_SIZE > 0)
1365 // Avoid troubles when NMI occurs during trace
1366 if (!p_trace->in_trace) {
1367 uint32_t avail;
1368 uint32_t out_len;
1369 uint16_t size;
1370
1371 p_trace->in_trace = true;
1372
1373 if (p_trace->wptr >= p_trace->rptr) {
1374 avail = TRACE_BUF_SIZE - (p_trace->wptr - p_trace->rptr) - 1;
1375 } else {
1376 avail = (p_trace->rptr - p_trace->wptr) - 1;
1377 }
1378
1379 out_len = buf_len;
1380 #ifdef AUDIO_DEBUG
1381 out_len += sizeof(trace_head_buf) - 1;
1382 #endif
1383 if (p_trace->discards) {
1384 out_len += sizeof(discards_buf);
1385 }
1386
1387 if (avail < out_len) {
1388 ret = 1;
1389 if (p_trace->discards < (1 << (sizeof(p_trace->discards) * 8)) - 1) {
1390 p_trace->discards++;
1391 }
1392 #ifdef CP_TRACE_ENABLE
1393 #if (TRACE_IDLE_OUTPUT == 0)
1394 // CP might have filled up the whole buffer
1395 hal_trace_send();
1396 #endif
1397 #endif
1398 } else {
1399 #ifdef AUDIO_DEBUG
1400 hal_trace_print_head();
1401 #endif
1402
1403 if (p_trace->discards) {
1404 hal_trace_print_discards(p_trace->discards);
1405 p_trace->discards = 0;
1406 }
1407
1408 size = TRACE_BUF_SIZE - p_trace->wptr;
1409 if (size >= buf_len) {
1410 size = buf_len;
1411 }
1412 memcpy(&p_trace->buf[p_trace->wptr], &buf[0], size);
1413 if (size < buf_len) {
1414 memcpy(&p_trace->buf[0], &buf[size], buf_len - size);
1415 }
1416 p_trace->wptr += buf_len;
1417 if (p_trace->wptr >= TRACE_BUF_SIZE) {
1418 p_trace->wptr -= TRACE_BUF_SIZE;
1419 p_trace->wrapped = true;
1420 }
1421 #if (TRACE_IDLE_OUTPUT == 0)
1422 hal_trace_send();
1423 #endif
1424 }
1425
1426 p_trace->in_trace = false;
1427
1428 #ifdef CP_TRACE_ENABLE
1429 if (cpu_id) {
1430 if (cp_buffer_cb && !cp_buffer_cb_running) {
1431 cp_buffer_cb_running = true;
1432 if (avail < out_len) {
1433 cp_buffer_cb(HAL_TRACE_BUF_STATE_FULL);
1434 } else if (avail - out_len < TRACE_NEAR_FULL_THRESH) {
1435 cp_buffer_cb(HAL_TRACE_BUF_STATE_NEAR_FULL);
1436 }
1437 cp_buffer_cb_running = false;
1438 }
1439 } else {
1440 app_wptr = p_trace->wptr;
1441 }
1442 #endif
1443 }
1444 #endif // TRACE_BUF_SIZE > 0
1445
1446 #ifdef CP_TRACE_ENABLE
1447 hal_trace_cp_unlock(cpu_id);
1448 #endif
1449
1450 #ifdef CRASH_DUMP_ENABLE
1451 #ifdef TRACE_TO_APP
1452 bool app_output;
1453
1454 app_output = app_output_cb_valid && app_output_enabled;
1455 #ifdef CP_TRACE_ENABLE
1456 if (cpu_id) {
1457 app_output = false;
1458 }
1459 #endif
1460
1461 if (app_output) {
1462 app_output_enabled = false;
1463 #if defined(CP_TRACE_ENABLE) && (TRACE_BUF_SIZE > 0)
1464 if (app_wptr < p_trace->app_rptr) {
1465 hal_trace_app_output_callback(&p_trace->buf[p_trace->app_rptr], TRACE_BUF_SIZE - p_trace->app_rptr);
1466 p_trace->app_rptr = 0;
1467 }
1468 if (app_wptr > p_trace->app_rptr) {
1469 hal_trace_app_output_callback(&p_trace->buf[p_trace->app_rptr], app_wptr - p_trace->app_rptr);
1470 p_trace->app_rptr = app_wptr;
1471 }
1472 #else
1473 hal_trace_app_output_callback(buf, buf_len);
1474 #endif
1475 app_output_enabled = true;
1476 }
1477 #endif
1478 #endif
1479
1480 #if defined(CP_TRACE_ENABLE) && defined(CP_MEMSC_TIMEOUT_CHECK)
1481 if (memsc_timeout[cpu_id] == 1) {
1482 memsc_timeout[cpu_id] = 2;
1483 ASSERT(false, "TRACE-%u: Wait memsc timeout", cpu_id);
1484 }
1485 #endif
1486
1487 int_unlock(lock);
1488
1489 return ret ? 0 : buf_len;
1490 }
1491
hal_raw_trace_output(const unsigned char * buf,unsigned int buf_len)1492 int hal_raw_trace_output(const unsigned char *buf, unsigned int buf_len)
1493 {
1494 if (get_hal_trace_onoff() == 1)
1495 {
1496 return 0;
1497 }
1498 return hal_trace_output(buf, buf_len);
1499 }
1500
1501 #ifdef USE_TRACE_ID
1502 //#define USE_CRC_CHECK
1503 //#define LITE_VERSION
1504
1505 #define TRACE_ID_MAX_ARG_NUM 15
1506
1507 typedef struct {
1508 uint32_t crc:6;
1509 uint32_t count:4;
1510 uint32_t tskid:5;
1511 uint32_t rfu:17; //!< reserved for future use
1512 uint32_t addr; //!< enough for trace string address
1513 }trace_info_t;
1514
1515 typedef struct {
1516 uint32_t crc:8;
1517 uint32_t timestamp:24; // 4 hours support
1518 }trace_head_t;
1519
1520 typedef struct {
1521 #ifndef LITE_VERSION
1522 trace_head_t trace_head;
1523 #endif
1524 trace_info_t trace_info;
1525 }__attribute__((packed)) LOG_DATA_T;
1526
1527 struct PACKED LOG_BODY_T {
1528 LOG_DATA_T hdr;
1529 uint32_t arg[TRACE_ID_MAX_ARG_NUM];
1530 };
1531
1532 extern uint32_t __trc_str_start__[];
1533 extern uint32_t __trc_str_end__[];
1534
crc8(uint8_t * data,uint32_t length)1535 uint8_t crc8(uint8_t *data, uint32_t length)
1536 {
1537 uint8_t i;
1538 uint8_t crc = 0; // Initial value
1539 while(length--)
1540 {
1541 crc ^= *data++; // crc ^= *data; data++;
1542 for ( i = 0; i < 8; i++ )
1543 {
1544 if ( crc & 0x80 )
1545 crc = (crc << 1) ^ 0x07;
1546 else
1547 crc <<= 1;
1548 }
1549 }
1550 return crc;
1551 }
1552
crc6(uint8_t * data,uint32_t length)1553 uint8_t crc6(uint8_t *data, uint32_t length)
1554 {
1555 uint8_t i;
1556 uint8_t crc = 0; // Initial value
1557 while(length--)
1558 {
1559 crc ^= *data++; // crc ^= *data; data++;
1560 for (i = 0; i < 8; ++i)
1561 {
1562 if (crc & 1)
1563 crc = (crc >> 1) ^ 0x30;// 0x30 = (reverse 0x03)>>(8-6)
1564 else
1565 crc = (crc >> 1);
1566 }
1567 }
1568 return crc;
1569 }
1570
1571
hal_trace_format_id(uint32_t attr,struct LOG_BODY_T * log,const char * fmt,va_list ap)1572 static int hal_trace_format_id(uint32_t attr, struct LOG_BODY_T *log, const char *fmt, va_list ap)
1573 {
1574 uint8_t num;
1575
1576 num = GET_BITFIELD(attr, TR_ATTR_ARG_NUM);
1577 if (num > TRACE_ID_MAX_ARG_NUM) {
1578 num = TRACE_ID_MAX_ARG_NUM;
1579 }
1580 for (int i = 0; i < num; i++) {
1581 log->arg[i] = va_arg(ap, unsigned long);
1582 }
1583
1584 log->hdr.trace_info.count = num;
1585 log->hdr.trace_info.addr = (uint32_t)fmt-(uint32_t)0xFFFC0000; //(uint32_t)fmt-(uint32_t)__trc_str_start__;
1586 log->hdr.trace_info.tskid =
1587 #ifdef RTOS
1588 osGetThreadIntId();
1589 #else
1590 0;
1591 #endif
1592 log->hdr.trace_info.crc = 0x2A;
1593 #ifndef LITE_VERSION
1594 log->hdr.trace_head.timestamp = TICKS_TO_MS(hal_sys_timer_get());
1595 #ifdef USE_CRC_CHECK
1596 log->hdr.trace_head.crc = crc8(((uint8_t *)&log->hdr) + 1, 7);
1597 #else
1598 log->hdr.trace_head.crc = 0xBE;
1599 #endif
1600 #else
1601 log->hdr.trace_info.crc = crc6(((uint8_t *)&log->hdr) + 1, 3);
1602 #endif
1603
1604 return sizeof(log->hdr) + sizeof(log->arg[0]) * num;
1605 }
1606 #endif // USE_TRACE_ID
1607
hal_trace_print_time(enum TR_LEVEL_T level,enum TR_MODULE_T module,char * buf,unsigned int size)1608 static int hal_trace_print_time(enum TR_LEVEL_T level, enum TR_MODULE_T module, char *buf, unsigned int size)
1609 {
1610 #ifdef TRACE_TIME_STAMP
1611 #ifdef CONFIG_SMP
1612 #define PRINT_CPU_ID
1613 #else
1614 #define PRINT_MODE_LEVEL
1615 #endif
1616 #ifdef PRINT_MODE_LEVEL
1617 static const char level_ch[] = { 'C', 'E', 'W', 'N', 'I', 'D', 'V', '-', };
1618 const char *mod_name;
1619 int i;
1620 #endif
1621 char ctx[10];
1622 int len;
1623
1624 #ifdef CRASH_DUMP_ENABLE
1625 if (in_crash_dump) {
1626 return 0;
1627 }
1628 #endif
1629
1630 len = 0;
1631 len += snprintf(&buf[len], size - len, "%9u/", (unsigned)__SLIM_TICKS_TO_MS(hal_sys_timer_get()));
1632 #ifdef TRACE_GLOBAL_TAG
1633 if (gbl_tag_cb && size > len) {
1634 #if defined(CP_TRACE_ENABLE) && !defined(CONFIG_SMP)
1635 if (get_cpu_id() == 0)
1636 #endif
1637 {
1638 len += gbl_tag_cb(&buf[len], size - len);
1639 }
1640 }
1641 #endif
1642 #if defined(ARM_CMNS) || defined(ARM_CMSE)
1643 if (size > len) {
1644 #if defined(ARM_CMNS)
1645 len += snprintf(&buf[len], size - len, "NS/");
1646 #elif defined(ARM_CMSE)
1647 len += snprintf(&buf[len], size - len, "SE/");
1648 #endif
1649 }
1650 #endif
1651 #ifdef PRINT_MODE_LEVEL
1652 if (size > len + 2) {
1653 buf[len++] = level_ch[level];
1654 buf[len++] = '/';
1655 }
1656 if (size > len + 7) {
1657 mod_name = hal_trace_get_log_module_desc(module);
1658 if (mod_name) {
1659 for (i = 0; i < 6; i++) {
1660 if (mod_name[i] == '\0') {
1661 break;
1662 }
1663 buf[len++] = mod_name[i];
1664 }
1665 } else {
1666 buf[len++] = 'M';
1667 i = hal_trace_print_unsigned(&buf[len], 5, module);
1668 len += i;
1669 i++;
1670 }
1671 for (; i < 6; i++) {
1672 buf[len++] = ' ';
1673 }
1674 buf[len++] = '/';
1675 }
1676 #endif
1677 #ifdef PRINT_CPU_ID
1678 if (size > len) {
1679 len += snprintf(&buf[len], size - len, "cpu%d/", get_cpu_id());
1680 }
1681 #endif
1682 if (size > len) {
1683 if (0) {
1684 #if defined(CP_TRACE_ENABLE) && !defined(CONFIG_SMP)
1685 } else if (get_cpu_id()) {
1686 ctx[0] = ' ';
1687 ctx[1] = 'C';
1688 ctx[2] = 'P';
1689 ctx[3] = '\0';
1690 #endif
1691 } else if (in_isr()) {
1692 uint32_t ctx_len;
1693
1694 ctx_len = snprintf(ctx, sizeof(ctx), "%2d", (int8_t)NVIC_GetCurrentActiveIRQ());
1695 if (ctx_len + 1 < ARRAY_SIZE(ctx)) {
1696 ctx[ctx_len] = 'E';
1697 ctx[ctx_len + 1] = '\0';
1698 } else {
1699 ctx[ARRAY_SIZE(ctx) - 2] = '.';
1700 ctx[ARRAY_SIZE(ctx) - 1] = '\0';
1701 }
1702 } else {
1703 #ifdef RTOS
1704 #if defined(KERNEL_RHINO) || defined(KERNEL_RTX5)
1705 const char *thread_name = osGetThreadName();
1706 snprintf(ctx, sizeof(ctx), "%.9s", thread_name ? (char *)thread_name : "NULL");
1707 #else
1708 snprintf(ctx, sizeof(ctx), "%3d", osGetThreadIntId());
1709 #endif
1710
1711 #else
1712 ctx[0] = ' ';
1713 ctx[1] = ' ';
1714 ctx[2] = '0';
1715 ctx[3] = '\0';
1716 #endif
1717 }
1718 ctx[ARRAY_SIZE(ctx) - 1] = '\0';
1719 len += snprintf(&buf[len], size - len, "%s | ", ctx);
1720 }
1721 return len;
1722 #else // !TRACE_TIME_STAMP
1723 return 0;
1724 #endif // !TRACE_TIME_STAMP
1725 }
1726
hal_trace_format_va(uint32_t attr,char * buf,unsigned int size,const char * fmt,va_list ap)1727 static inline int hal_trace_format_va(uint32_t attr, char *buf, unsigned int size, const char *fmt, va_list ap)
1728 {
1729 int len;
1730
1731 len = vsnprintf(&buf[0], size, fmt, ap);
1732 if ((attr & TR_ATTR_NO_LF) == 0) {
1733 #ifdef TRACE_CRLF
1734 if (len + 2 < size) {
1735 buf[len++] = '\r';
1736 }
1737 #endif
1738 if (len + 1 < size) {
1739 buf[len++] = '\n';
1740 }
1741 }
1742 //if (len < size) buf[len] = 0;
1743
1744 return len;
1745 }
1746
1747 static HAL_TRACE_PRINTF_HOOK_T _hal_trace_printf_hook = NULL;
hal_trace_printf_register_hook(HAL_TRACE_PRINTF_HOOK_T hook)1748 void hal_trace_printf_register_hook(HAL_TRACE_PRINTF_HOOK_T hook)
1749 {
1750 _hal_trace_printf_hook = hook;
1751 }
1752
hal_trace_printf_unregister_hook(HAL_TRACE_PRINTF_HOOK_T hook)1753 void hal_trace_printf_unregister_hook(HAL_TRACE_PRINTF_HOOK_T hook)
1754 {
1755 if (_hal_trace_printf_hook == hook) {
1756 _hal_trace_printf_hook = NULL;
1757 }
1758 }
1759
hal_trace_printf_hook(const char * tag,const char * fmt,va_list ap)1760 int hal_trace_printf_hook(const char *tag, const char *fmt, va_list ap)
1761 {
1762 int ret = 0;
1763 if (_hal_trace_printf_hook) {
1764 ret = _hal_trace_printf_hook(tag, fmt, ap);
1765 }
1766 return ret;
1767 }
1768
hal_trace_printf_internal(uint32_t attr,const char * fmt,va_list ap)1769 int hal_trace_printf_internal(uint32_t attr, const char *fmt, va_list ap)
1770 {
1771 #ifdef USE_TRACE_ID
1772 struct PACKED LOG_CONTAINER_T {
1773 char prefix[4];
1774 struct LOG_BODY_T body;
1775 };
1776 union LOG_BUF_T {
1777 char buf[60];
1778 struct LOG_CONTAINER_T container;
1779 uint32_t align;
1780 };
1781
1782 union LOG_BUF_T log_buf;
1783 char *buf = (char *)&log_buf;
1784 #else
1785 char buf[TRACE_PRINTF_LEN];
1786 #endif
1787 if (get_hal_trace_onoff()){
1788 return 0;
1789 }
1790
1791 #ifndef __ARM_ARCH_ISA_ARM
1792 if (!in_isr()) {
1793 if (hal_trace_printf_hook(NULL, fmt, ap)) {
1794 return 1;
1795 }
1796 }
1797 #endif
1798
1799 int len = 0;
1800 enum TR_LEVEL_T level;
1801 enum TR_MODULE_T module;
1802
1803 level = GET_BITFIELD(attr, TR_ATTR_LEVEL);
1804 module = GET_BITFIELD(attr, TR_ATTR_MOD);
1805
1806 #ifdef CRASH_DUMP_ENABLE
1807 if (!in_crash_dump)
1808 #endif
1809 {
1810 if (level > trace_max_level) {
1811 return 0;
1812 }
1813 if (level > TR_LEVEL_CRITICAL && (trace_mod_map[module >> 5] & (1 << (module & 0x1F))) == 0) {
1814 return 0;
1815 }
1816 }
1817
1818 #ifdef USE_TRACE_ID
1819 if ((attr & TR_ATTR_NO_ID) == 0 && (len = hal_trace_format_id(attr, &log_buf.container.body, fmt, ap)) > 0) {
1820 buf = &log_buf.container.prefix[3];
1821 buf[0] = '\0';
1822 len += 1;
1823 }
1824 else
1825 #endif
1826 {
1827 len = 0;
1828 if ((attr & TR_ATTR_NO_TS) == 0) {
1829 len += hal_trace_print_time(level, module, &buf[len], sizeof(buf) - len);
1830 }
1831 len += hal_trace_format_va(attr, &buf[len], sizeof(buf) - len, fmt, ap);
1832 }
1833
1834 return hal_trace_output((unsigned char *)buf, len);
1835 }
1836 #if defined(NUTTX_BUILD) && !defined(CONFIG_ARCH_CHIP_DEBUG_H)
1837 uint8_t tmp_int_buff[512];
1838 #endif
hal_trace_printf(uint32_t attr,const char * fmt,...)1839 int hal_trace_printf(uint32_t attr, const char *fmt, ...)
1840 {
1841 int ret;
1842 va_list ap;
1843
1844 if (attr & TR_ATTR_IMM) {
1845 hal_trace_flush_buffer();
1846 }
1847
1848 va_start(ap, fmt);
1849 #if defined(NUTTX_BUILD) && !defined(CONFIG_ARCH_CHIP_DEBUG_H)
1850 enum TR_LEVEL_T level;
1851 enum TR_MODULE_T module;
1852 bool is_nolf = attr & TR_ATTR_NO_LF;
1853 level = GET_BITFIELD(attr, TR_ATTR_LEVEL);
1854 module = GET_BITFIELD(attr, TR_ATTR_MOD);
1855 char *tmpfmt = NULL;
1856 ret = 0;
1857 if (!is_nolf)
1858 {
1859 if (up_interrupt_context())
1860 {
1861 sprintf(tmp_int_buff, "%s\n", fmt);
1862 fmt = tmp_int_buff;
1863 }
1864 else
1865 ret = asprintf(&tmpfmt, "%s\n", fmt);
1866 }
1867 if (ret < 0 || tmpfmt == NULL)
1868 vsyslog(level+1, fmt , ap);
1869 else
1870 {
1871 vsyslog(level+1, tmpfmt , ap);
1872 free(tmpfmt);
1873 }
1874 ret = 0;
1875 #else
1876 ret = hal_trace_printf_internal(attr, fmt, ap);
1877 #endif
1878 va_end(ap);
1879
1880 if (attr & TR_ATTR_IMM) {
1881 hal_trace_flush_buffer();
1882 }
1883
1884 return ret;
1885 }
1886
hal_trace_printf_without_crlf_ts(const char * fmt,...)1887 int hal_trace_printf_without_crlf_ts(const char *fmt, ...)
1888 {
1889 int ret;
1890 uint32_t attr = TR_ATTR_NO_LF|TR_ATTR_NO_TS|TR_ATTR_NO_ID;
1891 va_list ap;
1892
1893 va_start(ap, fmt);
1894 ret = hal_trace_printf_internal(attr, fmt, ap);
1895 va_end(ap);
1896
1897 return ret;
1898 }
1899
hal_trace_printf_without_crlf(const char * fmt,...)1900 int hal_trace_printf_without_crlf(const char *fmt, ...)
1901 {
1902 int ret;
1903 uint32_t attr = TR_ATTR_NO_LF|TR_ATTR_NO_ID;
1904 va_list ap;
1905
1906 va_start(ap, fmt);
1907 ret = hal_trace_printf_internal(attr, fmt, ap);
1908 va_end(ap);
1909
1910 return ret;
1911 }
1912
hal_trace_dump(const char * fmt,unsigned int size,unsigned int count,const void * buffer)1913 int hal_trace_dump(const char *fmt, unsigned int size, unsigned int count, const void *buffer)
1914 {
1915 char buf[TRACE_DUMP_LEN];
1916 int len=0, n=0, i=0;
1917
1918 switch( size )
1919 {
1920 case sizeof(uint32_t):
1921 while(i<count && len<sizeof(buf))
1922 {
1923 len += snprintf(&buf[len], sizeof(buf) - len, fmt, *(uint32_t *)((uint32_t *)buffer+i));
1924 i++;
1925 }
1926 break;
1927 case sizeof(uint16_t):
1928 while(i<count && len<sizeof(buf))
1929 {
1930 len += snprintf(&buf[len], sizeof(buf) - len, fmt, *(uint16_t *)((uint16_t *)buffer+i));
1931 i++;
1932 }
1933 break;
1934 case sizeof(uint8_t):
1935 default:
1936 while(i<count && len<sizeof(buf))
1937 {
1938 len += snprintf(&buf[len], sizeof(buf) - len, fmt, *(uint8_t *)((uint8_t *)buffer+i));
1939 i++;
1940 }
1941 break;
1942 }
1943
1944 #ifdef TRACE_CRLF
1945 if (len + 2 < sizeof(buf)) {
1946 buf[len++] = '\r';
1947 }
1948 #endif
1949 if (len + 1 < sizeof(buf)) {
1950 buf[len++] = '\n';
1951 }
1952
1953 if (get_hal_trace_onoff() == 1){
1954 return len;
1955 }
1956
1957 n = hal_trace_output((unsigned char *)buf, len);
1958
1959 return n;
1960 }
1961
hal_trace_busy(void)1962 int hal_trace_busy(void)
1963 {
1964 #if (TRACE_BUF_SIZE > 0)
1965 union HAL_UART_FLAG_T flag;
1966
1967 if (hal_trace_is_uart_transport(trace_transport)) {
1968 if (hal_uart_opened(trace_uart)) {
1969 flag = hal_uart_get_flag(trace_uart);
1970 return flag.BUSY;
1971 }
1972 }
1973 #endif
1974 return 0;
1975 }
1976
hal_trace_pause(void)1977 int hal_trace_pause(void)
1978 {
1979 #if (TRACE_BUF_SIZE > 0)
1980 int ret = 0;
1981 uint32_t lock;
1982
1983 lock = int_lock();
1984 if (p_trace->pause_cnt == 0) {
1985 if (hal_trace_is_uart_transport(trace_transport)) {
1986 #if (TRACE_IDLE_OUTPUT == 0)
1987 hal_trace_uart_stop_dma_send();
1988 #endif
1989 hal_uart_pause(trace_uart, HAL_UART_XFER_TYPE_TX);
1990 }
1991 }
1992 p_trace->pause_cnt++;
1993 if (p_trace->pause_cnt == 0) {
1994 p_trace->pause_cnt--;
1995 ret = 1;
1996 }
1997 int_unlock(lock);
1998
1999 return ret;
2000 #else
2001 return 0;
2002 #endif
2003 }
2004
hal_trace_continue(void)2005 int hal_trace_continue(void)
2006 {
2007 #if (TRACE_BUF_SIZE > 0)
2008 int ret = 0;
2009 uint32_t lock;
2010
2011 lock = int_lock();
2012 if (p_trace->pause_cnt == 0) {
2013 ret = 1;
2014 } else {
2015 p_trace->pause_cnt--;
2016 if (p_trace->pause_cnt == 0) {
2017 if (hal_trace_is_uart_transport(trace_transport)) {
2018 hal_uart_continue(trace_uart, HAL_UART_XFER_TYPE_TX);
2019 }
2020 #if (TRACE_IDLE_OUTPUT == 0)
2021 hal_trace_send();
2022 #endif
2023 }
2024 }
2025 int_unlock(lock);
2026
2027 return ret;
2028 #else
2029 return 0;
2030 #endif
2031 }
2032
hal_trace_force_continue(void)2033 static void hal_trace_force_continue(void)
2034 {
2035 #if (TRACE_BUF_SIZE > 0)
2036 if (p_trace->pause_cnt) {
2037 // Allow to flush buffer
2038 p_trace->pause_cnt = 0;
2039 if (hal_trace_is_uart_transport(trace_transport)) {
2040 hal_uart_continue(trace_uart, HAL_UART_XFER_TYPE_TX);
2041 }
2042 #if (TRACE_IDLE_OUTPUT == 0)
2043 hal_trace_send();
2044 #endif
2045 }
2046 #endif
2047 }
2048
hal_trace_flush_buffer(void)2049 int hal_trace_flush_buffer(void)
2050 {
2051 #if (TRACE_BUF_SIZE > 0)
2052 int ret = 0;
2053 uint32_t lock;
2054 uint32_t time;
2055 #if (TRACE_IDLE_OUTPUT == 0)
2056 enum HAL_DMA_RET_T dma_ret;
2057 #endif
2058
2059 if (trace_transport >= HAL_TRACE_TRANSPORT_QTY) {
2060 return -1;
2061 }
2062
2063 #ifdef CP_TRACE_ENABLE
2064 if (get_cpu_id()) {
2065 if (cp_buffer_cb) {
2066 cp_buffer_cb(HAL_TRACE_BUF_STATE_FLUSH);
2067 }
2068 return 0;
2069 }
2070 #endif
2071
2072 lock = int_lock();
2073
2074 if (p_trace->pause_cnt == 0) {
2075 time = hal_sys_timer_get();
2076 while (p_trace->wptr != p_trace->rptr &&
2077 (hal_sys_timer_get() - time) < TRACE_FLUSH_TIMEOUT) {
2078 #if (TRACE_IDLE_OUTPUT == 0)
2079 #if (defined(CHIP_BEST2001_DSP) || defined(CHIP_BEST2003_DSP)) && !defined(PROGRAMMER) && defined(RTOS)
2080 if (trace_transport == HAL_TRACE_TRANSPORT_TRANSQ1) {
2081 if (p_trace->sending) {
2082 while (hal_transq_tx_busy(HAL_TRANSQ_ID_1));
2083 hal_transq_local_irq_handler_body(HAL_TRANSQ_ID_1);
2084 }
2085 hal_trace_send();
2086 } else
2087 #endif
2088 {
2089 while (hal_dma_chan_busy(dma_cfg.ch));
2090 dma_ret = hal_dma_irq_run_chan(dma_cfg.ch);
2091 if (dma_ret != HAL_DMA_OK) {
2092 hal_trace_send();
2093 }
2094 }
2095 #else
2096 hal_trace_send();
2097 #endif
2098 }
2099 ret = (p_trace->wptr == p_trace->rptr) ? 0 : 1;
2100 }
2101
2102 int_unlock(lock);
2103
2104 return ret;
2105 #else
2106 return 0;
2107 #endif
2108 }
2109
hal_trace_flush_output(void)2110 int hal_trace_flush_output(void)
2111 {
2112 #if (TRACE_BUF_SIZE > 0)
2113 uint32_t lock;
2114 uint32_t time;
2115 int ret;
2116 int busy;
2117
2118 lock = int_lock();
2119
2120 ret = hal_trace_flush_buffer();
2121
2122 time = hal_sys_timer_get();
2123 while ((busy = hal_trace_busy()) && (hal_sys_timer_get() - time) < TRACE_FLUSH_TIMEOUT);
2124
2125 int_unlock(lock);
2126
2127 return (ret || busy);
2128 #else
2129 return 0;
2130 #endif
2131 }
2132
hal_trace_get_backtrace_addr(uint32_t addr)2133 uint32_t hal_trace_get_backtrace_addr(uint32_t addr)
2134 {
2135 if (!hal_trace_address_executable(addr)) {
2136 return 0;
2137 }
2138
2139 #ifndef __ARM_ARCH_ISA_ARM
2140 #if defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__)
2141 // BL Instruction
2142 // OFFSET: 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
2143 // VALUE : 1 1 1 1 0 - - - - - - - - - - - 1 1 - 1 - - - - - - - - - - - -
2144
2145 // BLX Instruction
2146 // OFFSET: 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
2147 // VALUE : 0 1 0 0 0 1 1 1 1 - - - - - - -
2148
2149 uint16_t val;
2150 uint32_t new_addr;
2151
2152 new_addr = (addr & ~1) - 2;
2153
2154 val = *(uint16_t *)new_addr;
2155 if ((val & 0xFF80) == 0x4780) {
2156 // BLX
2157 return new_addr;
2158 } else if ((val & 0xD000) == 0xD000) {
2159 new_addr -= 2;
2160 val = *(uint16_t *)new_addr;
2161 if ((val & 0xF800) == 0xF000) {
2162 // BL
2163 return new_addr;
2164 }
2165 }
2166 #else
2167 #if defined(NUTTX_BUILD)
2168 extern uint32_t _mmu_text_start[];
2169 extern uint32_t _mmu_text_end[];
2170 if (addr >= _mmu_text_start && addr <= _mmu_text_end)
2171 return addr;
2172 #else
2173 #error "Only ARMv7-M/ARMv8-M function can be checked for BL/BLX instructions"
2174 #endif
2175 #endif
2176 #endif
2177
2178 return 0;
2179 }
2180
2181 #ifndef __ARM_ARCH_ISA_ARM
hal_trace_print_special_stack_registers(uint32_t msp,uint32_t psp)2182 void hal_trace_print_special_stack_registers(uint32_t msp, uint32_t psp)
2183 {
2184 int len;
2185
2186 hal_trace_output_linefeed();
2187
2188 len = snprintf(crash_buf, sizeof(crash_buf), "MSP =%08X, PSP =%08X" NEW_LINE_STR, (unsigned)msp, (unsigned)psp);
2189 hal_trace_output((unsigned char *)crash_buf, len);
2190
2191 #ifdef __ARM_ARCH_8M_MAIN__
2192 len = snprintf(crash_buf, sizeof(crash_buf), "MSPLIM=%08X, PSPLIM=%08X" NEW_LINE_STR, (unsigned)__get_MSPLIM(), (unsigned)__get_PSPLIM());
2193 hal_trace_output((unsigned char *)crash_buf, len);
2194 #endif
2195 }
2196
2197 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
hal_trace_print_special_stack_registers_ns(uint32_t msp_ns,uint32_t psp_ns)2198 void hal_trace_print_special_stack_registers_ns(uint32_t msp_ns, uint32_t psp_ns)
2199 {
2200 int len;
2201
2202 hal_trace_output_linefeed();
2203
2204 len = snprintf(crash_buf, sizeof(crash_buf), "MSP_NS =%08X, PSP_NS =%08X" NEW_LINE_STR, (unsigned)msp_ns, (unsigned)psp_ns);
2205 hal_trace_output((unsigned char *)crash_buf, len);
2206
2207 len = snprintf(crash_buf, sizeof(crash_buf), "MSPLIM_NS=%08X, PSPLIM_NS=%08X" NEW_LINE_STR, (unsigned)__TZ_get_MSPLIM_NS(), (unsigned)__TZ_get_PSPLIM_NS());
2208 hal_trace_output((unsigned char *)crash_buf, len);
2209 }
2210 #endif
2211 #endif
2212
hal_trace_print_common_registers(const uint32_t * regs)2213 void hal_trace_print_common_registers(const uint32_t *regs)
2214 {
2215 int len;
2216 int i;
2217 int index;
2218
2219 hal_trace_output_linefeed();
2220
2221 for (i = 0; i < 3; i++) {
2222 index = i * 4;
2223 len = snprintf(crash_buf, sizeof(crash_buf), "R%-2d=%08X, R%-2d=%08X, R%-2d=%08X, R%-2d=%08X" NEW_LINE_STR,
2224 index, (unsigned)regs[index], index + 1, (unsigned)regs[index + 1],
2225 index + 2, (unsigned)regs[index + 2], index + 3, (unsigned)regs[index + 3]);
2226 hal_trace_output((unsigned char *)crash_buf, len);
2227 }
2228 len = snprintf(crash_buf, sizeof(crash_buf), "R12=%08X, SP =%08X, LR =%08X" NEW_LINE_STR,
2229 (unsigned)regs[12], (unsigned)regs[13], (unsigned)regs[14]);
2230 hal_trace_output((unsigned char *)crash_buf, len);
2231 }
2232
hal_trace_print_stack(uint32_t addr)2233 void hal_trace_print_stack(uint32_t addr)
2234 {
2235 static const char stack_title[] = "Stack:" NEW_LINE_STR;
2236 int len = 0;
2237 int i;
2238 int pos;
2239 uint32_t *stack;
2240
2241 addr &= ~3;
2242 if (!hal_trace_address_writable(addr)) {
2243 return;
2244 }
2245
2246 #ifndef DUMP_SECURE_STACK
2247 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
2248 // don't dump secure stack
2249 if (RAM_BASE < addr && addr < RAM_BASE + RAM_SIZE) {
2250 return;
2251 }
2252 #endif
2253 #endif
2254
2255 hal_trace_output_linefeed();
2256 hal_trace_output((const unsigned char *)stack_title, sizeof(stack_title) - 1);
2257
2258 stack = (uint32_t *)addr - STACK_DUMP_CNT_PREV;
2259 for (i = 0; i < (STACK_DUMP_CNT_PREV + STACK_DUMP_CNT); i++) {
2260 if (!hal_trace_address_writable((uint32_t)&stack[i])) {
2261 break;
2262 }
2263 pos = (i % STACK_DUMP_CNT_PER_LEN);
2264 if (pos == 0) {
2265 len = snprintf(crash_buf, sizeof(crash_buf), "%c %08X: %08X",
2266 (i == STACK_DUMP_CNT_PREV) ? '*' : ' ', (unsigned)&stack[i], (unsigned)stack[i]);
2267 } else {
2268 len += snprintf(crash_buf + len, sizeof(crash_buf) - len, " %08X", (unsigned)stack[i]);
2269 if (pos == (STACK_DUMP_CNT_PER_LEN - 1)) {
2270 #ifdef TRACE_CRLF
2271 if (len + 2 < sizeof(crash_buf)) {
2272 crash_buf[len++] = '\r';
2273 }
2274 #endif
2275 if (len + 1 < sizeof(crash_buf)) {
2276 crash_buf[len++] = '\n';
2277 }
2278 hal_trace_output((unsigned char *)crash_buf, len);
2279 hal_trace_flush_buffer();
2280 }
2281 }
2282 }
2283 }
2284
hal_trace_print_backtrace(uint32_t addr,uint32_t search_cnt,uint32_t print_cnt)2285 void hal_trace_print_backtrace(uint32_t addr, uint32_t search_cnt, uint32_t print_cnt)
2286 {
2287 static const char bt_title[] = "Possible Backtrace:" NEW_LINE_STR;
2288 int i, j;
2289 int len;
2290 uint32_t *stack;
2291 uint32_t call_addr;
2292
2293 addr &= ~3;
2294 if (!hal_trace_address_writable(addr)) {
2295 return;
2296 }
2297
2298 hal_trace_output_linefeed();
2299 hal_trace_output((const unsigned char *)bt_title, sizeof(bt_title) - 1);
2300
2301 stack = (uint32_t *)addr;
2302 for (i = 0, j = 0; i < search_cnt && j < print_cnt; i++) {
2303 if (!hal_trace_address_writable((uint32_t)&stack[i])) {
2304 break;
2305 }
2306 call_addr = hal_trace_get_backtrace_addr(stack[i]);
2307 if (call_addr) {
2308 #if defined(NUTTX_BUILD)
2309 len = snprintf(crash_buf, sizeof(crash_buf), "%8X ", (unsigned)call_addr);
2310 #else
2311 len = snprintf(crash_buf, sizeof(crash_buf), "%8X" NEW_LINE_STR, (unsigned)call_addr);
2312 #endif
2313 hal_trace_output((unsigned char *)crash_buf, len);
2314 j++;
2315 }
2316 }
2317 }
2318
hal_trace_get_id(void)2319 uint32_t hal_trace_get_id(void)
2320 {
2321 return trace_uart;
2322 }
2323
hal_trace_get_baudrate(void)2324 uint32_t hal_trace_get_baudrate(void)
2325 {
2326 #if (TRACE_BUF_SIZE > 0)
2327 return uart_cfg.baud;
2328 #else
2329 return 0;
2330 #endif
2331 }
2332
hal_trace_in_crash_dump(void)2333 bool hal_trace_in_crash_dump(void)
2334 {
2335 #ifdef CRASH_DUMP_ENABLE
2336 return in_crash_dump;
2337 #else
2338 return false;
2339 #endif
2340 }
2341
hal_trace_crash_dump_register(enum HAL_TRACE_CRASH_DUMP_MODULE_T module,HAL_TRACE_CRASH_DUMP_CB_T cb)2342 int hal_trace_crash_dump_register(enum HAL_TRACE_CRASH_DUMP_MODULE_T module, HAL_TRACE_CRASH_DUMP_CB_T cb)
2343 {
2344 #ifdef CRASH_DUMP_ENABLE
2345 ASSERT(module < HAL_TRACE_CRASH_DUMP_MODULE_END, "%s module %d", __func__, module);
2346 crash_dump_cb_list[module] = cb;
2347 #endif
2348 return 0;
2349 }
2350
hal_trace_crash_dump_callback(void)2351 void hal_trace_crash_dump_callback(void)
2352 {
2353 #ifdef CRASH_DUMP_ENABLE
2354 int i;
2355
2356 in_crash_dump = true;
2357
2358 for (i = 0; i < ARRAY_SIZE(crash_dump_cb_list); i++) {
2359 if (crash_dump_cb_list[i]) {
2360 crash_dump_cb_list[i]();
2361 }
2362 }
2363 #endif
2364 }
2365
2366 #ifdef CRASH_DUMP_ENABLE
2367 #ifdef TRACE_TO_APP
hal_trace_app_notify_callback(enum HAL_TRACE_STATE_T state)2368 void hal_trace_app_notify_callback(enum HAL_TRACE_STATE_T state)
2369 {
2370 if (state == HAL_TRACE_STATE_CRASH_ASSERT_START) {
2371 app_output_enabled = true;
2372 } else if (state == HAL_TRACE_STATE_CRASH_FAULT_START) {
2373 if (app_crash_custom_cb == NULL) {
2374 app_output_enabled = true;
2375 }
2376 }
2377 for (int i = 0; i < HAL_TRACE_APP_REG_ID_QTY; i++) {
2378 if (app_notify_cb[i]) {
2379 app_notify_cb[i](state);
2380 }
2381 }
2382 }
2383
hal_trace_app_output_callback(const unsigned char * buf,unsigned int buf_len)2384 static void hal_trace_app_output_callback(const unsigned char *buf, unsigned int buf_len)
2385 {
2386 for (int i = 0; i < HAL_TRACE_APP_REG_ID_QTY; i++) {
2387 if (app_output_cb[i]) {
2388 app_output_cb[i](buf, buf_len);
2389 }
2390 }
2391 }
2392 #endif
2393 #endif
2394
hal_trace_app_register(enum HAL_TRACE_APP_REG_ID_T id,HAL_TRACE_APP_NOTIFY_T notify_cb,HAL_TRACE_APP_OUTPUT_T output_cb)2395 int hal_trace_app_register(enum HAL_TRACE_APP_REG_ID_T id, HAL_TRACE_APP_NOTIFY_T notify_cb, HAL_TRACE_APP_OUTPUT_T output_cb)
2396 {
2397 if (id >= HAL_TRACE_APP_REG_ID_QTY) {
2398 return 1;
2399 }
2400 #ifdef TRACE_TO_APP
2401 bool output_valid = false;
2402 uint32_t lock;
2403
2404 lock = int_lock();
2405
2406 app_notify_cb[id] = notify_cb;
2407 app_output_cb[id] = output_cb;
2408
2409 for (int i = 0; i < HAL_TRACE_APP_REG_ID_QTY; i++) {
2410 if (app_output_cb[i]) {
2411 output_valid = true;
2412 break;
2413 }
2414 }
2415 app_output_cb_valid = output_valid;
2416
2417 int_unlock(lock);
2418 #endif
2419 return 0;
2420 }
2421
hal_trace_app_custom_register(HAL_TRACE_APP_NOTIFY_T notify_cb,HAL_TRACE_APP_OUTPUT_T output_cb,HAL_TRACE_APP_OUTPUT_T crash_custom_cb)2422 void hal_trace_app_custom_register(HAL_TRACE_APP_NOTIFY_T notify_cb, HAL_TRACE_APP_OUTPUT_T output_cb, HAL_TRACE_APP_OUTPUT_T crash_custom_cb)
2423 {
2424 #ifdef TRACE_TO_APP
2425 hal_trace_app_register(HAL_TRACE_APP_REG_ID_0, notify_cb, output_cb);
2426 app_crash_custom_cb = crash_custom_cb;
2427 #endif
2428 }
2429
hal_trace_global_tag_register(HAL_TRACE_GLOBAL_TAG_CB_T tag_cb)2430 void hal_trace_global_tag_register(HAL_TRACE_GLOBAL_TAG_CB_T tag_cb)
2431 {
2432 #ifdef TRACE_GLOBAL_TAG
2433 gbl_tag_cb = tag_cb;
2434 #endif
2435 }
2436
hal_trace_open_cp(HAL_TRACE_BUF_CTRL_T buf_cb,HAL_TRACE_APP_NOTIFY_T notify_cb)2437 int hal_trace_open_cp(HAL_TRACE_BUF_CTRL_T buf_cb, HAL_TRACE_APP_NOTIFY_T notify_cb)
2438 {
2439 #ifdef CP_TRACE_ENABLE
2440 cp_buffer_cb = buf_cb;
2441 #ifdef CRASH_DUMP_ENABLE
2442 cp_notify_cb = notify_cb;
2443 #endif
2444 #ifdef FAULT_DUMP
2445 NVIC_SetDefaultFaultHandler_cp(hal_trace_fault_handler);
2446 #endif
2447 #endif
2448
2449 return 0;
2450 }
2451
hal_trace_close_cp(void)2452 int hal_trace_close_cp(void)
2453 {
2454 #ifdef CP_TRACE_ENABLE
2455 cp_buffer_cb = NULL;
2456 #ifdef CRASH_DUMP_ENABLE
2457 cp_notify_cb = NULL;
2458 #endif
2459 // Force to unlock CP trace memsc
2460 hal_memsc_unlock(HAL_MEMSC_ID_TRACE);
2461 #endif
2462
2463 return 0;
2464 }
2465
2466 #else // !(DEBUG || REL_TRACE_ENABLE)
2467
hal_trace_open(enum HAL_TRACE_TRANSPORT_T transport)2468 int hal_trace_open(enum HAL_TRACE_TRANSPORT_T transport)
2469 {
2470 #ifdef FAULT_DUMP
2471 #ifdef __ARM_ARCH_ISA_ARM
2472 GIC_SetFaultDumpHandler(hal_trace_fault_dump);
2473 #else
2474 NVIC_SetDefaultFaultHandler(hal_trace_fault_handler);
2475 #endif
2476 #endif
2477
2478 return 0;
2479 }
2480
2481 #endif // !(DEBUG || REL_TRACE_ENABLE)
2482
hal_trace_address_writable(uint32_t addr)2483 int hal_trace_address_writable(uint32_t addr)
2484 {
2485 if (RAM_BASE < addr && addr < RAM_BASE + RAM_SIZE) {
2486 return 1;
2487 }
2488 #if defined(PSRAM_BASE) && (PSRAM_SIZE > 0)
2489 if (PSRAM_BASE < addr && addr < PSRAM_BASE + PSRAM_SIZE) {
2490 return 1;
2491 }
2492 #endif
2493 #if defined(PSRAM_NC_BASE) && (PSRAM_SIZE > 0)
2494 if (PSRAM_NC_BASE < addr && addr < PSRAM_NC_BASE + PSRAM_SIZE) {
2495 return 1;
2496 }
2497 #endif
2498 #if defined(PSRAMUHS_BASE) && (PSRAMUHS_SIZE > 0)
2499 if (PSRAMUHS_BASE < addr && addr < PSRAMUHS_BASE + PSRAMUHS_SIZE) {
2500 return 1;
2501 }
2502 #endif
2503 #if defined(PSRAMUHS_NC_BASE) && (PSRAMUHS_SIZE > 0)
2504 if (PSRAMUHS_NC_BASE < addr && addr < PSRAMUHS_NC_BASE + PSRAMUHS_SIZE) {
2505 return 1;
2506 }
2507 #endif
2508 #if defined(RAMRET_BASE) && (RAMRET_SIZE > 0)
2509 if (RAMRET_BASE < addr && addr < RAMRET_BASE + RAMRET_SIZE) {
2510 return 1;
2511 }
2512 #endif
2513 #if defined(RAMCP_BASE) && (RAMCP_SIZE > 0)
2514 if (RAMCP_BASE < addr && addr < RAMCP_BASE + RAMCP_SIZE) {
2515 return 1;
2516 }
2517 #endif
2518 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
2519 if (RAM_NS_BASE < addr && addr < RAM_NS_BASE + RAM_NS_SIZE) {
2520 return 1;
2521 }
2522 #endif
2523
2524 #if defined(CONFIG_BES_DUALCORE_AMP)
2525 #ifdef PSRAMCP_BASE
2526 if (PSRAMCP_BASE < addr && addr < PSRAMCP_BASE + PSRAMCP_SIZE) {
2527 return 1;
2528 }
2529 #endif
2530 #endif
2531 return 0;
2532 }
2533
hal_trace_address_executable(uint32_t addr)2534 int hal_trace_address_executable(uint32_t addr)
2535 {
2536 // Check thumb code
2537 if ((addr & 1) == 0) {
2538 return 0;
2539 }
2540
2541 // Avoid reading out of valid memory region when parsing instruction content
2542 #define X_ADDR_OFFSET 0x10
2543
2544 // Check location
2545 if ((RAMX_BASE + X_ADDR_OFFSET) < addr && addr < (RAMX_BASE + RAM_SIZE)) {
2546 return 1;
2547 }
2548 #if defined(PSRAMX_BASE) && (PSRAM_SIZE > 0)
2549 if ((PSRAMX_BASE + X_ADDR_OFFSET) < addr && addr < (PSRAMX_BASE + PSRAM_SIZE)) {
2550 return 1;
2551 }
2552 #endif
2553 #if defined(PSRAMUHSX_BASE) && (PSRAMUHS_SIZE > 0)
2554 if ((PSRAMUHSX_BASE + X_ADDR_OFFSET) < addr && addr < (PSRAMUHSX_BASE + PSRAMUHS_SIZE)) {
2555 return 1;
2556 }
2557 #endif
2558 #if defined(RAMXRET_BASE) && (RAMRET_SIZE > 0)
2559 if ((RAMXRET_BASE + X_ADDR_OFFSET) < addr && addr < (RAMXRET_BASE + RAMRET_SIZE)) {
2560 return 1;
2561 }
2562 #endif
2563
2564 // Check flash location
2565 #ifndef NO_FLASH_BASE_ACCESS
2566 #ifdef OTA_CODE_OFFSET
2567 #define FLASH_EXEC_START (FLASHX_BASE + OTA_CODE_OFFSET)
2568 #define FLASH_EXEC_SIZE (FLASH_SIZE - OTA_CODE_OFFSET)
2569 #else
2570 #define FLASH_EXEC_START (FLASHX_BASE)
2571 #define FLASH_EXEC_SIZE (FLASH_SIZE)
2572 #endif
2573 #ifdef FLASH_REGION_SIZE
2574 #undef FLASH_EXEC_SIZE
2575 #define FLASH_EXEC_SIZE (FLASH_REGION_SIZE)
2576 #endif
2577 if ((FLASH_EXEC_START + X_ADDR_OFFSET) < addr && addr < (FLASH_EXEC_START + FLASH_EXEC_SIZE)) {
2578 return 1;
2579 }
2580 #endif
2581
2582 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
2583 if ((RAMX_NS_BASE + X_ADDR_OFFSET) < addr && addr < (RAMX_NS_BASE + RAM_NS_SIZE)) {
2584 return 1;
2585 }
2586 if ((FLASHX_BASE + NS_APP_START_OFFSET + X_ADDR_OFFSET) < addr && addr < (FLASHX_BASE + FLASH_SIZE)) {
2587 return 1;
2588 }
2589 #endif
2590 #if defined(CONFIG_BES_DUALCORE_AMP)
2591 #ifdef PSRAMCPX_BASE
2592 if (PSRAMCPX_BASE + X_ADDR_OFFSET < addr && addr < PSRAMCPX_BASE + PSRAMCP_SIZE) {
2593 return 1;
2594 }
2595 #endif
2596 #endif
2597 //#define CHECK_ROM_CODE
2598 #ifdef CHECK_ROM_CODE
2599 #ifdef ROM_EXT_SIZE
2600 #define ROM_TOTAL_SIZE (ROM_SIZE + ROM_EXT_SIZE)
2601 #else
2602 #define ROM_TOTAL_SIZE (ROM_SIZE)
2603 #endif
2604 if ((ROMX_BASE + (NVIC_USER_IRQ_OFFSET * 4)) < addr && addr < (ROMX_BASE + ROM_TOTAL_SIZE)) {
2605 return 1;
2606 }
2607 #endif
2608
2609 #if 0
2610 if (FLASHX_NC_BASE < addr && addr < FLASHX_NC_BASE + FLASH_SIZE) {
2611 return 1;
2612 }
2613 #ifdef PSRAMX_NC_BASE
2614 if (PSRAMX_NC_BASE < addr && addr < PSRAMX_NC_BASE + PSRAM_SIZE) {
2615 return 1;
2616 }
2617 #endif
2618 #ifdef PSRAMUHSX_NC_BASE
2619 if (PSRAMUHSX_NC_BASE < addr && addr < PSRAMUHSX_NC_BASE + PSRAMUHS_SIZE) {
2620 return 1;
2621 }
2622 #endif
2623 #endif
2624 return 0;
2625 }
2626
hal_trace_address_readable(uint32_t addr)2627 int hal_trace_address_readable(uint32_t addr)
2628 {
2629 if (hal_trace_address_writable(addr)) {
2630 return 1;
2631 }
2632 if (hal_trace_address_executable(addr)) {
2633 return 1;
2634 }
2635 if (FLASH_BASE < addr && addr < FLASH_BASE + FLASH_SIZE) {
2636 return 1;
2637 }
2638 if (FLASH_NC_BASE < addr && addr < FLASH_NC_BASE + FLASH_SIZE) {
2639 return 1;
2640 }
2641 #if defined(PSRAM_NC_BASE) && (PSRAM_SIZE > 0)
2642 if (PSRAM_NC_BASE < addr && addr < PSRAM_NC_BASE + PSRAM_SIZE) {
2643 return 1;
2644 }
2645 #endif
2646 #if defined(PSRAMUHS_NC_BASE) && (PSRAMUHS_SIZE > 0)
2647 if (PSRAMUHS_NC_BASE < addr && addr < PSRAMUHS_NC_BASE + PSRAMUHS_SIZE) {
2648 return 1;
2649 }
2650 #endif
2651 return 0;
2652 }
2653
hal_trace_crash_end(void)2654 static void NORETURN hal_trace_crash_end(void)
2655 {
2656 #if (defined(DEBUG) || defined(REL_TRACE_ENABLE))
2657 hal_trace_output_linefeed();
2658 hal_trace_flush_buffer();
2659 hal_sys_timer_delay(MS_TO_TICKS(5));
2660 #endif
2661
2662 // Tag failure for simulation environment
2663 hal_cmu_simu_fail();
2664
2665 #ifndef IN_SUBSYS
2666 #ifdef CRASH_REBOOT
2667 hal_sw_bootmode_set(HAL_SW_BOOTMODE_REBOOT|HAL_SW_BOOTMODE_REBOOT_FROM_CRASH);
2668 pmu_reboot();
2669 #else
2670 hal_iomux_set_analog_i2c();
2671 hal_iomux_set_jtag();
2672 hal_cmu_jtag_clock_enable();
2673 #endif
2674 #endif
2675
2676 SAFE_PROGRAM_STOP();
2677 }
2678
get_cpu_id_tag(void)2679 __STATIC_FORCEINLINE uint32_t get_cpu_id_tag(void)
2680 {
2681 uint32_t cpu_id;
2682 #ifdef CP_TRACE_ENABLE
2683 cpu_id = get_cpu_id();
2684 #elif defined(__ARM_ARCH_ISA_ARM)
2685 cpu_id = 0xAAAA0000 | (get_cpu_id() & 0xFFFF);
2686 #else
2687 cpu_id = 0;
2688 #endif
2689 return cpu_id;
2690 }
2691
hal_trace_assert_dump_internal(ASSERT_DUMP_ARGS)2692 static void NORETURN USED hal_trace_assert_dump_internal(ASSERT_DUMP_ARGS)
2693 {
2694 const uint32_t *p_regs;
2695 struct ASSERT_INFO_T info;
2696 int i;
2697
2698 crash_occurs[get_cpu_id()] = true;
2699
2700 int_lock_global();
2701
2702 p_regs = (const uint32_t *)crash_buf;
2703 for (i = 0; i < ARRAY_SIZE(info.R); i++) {
2704 info.R[i] = p_regs[i];
2705 }
2706 #ifndef __ARM_ARCH_ISA_ARM
2707 info.MSP = p_regs[ARRAY_SIZE(info.R)];
2708 info.PSP = p_regs[ARRAY_SIZE(info.R) + 1];
2709 #endif
2710
2711 info.ID = HAL_TRACE_ASSERT_ID;
2712 info.CPU_ID = get_cpu_id_tag();
2713 #if (defined(DEBUG) || defined(REL_TRACE_ENABLE)) && defined(ASSERT_SHOW_FILE_FUNC)
2714 info.FILE = file;
2715 #elif (defined(DEBUG) || defined(REL_TRACE_ENABLE)) && defined(ASSERT_SHOW_FILE)
2716 info.FILE = scope;
2717 #else
2718 info.FILE = NULL;
2719 #endif
2720 #if (defined(DEBUG) || defined(REL_TRACE_ENABLE)) && defined(ASSERT_SHOW_FILE_FUNC)
2721 info.FUNC = func;
2722 #elif (defined(DEBUG) || defined(REL_TRACE_ENABLE)) && defined(ASSERT_SHOW_FUNC)
2723 info.FUNC = scope;
2724 #else
2725 info.FUNC = NULL;
2726 #endif
2727 #if (defined(DEBUG) || defined(REL_TRACE_ENABLE)) && (defined(ASSERT_SHOW_FILE_FUNC) || defined(ASSERT_SHOW_FILE) || defined(ASSERT_SHOW_FUNC))
2728 info.LINE = line;
2729 #else
2730 info.LINE = 0;
2731 #endif
2732 info.FMT = fmt;
2733 #ifndef __ARM_ARCH_ISA_ARM
2734 info.CONTROL = __get_CONTROL();
2735 #ifdef __ARM_ARCH_8M_MAIN__
2736 info.MSPLIM = __get_MSPLIM();
2737 info.PSPLIM = __get_PSPLIM();
2738 #endif
2739 #endif
2740
2741 *(volatile uint32_t *)RAM_BASE = (uint32_t)&info;
2742
2743 #ifdef ASSERT_MUTE_CODEC
2744 bool crash_mute = true;
2745 #ifdef CP_TRACE_ENABLE
2746 if (get_cpu_id()) {
2747 // Forbid CP to access CODEC
2748 crash_mute = false;
2749 }
2750 #endif
2751 if (crash_mute) {
2752 hal_codec_crash_mute();
2753 }
2754 #endif
2755
2756 #if (defined(DEBUG) || defined(REL_TRACE_ENABLE))
2757
2758 static const char POSSIBLY_UNUSED desc_file[] = "FILE : ";
2759 static const char POSSIBLY_UNUSED desc_func[] = "FUNCTION: ";
2760 static const char POSSIBLY_UNUSED desc_line[] = "LINE : ";
2761 int len;
2762 va_list ap;
2763
2764 #ifdef CP_TRACE_ENABLE
2765 // Release all the possible trace locks
2766 hal_trace_cp_force_unlock();
2767 #endif
2768 // Continue the trace
2769 hal_trace_force_continue();
2770
2771 #ifdef CRASH_DUMP_ENABLE
2772 bool full_dump = true;
2773
2774 #ifdef CP_TRACE_ENABLE
2775 if (get_cpu_id()) {
2776 full_dump = false;
2777 if (cp_notify_cb) {
2778 cp_notify_cb(HAL_TRACE_STATE_CRASH_ASSERT_START);
2779 }
2780 }
2781 #endif
2782
2783 if (full_dump) {
2784 #ifdef TRACE_TO_APP
2785 hal_trace_app_notify_callback(HAL_TRACE_STATE_CRASH_ASSERT_START);
2786 #endif
2787 }
2788 #endif
2789
2790 hal_trace_flush_buffer();
2791
2792 hal_sysfreq_req(HAL_SYSFREQ_USER_INIT, HAL_CMU_FREQ_52M);
2793
2794 len = hal_trace_print_time(TR_LEVEL_CRITICAL, TR_MODULE_NONE, &crash_buf[0], sizeof(crash_buf));
2795 if (len > 0) {
2796 hal_trace_output_linefeed();
2797 hal_trace_output((unsigned char *)crash_buf, len);
2798 }
2799 len = snprintf(&crash_buf[0], sizeof(crash_buf), NEW_LINE_STR "### ASSERT @ 0x%08X ###" NEW_LINE_STR, (unsigned)info.R[14]);
2800 hal_trace_output((unsigned char *)crash_buf, len);
2801
2802 #if defined(ASSERT_SHOW_FILE_FUNC) || defined(ASSERT_SHOW_FILE) || defined(ASSERT_SHOW_FUNC)
2803 const char separate_line[] = "----------------------------------------" NEW_LINE_STR;
2804 #ifdef ASSERT_SHOW_FILE
2805 const char *file = scope;
2806 #elif defined(ASSERT_SHOW_FUNC)
2807 const char *func = scope;
2808 #endif
2809
2810 #if defined(ASSERT_SHOW_FILE_FUNC) || defined(ASSERT_SHOW_FILE)
2811 hal_trace_output((const unsigned char *)desc_file, sizeof(desc_file) - 1);
2812 hal_trace_output((const unsigned char *)file, strlen(file));
2813 hal_trace_output_linefeed();
2814 #endif
2815
2816 #if defined(ASSERT_SHOW_FILE_FUNC) || defined(ASSERT_SHOW_FUNC)
2817 hal_trace_output((const unsigned char *)desc_func, sizeof(desc_func) - 1);
2818 hal_trace_output((const unsigned char *)func, strlen(func));
2819 hal_trace_output_linefeed();
2820 #endif
2821
2822 hal_trace_output((const unsigned char *)desc_line, sizeof(desc_func) - 1);
2823 len = snprintf(crash_buf, sizeof(crash_buf), "%u", line);
2824 hal_trace_output((const unsigned char *)crash_buf, len);
2825 hal_trace_output_linefeed();
2826
2827 hal_trace_output((unsigned char *)separate_line, sizeof(separate_line) - 1);
2828
2829 hal_trace_flush_buffer();
2830 #endif
2831
2832 va_start(ap, fmt);
2833 len = hal_trace_format_va(0, crash_buf, sizeof(crash_buf), fmt, ap);
2834 va_end(ap);
2835
2836 hal_trace_output((unsigned char *)crash_buf, len);
2837
2838 hal_trace_flush_buffer();
2839
2840 #ifdef ASSERT_VERBOSE_DUMP
2841 hal_trace_print_common_registers(info.R);
2842 hal_trace_print_special_stack_registers(info.MSP, info.PSP);
2843
2844 hal_trace_print_stack(info.R[13]);
2845
2846 hal_trace_print_backtrace(info.R[13], TRACE_BACKTRACE_SEARCH_WORD, TRACE_BACKTRACE_NUM);
2847
2848 hal_trace_output_linefeed();
2849
2850 hal_trace_flush_buffer();
2851 #endif
2852
2853 #ifdef CRASH_DUMP_ENABLE
2854 if (full_dump) {
2855 hal_trace_crash_dump_callback();
2856 hal_trace_flush_buffer();
2857 hal_sys_timer_delay(MS_TO_TICKS(5));
2858
2859 #ifdef CORE_DUMP
2860 {
2861 static CrashCatcherAssertRegisters regs;
2862
2863 regs.msp = info.MSP;
2864 regs.psp = info.PSP;
2865 regs.assertPSR = __get_xPSR();
2866 regs.R.r0 = info.R[0];
2867 regs.R.r1 = info.R[1];
2868 regs.R.r2 = info.R[2];
2869 regs.R.r3 = info.R[3];
2870 regs.R.r4 = info.R[4];
2871 regs.R.r5 = info.R[5];
2872 regs.R.r6 = info.R[6];
2873 regs.R.r7 = info.R[7];
2874 regs.R.r8 = info.R[8];
2875 regs.R.r9 = info.R[9];
2876 regs.R.r10 = info.R[10];
2877 regs.R.r11 = info.R[11];
2878 regs.R.r12 = info.R[12];
2879 regs.R.sp = info.R[13];
2880 regs.R.lr = info.R[14];
2881 /*
2882 * ASSERT's pc is not important, but who calling it is more important,
2883 * and just setting it to lr as normal assert dump.
2884 */
2885 regs.R.pc = info.R[14];
2886 regs.R.psr = regs.assertPSR;
2887
2888 AssertCatcher_Entry(®s);
2889 }
2890 hal_sys_timer_delay(MS_TO_TICKS(5));
2891 #endif
2892
2893 #ifdef TRACE_TO_APP
2894 hal_trace_app_notify_callback(HAL_TRACE_STATE_CRASH_END);
2895 #endif
2896 }
2897
2898 #ifdef CP_TRACE_ENABLE
2899 if (get_cpu_id()) {
2900 if (cp_notify_cb) {
2901 cp_notify_cb(HAL_TRACE_STATE_CRASH_END);
2902 }
2903 SAFE_PROGRAM_STOP();
2904 }
2905 #endif
2906 #endif // CRASH_DUMP_ENABLE
2907
2908 #endif // DEBUG || REL_TRACE_ENABLE
2909
2910 hal_trace_crash_end();
2911 }
2912
hal_trace_assert_dump(ASSERT_DUMP_ARGS)2913 void NORETURN NAKED hal_trace_assert_dump(ASSERT_DUMP_ARGS)
2914 {
2915 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) && !defined(DEBUG)
2916 // No way to read out the debug information. Just stop here
2917 SAFE_PROGRAM_STOP();
2918 #endif
2919
2920 #if defined(CHIP_BEST1501SIMU) || defined(CHIP_BEST1600SIMU)
2921 hal_cmu_simu_set_val(0xffffffff);
2922 #ifdef FPGA
2923 while(1);
2924 #endif
2925 #endif
2926
2927 asm volatile (
2928 "sub sp, sp, #4*(2+" TO_STRING(ASSERT_STACK_RESERVED) ");"
2929 ".cfi_def_cfa_offset 4*(2+" TO_STRING(ASSERT_STACK_RESERVED) ");"
2930 "push {r0-r5};"
2931 ".cfi_adjust_cfa_offset 4*6;"
2932 ".cfi_offset r0, -(4*(6+2+" TO_STRING(ASSERT_STACK_RESERVED) "));"
2933 ".cfi_offset r1, -(4*(5+2+" TO_STRING(ASSERT_STACK_RESERVED) "));"
2934 ".cfi_offset r2, -(4*(4+2+" TO_STRING(ASSERT_STACK_RESERVED) "));"
2935 ".cfi_offset r3, -(4*(3+2+" TO_STRING(ASSERT_STACK_RESERVED) "));"
2936 ".cfi_offset r4, -(4*(2+2+" TO_STRING(ASSERT_STACK_RESERVED) "));"
2937 ".cfi_offset r5, -(4*(1+2+" TO_STRING(ASSERT_STACK_RESERVED) "));"
2938 "ldr r0, =crash_buf;"
2939 "ldr r1, [sp];"
2940 "str r1, [r0], #4;"
2941 "ldr r1, [sp, #4];"
2942 "str r1, [r0], #4;"
2943 "stmia r0!, {r2-r12};"
2944 "add r1, sp, #4*(6+2+" TO_STRING(ASSERT_STACK_RESERVED) ");"
2945 "movs r5, r1;"
2946 "str r1, [r0], #4;"
2947 "str lr, [r0], #4;"
2948 #ifndef __ARM_ARCH_ISA_ARM
2949 // Check CONTROL.SPSEL (bit[1])
2950 "mrs r3, control;"
2951 "tst r3, #0x02;"
2952 "itte ne;"
2953 // r1 is still the original SP
2954 "movne r2, r1;"
2955 "mrsne r1, msp;"
2956 "mrseq r2, psp;"
2957 #endif
2958 "str r1, [r0], #4;"
2959 "str r2, [r0], #4;"
2960 #if (ASSERT_STACK_ARG_WORD != 8)
2961 #error "Bad ASSERT_STACK_ARG_WORD: should be 8"
2962 #endif
2963 // Save assert arguments in stack (ASSERT_STACK_ARG_WORD)
2964 "add r4, sp, #4*6;"
2965 "ldmia r5!, {r0-r3};"
2966 "stmia r4!, {r0-r3};"
2967 "ldmia r5!, {r0-r3};"
2968 "stmia r4!, {r0-r3};"
2969 "str lr, [r4];"
2970 ".cfi_offset lr, -(4*(2+" TO_STRING(STACK_DUMP_CNT_PREV) "));"
2971 "pop {r0-r5};"
2972 ".cfi_restore r5;"
2973 ".cfi_restore r4;"
2974 ".cfi_restore r3;"
2975 ".cfi_restore r2;"
2976 ".cfi_restore r1;"
2977 ".cfi_restore r0;"
2978 ".cfi_adjust_cfa_offset -4*6;"
2979 "bl hal_trace_assert_dump_internal;"
2980 );
2981 }
2982
2983 #ifdef FAULT_DUMP
hal_trace_fill_exception_info(struct EXCEPTION_INFO_T * info,const uint32_t * regs,const uint32_t * extra,uint32_t extra_len)2984 static void hal_trace_fill_exception_info(struct EXCEPTION_INFO_T *info, const uint32_t *regs, const uint32_t *extra, uint32_t extra_len)
2985 {
2986 info->ID = HAL_TRACE_EXCEPTION_ID;
2987 info->CPU_ID = get_cpu_id_tag();
2988 info->REGS = regs;
2989 #ifdef __ARM_ARCH_ISA_ARM
2990 info->extra = extra;
2991 info->extra_len = extra_len;
2992 #else
2993 info->MSP = regs[18];
2994 info->PSP = __get_PSP();
2995 info->PRIMASK = (regs[17] & 0xFF);
2996 info->FAULTMASK = ((regs[17] >> 8) & 0xFF);
2997 info->BASEPRI = ((regs[17] >> 16) & 0xFF);
2998 info->CONTROL = ((regs[17] >> 24) & 0xFF);
2999 info->ICSR = SCB->ICSR;
3000 info->AIRCR = SCB->AIRCR;
3001 info->SCR = SCB->SCR;
3002 info->CCR = SCB->CCR;
3003 info->SHCSR = SCB->SHCSR;
3004 info->CFSR = SCB->CFSR;
3005 info->HFSR = SCB->HFSR;
3006 info->AFSR = SCB->AFSR;
3007 info->DFSR = SCB->DFSR;
3008 info->MMFAR = SCB->MMFAR;
3009 info->BFAR = SCB->BFAR;
3010 #ifdef __ARM_ARCH_8M_MAIN__
3011 info->MSPLIM = __get_MSPLIM();
3012 info->PSPLIM = __get_PSPLIM();
3013 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
3014 info->SFSR = SAU->SFSR;
3015 info->SFAR = SAU->SFAR;
3016 info->MSP_NS = __TZ_get_MSP_NS();
3017 info->PSP_NS = __TZ_get_PSP_NS();
3018 info->MSPLIM_NS = __TZ_get_MSPLIM_NS();
3019 info->PSPLIM_NS = __TZ_get_PSPLIM_NS();
3020 info->PRIMASK_NS = __TZ_get_PRIMASK_NS();
3021 info->FAULTMASK_NS = __TZ_get_FAULTMASK_NS();
3022 info->BASEPRI_NS = __TZ_get_BASEPRI_NS();
3023 info->CONTROL_NS = __TZ_get_CONTROL_NS();
3024 #endif
3025 #endif
3026 #endif
3027 }
3028
3029 #if (defined(DEBUG) || defined(REL_TRACE_ENABLE))
3030 #ifdef __ARM_ARCH_ISA_ARM
hal_trace_print_fault_info_ca(const struct EXCEPTION_INFO_T * info)3031 static void hal_trace_print_fault_info_ca(const struct EXCEPTION_INFO_T *info)
3032 {
3033 const struct FAULT_REGS_T *fregs;
3034 const uint32_t *extra;
3035 //uint32_t extra_len;
3036 enum EXCEPTION_ID_T id;
3037 int len;
3038 uint32_t val;
3039 const char *desc;
3040
3041 fregs = (const struct FAULT_REGS_T*)info->REGS;
3042 extra = info->extra;
3043 //extra_len = info->extra_len;
3044
3045 id = (enum EXCEPTION_ID_T)extra[0];
3046
3047 len = snprintf(crash_buf, sizeof(crash_buf), "PC =%08X", (unsigned)fregs->r[15]);
3048 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", ExceptionNumber=%d" NEW_LINE_STR, id);
3049 hal_trace_output((unsigned char *)crash_buf, len);
3050
3051 hal_trace_print_common_registers(fregs->r);
3052
3053 len = snprintf(crash_buf, sizeof(crash_buf), "SPSR=%08X", (unsigned)fregs->spsr);
3054 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", APSR=%c%c%c%c%c",
3055 (fregs->spsr & (1 << 31)) ? 'N' : 'n',
3056 (fregs->spsr & (1 << 30)) ? 'Z' : 'z',
3057 (fregs->spsr & (1 << 29)) ? 'C' : 'c',
3058 (fregs->spsr & (1 << 28)) ? 'V' : 'v',
3059 (fregs->spsr & (1 << 27)) ? 'Q' : 'q'
3060 );
3061 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", XC=%c%c%c%c%c",
3062 (fregs->spsr & (1 << 9)) ? 'E' : 'e',
3063 (fregs->spsr & (1 << 8)) ? 'A' : 'a',
3064 (fregs->spsr & (1 << 7)) ? 'I' : 'i',
3065 (fregs->spsr & (1 << 6)) ? 'F' : 'f',
3066 (fregs->spsr & (1 << 5)) ? 'T' : 't'
3067 );
3068 val = fregs->spsr & 0x1F;
3069 if (val == 0x10) {
3070 desc = "USR";
3071 } else if (val == 0x11) {
3072 desc = "FIQ";
3073 } else if (val == 0x12) {
3074 desc = "IRQ";
3075 } else if (val == 0x13) {
3076 desc = "SVC";
3077 } else if (val == 0x16) {
3078 desc = "MON";
3079 } else if (val == 0x17) {
3080 desc = "ABT";
3081 } else if (val == 0x1A) {
3082 desc = "HYP";
3083 } else if (val == 0x1B) {
3084 desc = "UND";
3085 } else if (val == 0x1F) {
3086 desc = "SYS";
3087 } else {
3088 desc = "UNKNOWN";
3089 }
3090 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", MODE=%02X (%s)", (unsigned)val, desc);
3091 hal_trace_output((unsigned char *)crash_buf, len);
3092 hal_trace_output_linefeed();
3093 hal_trace_output_linefeed();
3094
3095 hal_trace_flush_buffer();
3096
3097 if (id == EXCEPTION_UNDEF) {
3098 } else if (id == EXCEPTION_SVC) {
3099 } else if (id == EXCEPTION_PABT) {
3100 } else if (id == EXCEPTION_DABT) {
3101 } else {
3102 }
3103 }
3104 #else
hal_trace_print_fault_info_cm(const struct EXCEPTION_INFO_T * info)3105 static void hal_trace_print_fault_info_cm(const struct EXCEPTION_INFO_T *info)
3106 {
3107 const uint32_t *regs;
3108 int len;
3109 uint32_t val;
3110
3111 regs = info->REGS;
3112
3113 len = snprintf(crash_buf, sizeof(crash_buf), "PC =%08X", (unsigned)regs[15]);
3114 val = __get_IPSR();
3115 if (val == 0) {
3116 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", ThreadMode");
3117 } else {
3118 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", ExceptionNumber=D'%d", (int)val - 16);
3119 }
3120 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", EXC_RETURN=%08X" NEW_LINE_STR, regs[19]);
3121 hal_trace_output((unsigned char *)crash_buf, len);
3122
3123 hal_trace_print_common_registers(regs);
3124 hal_trace_print_special_stack_registers(info->MSP, info->PSP);
3125 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
3126 hal_trace_print_special_stack_registers_ns(info->MSP_NS, info->PSP_NS);
3127 #endif
3128 hal_trace_output_linefeed();
3129
3130 len = snprintf(crash_buf, sizeof(crash_buf), "PRIMASK =%02X, FAULTMASK =%02X, BASEPRI =%02X, CONTROL =%02X" NEW_LINE_STR,
3131 (unsigned)info->PRIMASK, (unsigned)info->FAULTMASK, (unsigned)info->BASEPRI, (unsigned)info->CONTROL);
3132 hal_trace_output((unsigned char *)crash_buf, len);
3133 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
3134 len = snprintf(crash_buf, sizeof(crash_buf), "PRIMASK_NS=%02X, FAULTMASK_NS=%02X, BASEPRI_NS=%02X, CONTROL_NS=%02X" NEW_LINE_STR,
3135 (unsigned)info->PRIMASK_NS, (unsigned)info->FAULTMASK_NS, (unsigned)info->BASEPRI_NS, (unsigned)info->CONTROL_NS);
3136 hal_trace_output((unsigned char *)crash_buf, len);
3137 #endif
3138 hal_trace_output_linefeed();
3139
3140 len = snprintf(crash_buf, sizeof(crash_buf), "XPSR=%08X", (unsigned)regs[16]);
3141 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", APSR=%c%c%c%c%c",
3142 (regs[16] & (1 << 31)) ? 'N' : 'n',
3143 (regs[16] & (1 << 30)) ? 'Z' : 'z',
3144 (regs[16] & (1 << 29)) ? 'C' : 'c',
3145 (regs[16] & (1 << 28)) ? 'V' : 'v',
3146 (regs[16] & (1 << 27)) ? 'Q' : 'q'
3147 );
3148 val = regs[16] & 0x1FF;
3149 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", EPSR=%08X, IPSR=%03X", (unsigned)(regs[16] & 0x0700FC00), (unsigned)val);
3150 if (val == 0) {
3151 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (NoException)");
3152 }
3153 hal_trace_output((unsigned char *)crash_buf, len);
3154 hal_trace_output_linefeed();
3155 hal_trace_output_linefeed();
3156
3157 hal_trace_flush_buffer();
3158
3159 len = snprintf(crash_buf, sizeof(crash_buf), "ICSR =%08X, AIRCR=%08X, SCR =%08X, CCR =%08X" NEW_LINE_STR,
3160 (unsigned)info->ICSR, (unsigned)info->AIRCR, (unsigned)info->SCR, (unsigned)info->CCR);
3161 hal_trace_output((unsigned char *)crash_buf, len);
3162
3163 len = snprintf(crash_buf, sizeof(crash_buf), "SHCSR=%08X, CFSR =%08X, HFSR =%08X, AFSR =%08X" NEW_LINE_STR,
3164 (unsigned)info->SHCSR, (unsigned)info->CFSR, (unsigned)info->HFSR, (unsigned)info->AFSR);
3165 hal_trace_output((unsigned char *)crash_buf, len);
3166
3167 len = snprintf(crash_buf, sizeof(crash_buf), "DFSR =%08X", (unsigned)info->DFSR);
3168 hal_trace_output((unsigned char *)crash_buf, len);
3169 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
3170 len = snprintf(crash_buf, sizeof(crash_buf), ", SFSR =%08X", (unsigned)info->SFSR);
3171 hal_trace_output((unsigned char *)crash_buf, len);
3172 #endif
3173 hal_trace_output_linefeed();
3174
3175 len = snprintf(crash_buf, sizeof(crash_buf), "MMFAR=%08X, BFAR =%08X",
3176 (unsigned)info->MMFAR, (unsigned)info->BFAR);
3177 hal_trace_output((unsigned char *)crash_buf, len);
3178 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
3179 len = snprintf(crash_buf, sizeof(crash_buf), ", SFAR =%08X", (unsigned)info->SFAR);
3180 hal_trace_output((unsigned char *)crash_buf, len);
3181 #endif
3182 hal_trace_output_linefeed();
3183 hal_trace_output_linefeed();
3184
3185 if (info->HFSR & (1 << 30)) {
3186 len = snprintf(crash_buf, sizeof(crash_buf), "(Escalation HardFault)" NEW_LINE_STR);
3187 hal_trace_output((unsigned char *)crash_buf, len);
3188 }
3189
3190 len = snprintf(crash_buf, sizeof(crash_buf), "FaultInfo :");
3191 if ((info->SHCSR & 0x13F) == 0) {
3192 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (None)");
3193 } else {
3194 if (info->SHCSR & (1 << 0)) {
3195 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (MemFault)");
3196 }
3197 if (info->SHCSR & (1 << 1)) {
3198 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (BusFault)");
3199 }
3200 #ifdef __ARM_ARCH_8M_MAIN__
3201 if (info->SHCSR & (1 << 2)) {
3202 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (HardFault)");
3203 }
3204 #endif
3205 if (info->SHCSR & (1 << 3)) {
3206 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (UsageFault)");
3207 }
3208 #ifdef __ARM_ARCH_8M_MAIN__
3209 if (info->SHCSR & (1 << 4)) {
3210 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (SecureFault)");
3211 }
3212 if (info->SHCSR & (1 << 5)) {
3213 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (NMI)");
3214 }
3215 #endif
3216 if (info->SHCSR & (1 << 8)) {
3217 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Monitor)");
3218 }
3219 }
3220 hal_trace_output((unsigned char *)crash_buf, len);
3221 hal_trace_output_linefeed();
3222
3223 len = snprintf(crash_buf, sizeof(crash_buf), "FaultCause :");
3224 if (info->CFSR == 0) {
3225 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (None)");
3226 } else {
3227 if (info->CFSR & (1 << 0)) {
3228 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Instruction access violation)");
3229 }
3230 if (info->CFSR & (1 << 1)) {
3231 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Data access violation)");
3232 }
3233 if (info->CFSR & (1 << 3)) {
3234 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (MemFault on unstacking for a return from exception)");
3235 }
3236 if (info->CFSR & (1 << 4)) {
3237 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (MemFault on stacking for exception entry)");
3238 }
3239 if (info->CFSR & (1 << 5)) {
3240 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (MemFault during floating-point lazy state preservation)");
3241 }
3242 if (info->CFSR & (1 << 7)) {
3243 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (MMFAR valid)");
3244 }
3245 if (len) {
3246 hal_trace_output((unsigned char *)crash_buf, len);
3247 hal_trace_flush_buffer();
3248 len = 0;
3249 }
3250 if (info->CFSR & (1 << 8)) {
3251 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Instruction bus error)");
3252 }
3253 if (info->CFSR & (1 << 9)) {
3254 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Precise data bus error)");
3255 }
3256 #ifndef __ARM_ARCH_8M_MAIN__
3257 if (info->CFSR & (1 << 10)) {
3258 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Imprecise data bus error)");
3259 }
3260 #endif
3261 if (info->CFSR & (1 << 11)) {
3262 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (BusFault on unstacking for a return from exception)");
3263 }
3264 if (info->CFSR & (1 << 12)) {
3265 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (BusFault on stacking for exception entry)");
3266 }
3267 if (info->CFSR & (1 << 13)) {
3268 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (BusFault during floating-point lazy state preservation)");
3269 }
3270 if (info->CFSR & (1 << 15)) {
3271 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (BFAR valid)");
3272 }
3273 if (len) {
3274 hal_trace_output((unsigned char *)crash_buf, len);
3275 hal_trace_flush_buffer();
3276 len = 0;
3277 }
3278 if (info->CFSR & (1 << 16)) {
3279 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Undefined instruction UsageFault)");
3280 }
3281 if (info->CFSR & (1 << 17)) {
3282 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Invalid state UsageFault)");
3283 }
3284 if (info->CFSR & (1 << 18)) {
3285 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Invalid PC load by EXC_RETURN UsageFault)");
3286 }
3287 if (info->CFSR & (1 << 19)) {
3288 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (No coprocessor UsageFault)");
3289 }
3290 #ifdef __ARM_ARCH_8M_MAIN__
3291 if (info->CFSR & (1 << 20)) {
3292 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Stack overflow UsageFault)");
3293 }
3294 #endif
3295 if (info->CFSR & (1 << 24)) {
3296 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Unaligned access UsageFault)");
3297 }
3298 if (info->CFSR & (1 << 25)) {
3299 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Divide by zero UsageFault)");
3300 }
3301 }
3302 hal_trace_output((unsigned char *)crash_buf, len);
3303 hal_trace_output_linefeed();
3304
3305 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
3306 len = snprintf(crash_buf, sizeof(crash_buf), "SecFaultCause:");
3307 if (info->SFSR == 0) {
3308 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (None)");
3309 } else {
3310 if (info->SFSR & (1 << 0)) {
3311 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Invalid entry point)");
3312 }
3313 if (info->SFSR & (1 << 1)) {
3314 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Invalid integrity signature)");
3315 }
3316 if (info->SFSR & (1 << 2)) {
3317 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Invalid excpetion return)");
3318 }
3319 if (info->SFSR & (1 << 3)) {
3320 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Attribution unit violation)");
3321 }
3322 if (info->SFSR & (1 << 4)) {
3323 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Invalid transition)");
3324 }
3325 if (info->SFSR & (1 << 5)) {
3326 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Lazy floating-point state preservation error)");
3327 }
3328 if (info->SFSR & (1 << 6)) {
3329 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (SFAR valid)");
3330 }
3331 if (info->SFSR & (1 << 7)) {
3332 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Lazy state error)");
3333 }
3334 }
3335 hal_trace_output((unsigned char *)crash_buf, len);
3336 hal_trace_output_linefeed();
3337 #endif
3338
3339 len = snprintf(crash_buf, sizeof(crash_buf), "DebugEvent :");
3340 if (info->DFSR == 0) {
3341 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (None)");
3342 } else {
3343 if (info->DFSR & (1 << 0)) {
3344 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Halted)");
3345 }
3346 if (info->DFSR & (1 << 2)) {
3347 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Data Watchpoint Match)");
3348 }
3349 /*scan the all dwt functions*/
3350 volatile uint32_t *func = &DWT->FUNCTION0;
3351 uint32_t func_num = (DWT->CTRL >> 28) & 0xf;
3352
3353 for (int i = 0; i < func_num; i++) {
3354 if (*func & DWT_FUNCTION_MATCHED_Msk) {
3355 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Function %d matched)", i);
3356 }
3357 func += 4;
3358 }
3359 }
3360
3361 hal_trace_output((unsigned char *)crash_buf, len);
3362 hal_trace_output_linefeed();
3363 }
3364 #endif
3365
hal_trace_print_fault_info(const struct EXCEPTION_INFO_T * info)3366 static void hal_trace_print_fault_info(const struct EXCEPTION_INFO_T *info)
3367 {
3368 #ifdef __ARM_ARCH_ISA_ARM
3369 hal_trace_print_fault_info_ca(info);
3370 #else
3371 hal_trace_print_fault_info_cm(info);
3372 #endif
3373 }
3374 #endif // DEBUG || REL_TRACE_ENABLE
3375
hal_trace_fault_dump(const uint32_t * regs,const uint32_t * extra,uint32_t extra_len)3376 void hal_trace_fault_dump(const uint32_t *regs, const uint32_t *extra, uint32_t extra_len)
3377 {
3378 struct EXCEPTION_INFO_T info;
3379
3380 crash_occurs[get_cpu_id()] = true;
3381 #if defined(CHIP_BEST1501SIMU) || defined(CHIP_BEST1600SIMU)
3382 hal_cmu_simu_set_val(0xdddddddd);
3383 #endif
3384
3385 int_lock_global();
3386
3387 hal_trace_fill_exception_info(&info, regs, extra, extra_len);
3388
3389 *(volatile uint32_t *)RAM_BASE = (uint32_t)&info;
3390
3391 #if (defined(DEBUG) || defined(REL_TRACE_ENABLE))
3392
3393 static const char title[] = NEW_LINE_STR "### EXCEPTION ###" NEW_LINE_STR;
3394 int len;
3395
3396 #ifdef CP_TRACE_ENABLE
3397 // Release all the possible trace locks
3398 hal_trace_cp_force_unlock();
3399 #endif
3400 // Continue the trace
3401 hal_trace_force_continue();
3402
3403 #ifdef CRASH_DUMP_ENABLE
3404 bool full_dump = true;
3405
3406 #ifdef CP_TRACE_ENABLE
3407 if (get_cpu_id()) {
3408 full_dump = false;
3409 if (cp_notify_cb) {
3410 cp_notify_cb(HAL_TRACE_STATE_CRASH_FAULT_START);
3411 }
3412 }
3413 #endif
3414
3415 if (full_dump) {
3416 #ifdef TRACE_TO_APP
3417 hal_trace_app_notify_callback(HAL_TRACE_STATE_CRASH_FAULT_START);
3418 #endif
3419 }
3420 #endif
3421
3422 hal_trace_flush_buffer();
3423
3424 hal_sysfreq_req(HAL_SYSFREQ_USER_INIT, HAL_CMU_FREQ_52M);
3425
3426 len = hal_trace_print_time(TR_LEVEL_CRITICAL, TR_MODULE_NONE, &crash_buf[0], sizeof(crash_buf));
3427 if (len > 0) {
3428 hal_trace_output_linefeed();
3429 hal_trace_output((unsigned char *)crash_buf, len);
3430 }
3431 hal_trace_output((unsigned char *)title, sizeof(title) - 1);
3432
3433 hal_trace_print_fault_info(&info);
3434
3435 hal_trace_flush_buffer();
3436
3437 hal_trace_print_stack(regs[13]);
3438
3439 hal_trace_print_backtrace(regs[13], TRACE_BACKTRACE_SEARCH_WORD, TRACE_BACKTRACE_NUM);
3440
3441 hal_trace_output_linefeed();
3442
3443 hal_trace_flush_buffer();
3444
3445 #ifdef CRASH_DUMP_ENABLE
3446 if (full_dump) {
3447 hal_trace_crash_dump_callback();
3448 hal_trace_flush_buffer();
3449
3450 #ifndef __ARM_ARCH_ISA_ARM
3451 #ifdef TRACE_TO_APP
3452 // Crash-Dump "Lite-Version"
3453 if (app_crash_custom_cb) {
3454 uint32_t *stack;
3455 app_crash_custom_cb((unsigned char *)regs,
3456 CRASH_DUMP_REGISTERS_NUM_BYTES);
3457 stack = (uint32_t *)(__get_MSP() & ~3);
3458 app_crash_custom_cb((unsigned char *)stack,
3459 ((CRASH_DUMP_STACK_NUM_BYTES)/2));
3460 stack = (uint32_t *)(__get_PSP() & ~3);
3461 app_crash_custom_cb((unsigned char *)stack,
3462 ((CRASH_DUMP_STACK_NUM_BYTES)/2));
3463 }
3464 #endif
3465
3466 #ifdef CORE_DUMP
3467 {
3468 static CrashCatcherExceptionRegisters eregs;
3469
3470 eregs.msp = info.MSP;
3471 eregs.psp = info.PSP;
3472 eregs.exceptionPSR = regs[16] & 0x0700FE00;
3473 eregs.r4 = regs[4];
3474 eregs.r5 = regs[5];
3475 eregs.r6 = regs[6];
3476 eregs.r7 = regs[7];
3477 eregs.r8 = regs[8];
3478 eregs.r9 = regs[9];
3479 eregs.r10 = regs[10];
3480 eregs.r11 = regs[11];
3481 eregs.exceptionLR = regs[19];
3482 CrashCatcher_Entry( &eregs);
3483 }
3484 #endif
3485 #endif // !__ARM_ARCH_ISA_ARM
3486
3487 #ifdef TRACE_TO_APP
3488 hal_trace_app_notify_callback(HAL_TRACE_STATE_CRASH_END);
3489 #endif
3490 }
3491
3492 #ifdef CP_TRACE_ENABLE
3493 if (get_cpu_id()) {
3494 if (cp_notify_cb) {
3495 cp_notify_cb(HAL_TRACE_STATE_CRASH_END);
3496 }
3497 SAFE_PROGRAM_STOP();
3498 }
3499 #endif
3500 #endif // CRASH_DUMP_ENABLE
3501
3502 #endif // DEBUG || REL_TRACE_ENABLE
3503
3504 hal_trace_crash_end();
3505 }
3506
3507 #ifndef __ARM_ARCH_ISA_ARM
hal_trace_fault_handler(void)3508 static void NAKED hal_trace_fault_handler(void)
3509 {
3510 // TODO: Save FP registers (and check lazy floating-point context preservation)
3511
3512 // Registers saved in SP
3513 // R0-R15 PSR SPECIAL_REGS MSP EXC_RETURN
3514
3515 asm volatile (
3516 // Get special_regs(primask/faultmask/basepri/control)
3517 "mrs r0, primask;"
3518 "mrs r1, faultmask;"
3519 "mrs r2, basepri;"
3520 "mrs r3, control;"
3521 "bfi r12, r0, #0, #8;"
3522 "bfi r12, r1, #8, #8;"
3523 "bfi r12, r2, #16, #8;"
3524 "bfi r12, r3, #24, #8;"
3525 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
3526 // Check EXC_RETURN.S (bit[6])
3527 "tst lr, #0x40;"
3528 "bne _get_sec_sp;"
3529 // EXC_RETURN.ES must be 1 here
3530 // Check EXC_RETURN.MODE (bit[3]) and CONTROL.SPSEL (bit[1])
3531 "ubfx r3, lr, #3, #1;"
3532 "mrs r2, control_ns;"
3533 "ubfx r2, r2, #1, #1;"
3534 "ands r3, r2;"
3535 "ite ne;"
3536 // Using PSP_NS
3537 "mrsne r3, psp_ns;"
3538 // Using MSP_NS
3539 "mrseq r3, msp_ns;"
3540 "b _save_msp_lr;"
3541 "_get_sec_sp:;"
3542 #endif
3543 // Check EXC_RETURN.MODE (bit[3]) and EXC_RETURN.SPSEL (bit[2])
3544 "and r3, lr, #0x0C;"
3545 "teq r3, #0x0C;"
3546 "ite eq;"
3547 // Using PSP
3548 "mrseq r3, psp;"
3549 // Using MSP
3550 "mrsne r3, msp;"
3551 "_save_msp_lr:;"
3552 // Save original MSP and current exception lr
3553 "mrs r0, msp;"
3554 "push {r0, lr};"
3555 ".cfi_def_cfa_offset 4*2;"
3556 ".cfi_rel_offset lr, 4*1;"
3557 #ifdef ARM_CMNS
3558 // -- Check EXC_RETURN.S (bit[6])
3559 "tst lr, #0x40;"
3560 "beq _check_fp_cntx;"
3561 // Save special_regs(primask/faultmask/basepri/control)
3562 "str r12, [sp, #-4]!;"
3563 // Save 0 as psr
3564 "mov r1, 0;"
3565 "str r1, [sp, #-4]!;"
3566 // Save 0 as pc
3567 "str r1, [sp, #-4]!;"
3568 // Save 0 as lr
3569 "str r1, [sp, #-4]!;"
3570 // Save sp
3571 "str r0, [sp, #-4]!;"
3572 // Save 0 as r0-12
3573 "str r1, [sp, #-4]!;"
3574 "str r1, [sp, #-4]!;"
3575 "str r1, [sp, #-4]!;"
3576 "str r1, [sp, #-4]!;"
3577 "str r1, [sp, #-4]!;"
3578 "str r1, [sp, #-4]!;"
3579 "str r1, [sp, #-4]!;"
3580 "str r1, [sp, #-4]!;"
3581 "str r1, [sp, #-4]!;"
3582 "str r1, [sp, #-4]!;"
3583 "str r1, [sp, #-4]!;"
3584 "str r1, [sp, #-4]!;"
3585 "str r1, [sp, #-4]!;"
3586 "b _call_fault_handler;"
3587 #elif defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
3588 // -- Check EXC_RETURN.DCRS (bit[5])
3589 "tst lr, #0x20;"
3590 "beq _get_callee_saved_regs;"
3591 // -- Check EXC_RETURN.ES (bit[0])
3592 "tst lr, #0x01;"
3593 "bne _check_fp_cntx;"
3594 "_get_callee_saved_regs:;"
3595 "add r3, #4*2;"
3596 "ldm r3!, {r4-r11};"
3597 #endif
3598 "_check_fp_cntx:;"
3599 // Check EXC_RETURN.FType (bit[4])
3600 "tst lr, #0x10;"
3601 "ite eq;"
3602 // FPU context saved
3603 "moveq r1, #1;"
3604 // No FPU context
3605 "movne r1, #0;"
3606 // Make room for r0-r15,psr,special_regs(primask/faultmask/basepri/control)
3607 "sub sp, #4*18;"
3608 ".cfi_adjust_cfa_offset 4*18;"
3609 // Save r4-r11
3610 "add r0, sp, #4*4;"
3611 "stm r0, {r4-r11};"
3612 ".cfi_rel_offset r4, 4*4;"
3613 ".cfi_rel_offset r5, 4*5;"
3614 ".cfi_rel_offset r6, 4*6;"
3615 ".cfi_rel_offset r7, 4*7;"
3616 ".cfi_rel_offset r8, 4*8;"
3617 ".cfi_rel_offset r9, 4*9;"
3618 ".cfi_rel_offset r10, 4*10;"
3619 ".cfi_rel_offset r11, 4*11;"
3620 // Save r0-r3
3621 "ldm r3, {r4-r7};"
3622 "stm sp, {r4-r7};"
3623 ".cfi_rel_offset r0, 4*0;"
3624 ".cfi_rel_offset r1, 4*1;"
3625 ".cfi_rel_offset r2, 4*2;"
3626 ".cfi_rel_offset r3, 4*3;"
3627 // Save r12
3628 "ldr r0, [r3, #4*4];"
3629 "str r0, [sp, #4*12];"
3630 ".cfi_rel_offset r12, 4*12;"
3631 // Save sp
3632 "teq r1, 0;"
3633 "itt eq;"
3634 "addeq r0, r3, #4*8;"
3635 "beq _done_stack_frame;"
3636 "add r0, r3, #4*(8+18);"
3637 "_done_stack_frame:;"
3638 // -- Check RETPSR.SPREALIGN (bit[9])
3639 "ldr r4, [r3, #4*7];"
3640 "tst r4, #(1 << 9);"
3641 "it ne;"
3642 "addne r0, #4;"
3643 "str r0, [sp, #4*13];"
3644 // Save lr
3645 "ldr r0, [r3, #4*5];"
3646 "str r0, [sp, #4*14];"
3647 // Save pc
3648 "ldr r0, [r3, #4*6];"
3649 "str r0, [sp, #4*15];"
3650 // Save PSR
3651 "ldr r0, [r3, #4*7];"
3652 "str r0, [sp, #4*16];"
3653 // Save special_regs(primask/faultmask/basepri/control)
3654 "str r12, [sp, #4*17];"
3655 "_call_fault_handler:;"
3656 // Invoke the fault handler
3657 "mov r0, sp;"
3658 "mov r1, 0;"
3659 "mov r2, 0;"
3660 "ldr r3, =hal_trace_fault_dump;"
3661 "blx r3;"
3662 // Restore r4-r7
3663 "add r0, sp, #4*4;"
3664 "ldm r0, {r4-r7};"
3665 // Restore sp
3666 "add sp, #18*4;"
3667 ".cfi_adjust_cfa_offset -4*18;"
3668 "pop {r0, lr};"
3669 ".cfi_adjust_cfa_offset -4*2;"
3670 ".cfi_restore lr;"
3671 ".cfi_def_cfa_offset 0;"
3672 "bx lr;"
3673 ""
3674 );
3675 }
3676 #endif
3677 #endif
3678
3679 //==============================================================================
3680 // TRACE RX
3681 //==============================================================================
3682
3683 #if (defined(DEBUG) || defined(REL_TRACE_ENABLE))
3684
3685 enum HAL_TRACE_RX_STATE_T {
3686 HAL_TRACE_RX_STATE_CLOSED = 0,
3687 HAL_TRACE_RX_STATE_OPENED,
3688 HAL_TRACE_RX_STATE_SLEEP,
3689 };
3690
3691 static enum HAL_TRACE_RX_STATE_T trace_rx_state;
3692 static uint8_t *trace_rx_buf;
3693 static uint32_t trace_rx_len;
3694 static HAL_TRACE_RX_CALLBACK_T trace_rx_cb;
3695
hal_trace_rx_start(void)3696 static void hal_trace_rx_start(void)
3697 {
3698 uint32_t desc_cnt = 1;
3699 union HAL_UART_IRQ_T mask;
3700 struct HAL_DMA_DESC_T dma_desc_rx;
3701 int ret;
3702
3703 mask.reg = 0;
3704 mask.BE = 0;
3705 mask.FE = 0;
3706 mask.OE = 0;
3707 mask.PE = 0;
3708 mask.RT = 1;
3709
3710 // TODO: Use stream mode
3711 ret = hal_uart_dma_recv_mask(trace_uart, trace_rx_buf, trace_rx_len, &dma_desc_rx, &desc_cnt, &mask);
3712 ASSERT(ret == 0, "%s: Failed to start dma rx: %d", __func__, ret);
3713 }
3714
hal_trace_rx_stop(void)3715 static void hal_trace_rx_stop(void)
3716 {
3717 union HAL_UART_IRQ_T mask;
3718
3719 hal_uart_stop_dma_recv(trace_uart);
3720
3721 mask.reg = 0;
3722 hal_uart_irq_set_mask(trace_uart, mask);
3723 }
3724
hal_trace_rx_irq_handler(uint32_t xfer_size,int dma_error,union HAL_UART_IRQ_T status)3725 static void hal_trace_rx_irq_handler(uint32_t xfer_size, int dma_error, union HAL_UART_IRQ_T status)
3726 {
3727 POSSIBLY_UNUSED int res = 0;
3728
3729 if (trace_rx_cb == NULL) {
3730 return;
3731 }
3732
3733 if (xfer_size) {
3734 res = trace_rx_cb(trace_rx_buf, xfer_size);
3735 //TRACE(0, "%s: trace_rx_cb (%p) prase data error: %d", __func__, trace_rx_cb, res);
3736 }
3737 if (xfer_size || status.RT) {
3738 if (trace_rx_state == HAL_TRACE_RX_STATE_OPENED) {
3739 hal_trace_rx_start();
3740 }
3741 }
3742 }
3743
hal_trace_rx_open(unsigned char * buf,unsigned int len,HAL_TRACE_RX_CALLBACK_T rx_callback)3744 int hal_trace_rx_open(unsigned char *buf, unsigned int len, HAL_TRACE_RX_CALLBACK_T rx_callback)
3745 {
3746 if (buf == NULL || len == 0 || rx_callback == NULL) {
3747 return 1;
3748 }
3749
3750 if (!hal_trace_is_uart_transport(trace_transport)) {
3751 return 2;
3752 }
3753
3754 #if (TRACE_BUF_SIZE <= 0)
3755 int ret;
3756
3757 trace_uart = HAL_UART_ID_0 + (trace_transport - HAL_TRACE_TRANSPORT_UART0);
3758 ret = hal_uart_open(trace_uart, &uart_cfg);
3759 if (ret) {
3760 return ret;
3761 }
3762 #endif
3763
3764 trace_rx_buf = buf;
3765 trace_rx_len = len;
3766 trace_rx_cb = rx_callback;
3767
3768 hal_uart_irq_set_dma_handler(trace_uart, hal_trace_rx_irq_handler, NULL);
3769
3770 if (trace_rx_state != HAL_TRACE_RX_STATE_OPENED) {
3771 trace_rx_state = HAL_TRACE_RX_STATE_OPENED;
3772 hal_trace_rx_start();
3773 }
3774
3775 return 0;
3776 }
3777
hal_trace_rx_close(void)3778 int hal_trace_rx_close(void)
3779 {
3780 uint32_t lock;
3781
3782 if (!hal_trace_is_uart_transport(trace_transport)) {
3783 return 2;
3784 }
3785
3786 lock = int_lock();
3787 hal_trace_rx_stop();
3788 trace_rx_state = HAL_TRACE_RX_STATE_CLOSED;
3789 int_unlock(lock);
3790
3791 trace_rx_buf = NULL;
3792 trace_rx_len = 0;
3793 trace_rx_cb = NULL;
3794
3795 #if (TRACE_BUF_SIZE <= 0)
3796 hal_uart_close(trace_uart);
3797 #endif
3798
3799 return 0;
3800 }
3801
hal_trace_rx_sleep(void)3802 int hal_trace_rx_sleep(void)
3803 {
3804 uint32_t lock;
3805
3806 if (trace_rx_state != HAL_TRACE_RX_STATE_OPENED) {
3807 return 1;
3808 }
3809
3810 lock = int_lock();
3811 hal_trace_rx_stop();
3812 trace_rx_state = HAL_TRACE_RX_STATE_SLEEP;
3813 int_unlock(lock);
3814
3815 return 0;
3816 }
3817
hal_trace_rx_wakeup(void)3818 int hal_trace_rx_wakeup(void)
3819 {
3820 if (trace_rx_state != HAL_TRACE_RX_STATE_SLEEP) {
3821 return 1;
3822 }
3823
3824 if (trace_rx_buf == NULL || trace_rx_len == 0 || trace_rx_cb == NULL) {
3825 return 2;
3826 }
3827
3828 trace_rx_state = HAL_TRACE_RX_STATE_OPENED;
3829 hal_trace_rx_start();
3830
3831 return 0;
3832 }
3833
3834 #endif
3835
3836 #ifdef TOTA_CRASH_DUMP_TOOL_ENABLE
hal_trace_crash_dump_printf(uint32_t attr,const char * fmt,...)3837 int hal_trace_crash_dump_printf(uint32_t attr, const char *fmt, ...)
3838 {
3839 int ret;
3840 va_list ap;
3841 char buf[120];
3842 int len = 0;
3843 enum TR_LEVEL_T level;
3844 enum TR_MODULE_T module;
3845
3846 if (attr & TR_ATTR_IMM) {
3847 hal_trace_flush_buffer();
3848 }
3849
3850 va_start(ap, fmt);
3851
3852 level = GET_BITFIELD(attr, TR_ATTR_LEVEL);
3853 module = GET_BITFIELD(attr, TR_ATTR_MOD);
3854
3855 #ifdef CRASH_DUMP_ENABLE
3856 if (!in_crash_dump)
3857 #endif
3858 {
3859 if (level > get_hal_trace_log_level()) {
3860 return 0;
3861 }
3862 if (level > TR_LEVEL_CRITICAL && (trace_mod_map[module >> 5] & (1 << (module & 0x1F))) == 0) {
3863 return 0;
3864 }
3865 }
3866
3867 len = 0;
3868 if ((attr & TR_ATTR_NO_TS) == 0)
3869 {
3870 len += hal_trace_print_time(level, module, &buf[len], sizeof(buf) - len);
3871 }
3872 len += hal_trace_format_va(attr, &buf[len], sizeof(buf) - len, fmt, ap);
3873 ret = hal_trace_output((unsigned char *)buf, len);
3874 va_end(ap);
3875
3876 if (attr & TR_ATTR_IMM) {
3877 hal_trace_flush_buffer();
3878 }
3879
3880 return ret;
3881 }
3882 #endif
3883
3884 #if (TRACE_BUF_SIZE > 0)
3885 #define UART_CRLF "\r\n"
3886 #define UART_LFCR "\n\r"
3887 #define UART_CR "\r"
3888 #define UART_LF "\n"
3889 #define UART_MAX_TEMP 128
hal_trace_output_crlf(const unsigned char * buf,unsigned int len,bool block_flag)3890 int hal_trace_output_crlf(const unsigned char *buf, unsigned int len,bool block_flag)
3891 {
3892 char p_str[UART_MAX_TEMP];
3893 char *p_data;
3894 uint32_t j;
3895 uint32_t str_len = len;
3896 if (buf == NULL)
3897 {
3898 return -1;
3899 }
3900 uint32_t lock;
3901 uint32_t avail = 0;
3902 if (block_flag)
3903 {
3904 lock = int_lock();
3905 if (p_trace->wptr >= p_trace->rptr) {
3906 avail = TRACE_BUF_SIZE - (p_trace->wptr - p_trace->rptr) - 1;
3907 } else {
3908 avail = (p_trace->rptr - p_trace->wptr) - 1;
3909 }
3910 int_unlock(lock);
3911 if (avail < (len+1024)) {
3912 hal_trace_flush_buffer();
3913 }
3914 }
3915 p_data = (char *)buf;
3916 j=0;
3917 for(int i =0;i<str_len;i++){
3918 p_str[j++] = p_data[i];
3919 if(p_data[i]=='\r' && p_data[i+1]!='\n'){
3920 p_str[j]='\n';
3921 j++;
3922 continue;
3923 }
3924 if(p_data[i]=='\n'){
3925 p_str[j-1] = '\r';
3926 p_str[j] = '\n';
3927 j++;
3928 continue;
3929 }
3930 if(j<UART_MAX_TEMP)
3931 {
3932 continue;
3933 }
3934 if(j>0){
3935 hal_trace_output((const unsigned char *)p_str,j);
3936 j=0;
3937 }
3938 }
3939 if(j>0){
3940 hal_trace_output((const unsigned char *)p_str,j);
3941 j = 0;
3942 }
3943 return len;
3944 }
hal_trace_output_block(const unsigned char * buf,unsigned int len)3945 int hal_trace_output_block(const unsigned char *buf, unsigned int len)
3946 {
3947 uint32_t lock;
3948 uint32_t avail = 0;
3949 lock = int_lock();
3950 if (p_trace->wptr >= p_trace->rptr) {
3951 avail = TRACE_BUF_SIZE - (p_trace->wptr - p_trace->rptr) - 1;
3952 } else {
3953 avail = (p_trace->rptr - p_trace->wptr) - 1;
3954 }
3955 int_unlock(lock);
3956 if (avail < (len+1024)) {
3957 hal_trace_flush_buffer();
3958 }
3959
3960 return hal_trace_output((unsigned char *)buf, len);
3961 }
3962 #endif
3963
3964 #ifndef __ARM_ARCH_ISA_ARM
3965 #define A7_TRACE_TAG "A7_TRACE:"
3966 int _print_a7_flush = 0;
hal_trace_print_a7_flush(int onoff)3967 void hal_trace_print_a7_flush(int onoff)
3968 {
3969 _print_a7_flush = onoff;
3970 TRACE(0, "%s onoff=%d", __FUNCTION__, onoff);
3971 }
3972
hal_trace_print_a7(const unsigned char * buf,unsigned int buf_len)3973 void hal_trace_print_a7(const unsigned char *buf, unsigned int buf_len)
3974 {
3975 /* check platform trace on/off */
3976 if (get_hal_trace_onoff() == 1)
3977 {
3978 return;
3979 }
3980
3981 /* output trace by local driver */
3982 if (buf && (buf_len > 0)) {
3983 if (_print_a7_flush == 0) // don't add A7_TRACE_TAG for A7 crashdump
3984 hal_trace_output((const unsigned char *)A7_TRACE_TAG, sizeof(A7_TRACE_TAG));
3985 hal_trace_output(buf, buf_len);
3986 if (_print_a7_flush) {
3987 hal_trace_flush_buffer();
3988 }
3989 }
3990 }
3991 #endif
3992