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 #if defined(NUTTX_BUILD) && !defined(CONFIG_ARCH_CHIP_DEBUG_H)
1806 bool is_nolf = attr & TR_ATTR_NO_LF;
1807 //if (!is_nolf)
1808 {
1809 len = snprintf(buf, TRACE_PRINTF_LEN,"%s\n", fmt);
1810 fmt = buf;
1811 }
1812 vsyslog(level+1, fmt , ap);
1813 return len;
1814 #else
1815
1816 #ifdef CRASH_DUMP_ENABLE
1817 if (!in_crash_dump)
1818 #endif
1819 {
1820 if (level > trace_max_level) {
1821 return 0;
1822 }
1823 if (level > TR_LEVEL_CRITICAL && (trace_mod_map[module >> 5] & (1 << (module & 0x1F))) == 0) {
1824 return 0;
1825 }
1826 }
1827
1828 #ifdef USE_TRACE_ID
1829 if ((attr & TR_ATTR_NO_ID) == 0 && (len = hal_trace_format_id(attr, &log_buf.container.body, fmt, ap)) > 0) {
1830 buf = &log_buf.container.prefix[3];
1831 buf[0] = '\0';
1832 len += 1;
1833 }
1834 else
1835 #endif
1836 {
1837 len = 0;
1838 if ((attr & TR_ATTR_NO_TS) == 0) {
1839 len += hal_trace_print_time(level, module, &buf[len], sizeof(buf) - len);
1840 }
1841 len += hal_trace_format_va(attr, &buf[len], sizeof(buf) - len, fmt, ap);
1842 }
1843
1844 return hal_trace_output((unsigned char *)buf, len);
1845 #endif
1846 }
1847
hal_trace_printf(uint32_t attr,const char * fmt,...)1848 int hal_trace_printf(uint32_t attr, const char *fmt, ...)
1849 {
1850 int ret;
1851 va_list ap;
1852
1853 if (attr & TR_ATTR_IMM) {
1854 hal_trace_flush_buffer();
1855 }
1856
1857 va_start(ap, fmt);
1858 ret = hal_trace_printf_internal(attr, fmt, ap);
1859 va_end(ap);
1860
1861 if (attr & TR_ATTR_IMM) {
1862 hal_trace_flush_buffer();
1863 }
1864
1865 return ret;
1866 }
1867
hal_trace_printf_without_crlf_ts(const char * fmt,...)1868 int hal_trace_printf_without_crlf_ts(const char *fmt, ...)
1869 {
1870 int ret;
1871 uint32_t attr = TR_ATTR_NO_LF|TR_ATTR_NO_TS|TR_ATTR_NO_ID;
1872 va_list ap;
1873
1874 va_start(ap, fmt);
1875 ret = hal_trace_printf_internal(attr, fmt, ap);
1876 va_end(ap);
1877
1878 return ret;
1879 }
1880
hal_trace_printf_without_crlf(const char * fmt,...)1881 int hal_trace_printf_without_crlf(const char *fmt, ...)
1882 {
1883 int ret;
1884 uint32_t attr = TR_ATTR_NO_LF|TR_ATTR_NO_ID;
1885 va_list ap;
1886
1887 va_start(ap, fmt);
1888 ret = hal_trace_printf_internal(attr, fmt, ap);
1889 va_end(ap);
1890
1891 return ret;
1892 }
1893
hal_trace_dump(const char * fmt,unsigned int size,unsigned int count,const void * buffer)1894 int hal_trace_dump(const char *fmt, unsigned int size, unsigned int count, const void *buffer)
1895 {
1896 char buf[TRACE_DUMP_LEN];
1897 int len=0, n=0, i=0;
1898
1899 switch( size )
1900 {
1901 case sizeof(uint32_t):
1902 while(i<count && len<sizeof(buf))
1903 {
1904 len += snprintf(&buf[len], sizeof(buf) - len, fmt, *(uint32_t *)((uint32_t *)buffer+i));
1905 i++;
1906 }
1907 break;
1908 case sizeof(uint16_t):
1909 while(i<count && len<sizeof(buf))
1910 {
1911 len += snprintf(&buf[len], sizeof(buf) - len, fmt, *(uint16_t *)((uint16_t *)buffer+i));
1912 i++;
1913 }
1914 break;
1915 case sizeof(uint8_t):
1916 default:
1917 while(i<count && len<sizeof(buf))
1918 {
1919 len += snprintf(&buf[len], sizeof(buf) - len, fmt, *(uint8_t *)((uint8_t *)buffer+i));
1920 i++;
1921 }
1922 break;
1923 }
1924
1925 #ifdef TRACE_CRLF
1926 if (len + 2 < sizeof(buf)) {
1927 buf[len++] = '\r';
1928 }
1929 #endif
1930 if (len + 1 < sizeof(buf)) {
1931 buf[len++] = '\n';
1932 }
1933
1934 if (get_hal_trace_onoff() == 1){
1935 return len;
1936 }
1937
1938 n = hal_trace_output((unsigned char *)buf, len);
1939
1940 return n;
1941 }
1942
hal_trace_busy(void)1943 int hal_trace_busy(void)
1944 {
1945 #if (TRACE_BUF_SIZE > 0)
1946 union HAL_UART_FLAG_T flag;
1947
1948 if (hal_trace_is_uart_transport(trace_transport)) {
1949 if (hal_uart_opened(trace_uart)) {
1950 flag = hal_uart_get_flag(trace_uart);
1951 return flag.BUSY;
1952 }
1953 }
1954 #endif
1955 return 0;
1956 }
1957
hal_trace_pause(void)1958 int hal_trace_pause(void)
1959 {
1960 #if (TRACE_BUF_SIZE > 0)
1961 int ret = 0;
1962 uint32_t lock;
1963
1964 lock = int_lock();
1965 if (p_trace->pause_cnt == 0) {
1966 if (hal_trace_is_uart_transport(trace_transport)) {
1967 #if (TRACE_IDLE_OUTPUT == 0)
1968 hal_trace_uart_stop_dma_send();
1969 #endif
1970 hal_uart_pause(trace_uart, HAL_UART_XFER_TYPE_TX);
1971 }
1972 }
1973 p_trace->pause_cnt++;
1974 if (p_trace->pause_cnt == 0) {
1975 p_trace->pause_cnt--;
1976 ret = 1;
1977 }
1978 int_unlock(lock);
1979
1980 return ret;
1981 #else
1982 return 0;
1983 #endif
1984 }
1985
hal_trace_continue(void)1986 int hal_trace_continue(void)
1987 {
1988 #if (TRACE_BUF_SIZE > 0)
1989 int ret = 0;
1990 uint32_t lock;
1991
1992 lock = int_lock();
1993 if (p_trace->pause_cnt == 0) {
1994 ret = 1;
1995 } else {
1996 p_trace->pause_cnt--;
1997 if (p_trace->pause_cnt == 0) {
1998 if (hal_trace_is_uart_transport(trace_transport)) {
1999 hal_uart_continue(trace_uart, HAL_UART_XFER_TYPE_TX);
2000 }
2001 #if (TRACE_IDLE_OUTPUT == 0)
2002 hal_trace_send();
2003 #endif
2004 }
2005 }
2006 int_unlock(lock);
2007
2008 return ret;
2009 #else
2010 return 0;
2011 #endif
2012 }
2013
hal_trace_force_continue(void)2014 static void hal_trace_force_continue(void)
2015 {
2016 #if (TRACE_BUF_SIZE > 0)
2017 if (p_trace->pause_cnt) {
2018 // Allow to flush buffer
2019 p_trace->pause_cnt = 0;
2020 if (hal_trace_is_uart_transport(trace_transport)) {
2021 hal_uart_continue(trace_uart, HAL_UART_XFER_TYPE_TX);
2022 }
2023 #if (TRACE_IDLE_OUTPUT == 0)
2024 hal_trace_send();
2025 #endif
2026 }
2027 #endif
2028 }
2029
hal_trace_flush_buffer(void)2030 int hal_trace_flush_buffer(void)
2031 {
2032 #if (TRACE_BUF_SIZE > 0)
2033 int ret = 0;
2034 uint32_t lock;
2035 uint32_t time;
2036 #if (TRACE_IDLE_OUTPUT == 0)
2037 enum HAL_DMA_RET_T dma_ret;
2038 #endif
2039
2040 if (trace_transport >= HAL_TRACE_TRANSPORT_QTY) {
2041 return -1;
2042 }
2043
2044 #ifdef CP_TRACE_ENABLE
2045 if (get_cpu_id()) {
2046 if (cp_buffer_cb) {
2047 cp_buffer_cb(HAL_TRACE_BUF_STATE_FLUSH);
2048 }
2049 return 0;
2050 }
2051 #endif
2052
2053 lock = int_lock();
2054
2055 if (p_trace->pause_cnt == 0) {
2056 time = hal_sys_timer_get();
2057 while (p_trace->wptr != p_trace->rptr &&
2058 (hal_sys_timer_get() - time) < TRACE_FLUSH_TIMEOUT) {
2059 #if (TRACE_IDLE_OUTPUT == 0)
2060 #if (defined(CHIP_BEST2001_DSP) || defined(CHIP_BEST2003_DSP)) && !defined(PROGRAMMER) && defined(RTOS)
2061 if (trace_transport == HAL_TRACE_TRANSPORT_TRANSQ1) {
2062 if (p_trace->sending) {
2063 while (hal_transq_tx_busy(HAL_TRANSQ_ID_1));
2064 hal_transq_local_irq_handler_body(HAL_TRANSQ_ID_1);
2065 }
2066 hal_trace_send();
2067 } else
2068 #endif
2069 {
2070 while (hal_dma_chan_busy(dma_cfg.ch));
2071 dma_ret = hal_dma_irq_run_chan(dma_cfg.ch);
2072 if (dma_ret != HAL_DMA_OK) {
2073 hal_trace_send();
2074 }
2075 }
2076 #else
2077 hal_trace_send();
2078 #endif
2079 }
2080 ret = (p_trace->wptr == p_trace->rptr) ? 0 : 1;
2081 }
2082
2083 int_unlock(lock);
2084
2085 return ret;
2086 #else
2087 return 0;
2088 #endif
2089 }
2090
hal_trace_flush_output(void)2091 int hal_trace_flush_output(void)
2092 {
2093 #if (TRACE_BUF_SIZE > 0)
2094 uint32_t lock;
2095 uint32_t time;
2096 int ret;
2097 int busy;
2098
2099 lock = int_lock();
2100
2101 ret = hal_trace_flush_buffer();
2102
2103 time = hal_sys_timer_get();
2104 while ((busy = hal_trace_busy()) && (hal_sys_timer_get() - time) < TRACE_FLUSH_TIMEOUT);
2105
2106 int_unlock(lock);
2107
2108 return (ret || busy);
2109 #else
2110 return 0;
2111 #endif
2112 }
2113
hal_trace_get_backtrace_addr(uint32_t addr)2114 uint32_t hal_trace_get_backtrace_addr(uint32_t addr)
2115 {
2116 if (!hal_trace_address_executable(addr)) {
2117 return 0;
2118 }
2119
2120 #ifndef __ARM_ARCH_ISA_ARM
2121 #if defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__)
2122 // BL Instruction
2123 // 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
2124 // VALUE : 1 1 1 1 0 - - - - - - - - - - - 1 1 - 1 - - - - - - - - - - - -
2125
2126 // BLX Instruction
2127 // OFFSET: 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
2128 // VALUE : 0 1 0 0 0 1 1 1 1 - - - - - - -
2129
2130 uint16_t val;
2131 uint32_t new_addr;
2132
2133 new_addr = (addr & ~1) - 2;
2134
2135 val = *(uint16_t *)new_addr;
2136 if ((val & 0xFF80) == 0x4780) {
2137 // BLX
2138 return new_addr;
2139 } else if ((val & 0xD000) == 0xD000) {
2140 new_addr -= 2;
2141 val = *(uint16_t *)new_addr;
2142 if ((val & 0xF800) == 0xF000) {
2143 // BL
2144 return new_addr;
2145 }
2146 }
2147 #else
2148 #if defined(NUTTX_BUILD)
2149 extern uint32_t _mmu_text_start[];
2150 extern uint32_t _mmu_text_end[];
2151 if (addr >= _mmu_text_start && addr <= _mmu_text_end)
2152 return addr;
2153 #else
2154 #error "Only ARMv7-M/ARMv8-M function can be checked for BL/BLX instructions"
2155 #endif
2156 #endif
2157 #endif
2158
2159 return 0;
2160 }
2161
2162 #ifndef __ARM_ARCH_ISA_ARM
hal_trace_print_special_stack_registers(uint32_t msp,uint32_t psp)2163 void hal_trace_print_special_stack_registers(uint32_t msp, uint32_t psp)
2164 {
2165 int len;
2166
2167 hal_trace_output_linefeed();
2168
2169 len = snprintf(crash_buf, sizeof(crash_buf), "MSP =%08X, PSP =%08X" NEW_LINE_STR, (unsigned)msp, (unsigned)psp);
2170 hal_trace_output((unsigned char *)crash_buf, len);
2171
2172 #ifdef __ARM_ARCH_8M_MAIN__
2173 len = snprintf(crash_buf, sizeof(crash_buf), "MSPLIM=%08X, PSPLIM=%08X" NEW_LINE_STR, (unsigned)__get_MSPLIM(), (unsigned)__get_PSPLIM());
2174 hal_trace_output((unsigned char *)crash_buf, len);
2175 #endif
2176 }
2177
2178 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
hal_trace_print_special_stack_registers_ns(uint32_t msp_ns,uint32_t psp_ns)2179 void hal_trace_print_special_stack_registers_ns(uint32_t msp_ns, uint32_t psp_ns)
2180 {
2181 int len;
2182
2183 hal_trace_output_linefeed();
2184
2185 len = snprintf(crash_buf, sizeof(crash_buf), "MSP_NS =%08X, PSP_NS =%08X" NEW_LINE_STR, (unsigned)msp_ns, (unsigned)psp_ns);
2186 hal_trace_output((unsigned char *)crash_buf, len);
2187
2188 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());
2189 hal_trace_output((unsigned char *)crash_buf, len);
2190 }
2191 #endif
2192 #endif
2193
hal_trace_print_common_registers(const uint32_t * regs)2194 void hal_trace_print_common_registers(const uint32_t *regs)
2195 {
2196 int len;
2197 int i;
2198 int index;
2199
2200 hal_trace_output_linefeed();
2201
2202 for (i = 0; i < 3; i++) {
2203 index = i * 4;
2204 len = snprintf(crash_buf, sizeof(crash_buf), "R%-2d=%08X, R%-2d=%08X, R%-2d=%08X, R%-2d=%08X" NEW_LINE_STR,
2205 index, (unsigned)regs[index], index + 1, (unsigned)regs[index + 1],
2206 index + 2, (unsigned)regs[index + 2], index + 3, (unsigned)regs[index + 3]);
2207 hal_trace_output((unsigned char *)crash_buf, len);
2208 }
2209 len = snprintf(crash_buf, sizeof(crash_buf), "R12=%08X, SP =%08X, LR =%08X" NEW_LINE_STR,
2210 (unsigned)regs[12], (unsigned)regs[13], (unsigned)regs[14]);
2211 hal_trace_output((unsigned char *)crash_buf, len);
2212 }
2213
hal_trace_print_stack(uint32_t addr)2214 void hal_trace_print_stack(uint32_t addr)
2215 {
2216 static const char stack_title[] = "Stack:" NEW_LINE_STR;
2217 int len = 0;
2218 int i;
2219 int pos;
2220 uint32_t *stack;
2221
2222 addr &= ~3;
2223 if (!hal_trace_address_writable(addr)) {
2224 return;
2225 }
2226
2227 #ifndef DUMP_SECURE_STACK
2228 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
2229 // don't dump secure stack
2230 if (RAM_BASE < addr && addr < RAM_BASE + RAM_SIZE) {
2231 return;
2232 }
2233 #endif
2234 #endif
2235
2236 hal_trace_output_linefeed();
2237 hal_trace_output((const unsigned char *)stack_title, sizeof(stack_title) - 1);
2238
2239 stack = (uint32_t *)addr - STACK_DUMP_CNT_PREV;
2240 for (i = 0; i < (STACK_DUMP_CNT_PREV + STACK_DUMP_CNT); i++) {
2241 if (!hal_trace_address_writable((uint32_t)&stack[i])) {
2242 break;
2243 }
2244 pos = (i % STACK_DUMP_CNT_PER_LEN);
2245 if (pos == 0) {
2246 len = snprintf(crash_buf, sizeof(crash_buf), "%c %08X: %08X",
2247 (i == STACK_DUMP_CNT_PREV) ? '*' : ' ', (unsigned)&stack[i], (unsigned)stack[i]);
2248 } else {
2249 len += snprintf(crash_buf + len, sizeof(crash_buf) - len, " %08X", (unsigned)stack[i]);
2250 if (pos == (STACK_DUMP_CNT_PER_LEN - 1)) {
2251 #ifdef TRACE_CRLF
2252 if (len + 2 < sizeof(crash_buf)) {
2253 crash_buf[len++] = '\r';
2254 }
2255 #endif
2256 if (len + 1 < sizeof(crash_buf)) {
2257 crash_buf[len++] = '\n';
2258 }
2259 hal_trace_output((unsigned char *)crash_buf, len);
2260 hal_trace_flush_buffer();
2261 }
2262 }
2263 }
2264 }
2265
hal_trace_print_backtrace(uint32_t addr,uint32_t search_cnt,uint32_t print_cnt)2266 void hal_trace_print_backtrace(uint32_t addr, uint32_t search_cnt, uint32_t print_cnt)
2267 {
2268 static const char bt_title[] = "Possible Backtrace:" NEW_LINE_STR;
2269 int i, j;
2270 int len;
2271 uint32_t *stack;
2272 uint32_t call_addr;
2273
2274 addr &= ~3;
2275 if (!hal_trace_address_writable(addr)) {
2276 return;
2277 }
2278
2279 hal_trace_output_linefeed();
2280 hal_trace_output((const unsigned char *)bt_title, sizeof(bt_title) - 1);
2281
2282 stack = (uint32_t *)addr;
2283 for (i = 0, j = 0; i < search_cnt && j < print_cnt; i++) {
2284 if (!hal_trace_address_writable((uint32_t)&stack[i])) {
2285 break;
2286 }
2287 call_addr = hal_trace_get_backtrace_addr(stack[i]);
2288 if (call_addr) {
2289 #if defined(NUTTX_BUILD)
2290 len = snprintf(crash_buf, sizeof(crash_buf), "%8X ", (unsigned)call_addr);
2291 #else
2292 len = snprintf(crash_buf, sizeof(crash_buf), "%8X" NEW_LINE_STR, (unsigned)call_addr);
2293 #endif
2294 hal_trace_output((unsigned char *)crash_buf, len);
2295 j++;
2296 }
2297 }
2298 }
2299
hal_trace_get_id(void)2300 uint32_t hal_trace_get_id(void)
2301 {
2302 return trace_uart;
2303 }
2304
hal_trace_get_baudrate(void)2305 uint32_t hal_trace_get_baudrate(void)
2306 {
2307 #if (TRACE_BUF_SIZE > 0)
2308 return uart_cfg.baud;
2309 #else
2310 return 0;
2311 #endif
2312 }
2313
hal_trace_in_crash_dump(void)2314 bool hal_trace_in_crash_dump(void)
2315 {
2316 #ifdef CRASH_DUMP_ENABLE
2317 return in_crash_dump;
2318 #else
2319 return false;
2320 #endif
2321 }
2322
hal_trace_crash_dump_register(enum HAL_TRACE_CRASH_DUMP_MODULE_T module,HAL_TRACE_CRASH_DUMP_CB_T cb)2323 int hal_trace_crash_dump_register(enum HAL_TRACE_CRASH_DUMP_MODULE_T module, HAL_TRACE_CRASH_DUMP_CB_T cb)
2324 {
2325 #ifdef CRASH_DUMP_ENABLE
2326 ASSERT(module < HAL_TRACE_CRASH_DUMP_MODULE_END, "%s module %d", __func__, module);
2327 crash_dump_cb_list[module] = cb;
2328 #endif
2329 return 0;
2330 }
2331
hal_trace_crash_dump_callback(void)2332 void hal_trace_crash_dump_callback(void)
2333 {
2334 #ifdef CRASH_DUMP_ENABLE
2335 int i;
2336
2337 in_crash_dump = true;
2338
2339 for (i = 0; i < ARRAY_SIZE(crash_dump_cb_list); i++) {
2340 if (crash_dump_cb_list[i]) {
2341 crash_dump_cb_list[i]();
2342 }
2343 }
2344 #endif
2345 }
2346
2347 #ifdef CRASH_DUMP_ENABLE
2348 #ifdef TRACE_TO_APP
hal_trace_app_notify_callback(enum HAL_TRACE_STATE_T state)2349 void hal_trace_app_notify_callback(enum HAL_TRACE_STATE_T state)
2350 {
2351 if (state == HAL_TRACE_STATE_CRASH_ASSERT_START) {
2352 app_output_enabled = true;
2353 } else if (state == HAL_TRACE_STATE_CRASH_FAULT_START) {
2354 if (app_crash_custom_cb == NULL) {
2355 app_output_enabled = true;
2356 }
2357 }
2358 for (int i = 0; i < HAL_TRACE_APP_REG_ID_QTY; i++) {
2359 if (app_notify_cb[i]) {
2360 app_notify_cb[i](state);
2361 }
2362 }
2363 }
2364
hal_trace_app_output_callback(const unsigned char * buf,unsigned int buf_len)2365 static void hal_trace_app_output_callback(const unsigned char *buf, unsigned int buf_len)
2366 {
2367 for (int i = 0; i < HAL_TRACE_APP_REG_ID_QTY; i++) {
2368 if (app_output_cb[i]) {
2369 app_output_cb[i](buf, buf_len);
2370 }
2371 }
2372 }
2373 #endif
2374 #endif
2375
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)2376 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)
2377 {
2378 if (id >= HAL_TRACE_APP_REG_ID_QTY) {
2379 return 1;
2380 }
2381 #ifdef TRACE_TO_APP
2382 bool output_valid = false;
2383 uint32_t lock;
2384
2385 lock = int_lock();
2386
2387 app_notify_cb[id] = notify_cb;
2388 app_output_cb[id] = output_cb;
2389
2390 for (int i = 0; i < HAL_TRACE_APP_REG_ID_QTY; i++) {
2391 if (app_output_cb[i]) {
2392 output_valid = true;
2393 break;
2394 }
2395 }
2396 app_output_cb_valid = output_valid;
2397
2398 int_unlock(lock);
2399 #endif
2400 return 0;
2401 }
2402
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)2403 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)
2404 {
2405 #ifdef TRACE_TO_APP
2406 hal_trace_app_register(HAL_TRACE_APP_REG_ID_0, notify_cb, output_cb);
2407 app_crash_custom_cb = crash_custom_cb;
2408 #endif
2409 }
2410
hal_trace_global_tag_register(HAL_TRACE_GLOBAL_TAG_CB_T tag_cb)2411 void hal_trace_global_tag_register(HAL_TRACE_GLOBAL_TAG_CB_T tag_cb)
2412 {
2413 #ifdef TRACE_GLOBAL_TAG
2414 gbl_tag_cb = tag_cb;
2415 #endif
2416 }
2417
hal_trace_open_cp(HAL_TRACE_BUF_CTRL_T buf_cb,HAL_TRACE_APP_NOTIFY_T notify_cb)2418 int hal_trace_open_cp(HAL_TRACE_BUF_CTRL_T buf_cb, HAL_TRACE_APP_NOTIFY_T notify_cb)
2419 {
2420 #ifdef CP_TRACE_ENABLE
2421 cp_buffer_cb = buf_cb;
2422 #ifdef CRASH_DUMP_ENABLE
2423 cp_notify_cb = notify_cb;
2424 #endif
2425 #ifdef FAULT_DUMP
2426 NVIC_SetDefaultFaultHandler_cp(hal_trace_fault_handler);
2427 #endif
2428 #endif
2429
2430 return 0;
2431 }
2432
hal_trace_close_cp(void)2433 int hal_trace_close_cp(void)
2434 {
2435 #ifdef CP_TRACE_ENABLE
2436 cp_buffer_cb = NULL;
2437 #ifdef CRASH_DUMP_ENABLE
2438 cp_notify_cb = NULL;
2439 #endif
2440 // Force to unlock CP trace memsc
2441 hal_memsc_unlock(HAL_MEMSC_ID_TRACE);
2442 #endif
2443
2444 return 0;
2445 }
2446
2447 #else // !(DEBUG || REL_TRACE_ENABLE)
2448
hal_trace_open(enum HAL_TRACE_TRANSPORT_T transport)2449 int hal_trace_open(enum HAL_TRACE_TRANSPORT_T transport)
2450 {
2451 #ifdef FAULT_DUMP
2452 #ifdef __ARM_ARCH_ISA_ARM
2453 GIC_SetFaultDumpHandler(hal_trace_fault_dump);
2454 #else
2455 NVIC_SetDefaultFaultHandler(hal_trace_fault_handler);
2456 #endif
2457 #endif
2458
2459 return 0;
2460 }
2461
2462 #endif // !(DEBUG || REL_TRACE_ENABLE)
2463
hal_trace_address_writable(uint32_t addr)2464 int hal_trace_address_writable(uint32_t addr)
2465 {
2466 if (RAM_BASE < addr && addr < RAM_BASE + RAM_SIZE) {
2467 return 1;
2468 }
2469 #if defined(PSRAM_BASE) && (PSRAM_SIZE > 0)
2470 if (PSRAM_BASE < addr && addr < PSRAM_BASE + PSRAM_SIZE) {
2471 return 1;
2472 }
2473 #endif
2474 #if defined(PSRAM_NC_BASE) && (PSRAM_SIZE > 0)
2475 if (PSRAM_NC_BASE < addr && addr < PSRAM_NC_BASE + PSRAM_SIZE) {
2476 return 1;
2477 }
2478 #endif
2479 #if defined(PSRAMUHS_BASE) && (PSRAMUHS_SIZE > 0)
2480 if (PSRAMUHS_BASE < addr && addr < PSRAMUHS_BASE + PSRAMUHS_SIZE) {
2481 return 1;
2482 }
2483 #endif
2484 #if defined(PSRAMUHS_NC_BASE) && (PSRAMUHS_SIZE > 0)
2485 if (PSRAMUHS_NC_BASE < addr && addr < PSRAMUHS_NC_BASE + PSRAMUHS_SIZE) {
2486 return 1;
2487 }
2488 #endif
2489 #if defined(RAMRET_BASE) && (RAMRET_SIZE > 0)
2490 if (RAMRET_BASE < addr && addr < RAMRET_BASE + RAMRET_SIZE) {
2491 return 1;
2492 }
2493 #endif
2494 #if defined(RAMCP_BASE) && (RAMCP_SIZE > 0)
2495 if (RAMCP_BASE < addr && addr < RAMCP_BASE + RAMCP_SIZE) {
2496 return 1;
2497 }
2498 #endif
2499 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
2500 if (RAM_NS_BASE < addr && addr < RAM_NS_BASE + RAM_NS_SIZE) {
2501 return 1;
2502 }
2503 #endif
2504
2505 #if defined(CONFIG_BES_DUALCORE_AMP)
2506 #ifdef PSRAMCP_BASE
2507 if (PSRAMCP_BASE < addr && addr < PSRAMCP_BASE + PSRAMCP_SIZE) {
2508 return 1;
2509 }
2510 #endif
2511 #endif
2512 return 0;
2513 }
2514
hal_trace_address_executable(uint32_t addr)2515 int hal_trace_address_executable(uint32_t addr)
2516 {
2517 // Check thumb code
2518 if ((addr & 1) == 0) {
2519 return 0;
2520 }
2521
2522 // Avoid reading out of valid memory region when parsing instruction content
2523 #define X_ADDR_OFFSET 0x10
2524
2525 // Check location
2526 if ((RAMX_BASE + X_ADDR_OFFSET) < addr && addr < (RAMX_BASE + RAM_SIZE)) {
2527 return 1;
2528 }
2529 #if defined(PSRAMX_BASE) && (PSRAM_SIZE > 0)
2530 if ((PSRAMX_BASE + X_ADDR_OFFSET) < addr && addr < (PSRAMX_BASE + PSRAM_SIZE)) {
2531 return 1;
2532 }
2533 #endif
2534 #if defined(PSRAMUHSX_BASE) && (PSRAMUHS_SIZE > 0)
2535 if ((PSRAMUHSX_BASE + X_ADDR_OFFSET) < addr && addr < (PSRAMUHSX_BASE + PSRAMUHS_SIZE)) {
2536 return 1;
2537 }
2538 #endif
2539 #if defined(RAMXRET_BASE) && (RAMRET_SIZE > 0)
2540 if ((RAMXRET_BASE + X_ADDR_OFFSET) < addr && addr < (RAMXRET_BASE + RAMRET_SIZE)) {
2541 return 1;
2542 }
2543 #endif
2544
2545 // Check flash location
2546 #ifndef NO_FLASH_BASE_ACCESS
2547 #ifdef OTA_CODE_OFFSET
2548 #define FLASH_EXEC_START (FLASHX_BASE + OTA_CODE_OFFSET)
2549 #define FLASH_EXEC_SIZE (FLASH_SIZE - OTA_CODE_OFFSET)
2550 #else
2551 #define FLASH_EXEC_START (FLASHX_BASE)
2552 #define FLASH_EXEC_SIZE (FLASH_SIZE)
2553 #endif
2554 #ifdef FLASH_REGION_SIZE
2555 #undef FLASH_EXEC_SIZE
2556 #define FLASH_EXEC_SIZE (FLASH_REGION_SIZE)
2557 #endif
2558 if ((FLASH_EXEC_START + X_ADDR_OFFSET) < addr && addr < (FLASH_EXEC_START + FLASH_EXEC_SIZE)) {
2559 return 1;
2560 }
2561 #endif
2562
2563 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
2564 if ((RAMX_NS_BASE + X_ADDR_OFFSET) < addr && addr < (RAMX_NS_BASE + RAM_NS_SIZE)) {
2565 return 1;
2566 }
2567 if ((FLASHX_BASE + NS_APP_START_OFFSET + X_ADDR_OFFSET) < addr && addr < (FLASHX_BASE + FLASH_SIZE)) {
2568 return 1;
2569 }
2570 #endif
2571 #if defined(CONFIG_BES_DUALCORE_AMP)
2572 #ifdef PSRAMCPX_BASE
2573 if (PSRAMCPX_BASE + X_ADDR_OFFSET < addr && addr < PSRAMCPX_BASE + PSRAMCP_SIZE) {
2574 return 1;
2575 }
2576 #endif
2577 #endif
2578 //#define CHECK_ROM_CODE
2579 #ifdef CHECK_ROM_CODE
2580 #ifdef ROM_EXT_SIZE
2581 #define ROM_TOTAL_SIZE (ROM_SIZE + ROM_EXT_SIZE)
2582 #else
2583 #define ROM_TOTAL_SIZE (ROM_SIZE)
2584 #endif
2585 if ((ROMX_BASE + (NVIC_USER_IRQ_OFFSET * 4)) < addr && addr < (ROMX_BASE + ROM_TOTAL_SIZE)) {
2586 return 1;
2587 }
2588 #endif
2589
2590 #if 0
2591 if (FLASHX_NC_BASE < addr && addr < FLASHX_NC_BASE + FLASH_SIZE) {
2592 return 1;
2593 }
2594 #ifdef PSRAMX_NC_BASE
2595 if (PSRAMX_NC_BASE < addr && addr < PSRAMX_NC_BASE + PSRAM_SIZE) {
2596 return 1;
2597 }
2598 #endif
2599 #ifdef PSRAMUHSX_NC_BASE
2600 if (PSRAMUHSX_NC_BASE < addr && addr < PSRAMUHSX_NC_BASE + PSRAMUHS_SIZE) {
2601 return 1;
2602 }
2603 #endif
2604 #endif
2605 return 0;
2606 }
2607
hal_trace_address_readable(uint32_t addr)2608 int hal_trace_address_readable(uint32_t addr)
2609 {
2610 if (hal_trace_address_writable(addr)) {
2611 return 1;
2612 }
2613 if (hal_trace_address_executable(addr)) {
2614 return 1;
2615 }
2616 if (FLASH_BASE < addr && addr < FLASH_BASE + FLASH_SIZE) {
2617 return 1;
2618 }
2619 if (FLASH_NC_BASE < addr && addr < FLASH_NC_BASE + FLASH_SIZE) {
2620 return 1;
2621 }
2622 #if defined(PSRAM_NC_BASE) && (PSRAM_SIZE > 0)
2623 if (PSRAM_NC_BASE < addr && addr < PSRAM_NC_BASE + PSRAM_SIZE) {
2624 return 1;
2625 }
2626 #endif
2627 #if defined(PSRAMUHS_NC_BASE) && (PSRAMUHS_SIZE > 0)
2628 if (PSRAMUHS_NC_BASE < addr && addr < PSRAMUHS_NC_BASE + PSRAMUHS_SIZE) {
2629 return 1;
2630 }
2631 #endif
2632 return 0;
2633 }
2634
hal_trace_crash_end(void)2635 static void NORETURN hal_trace_crash_end(void)
2636 {
2637 #if (defined(DEBUG) || defined(REL_TRACE_ENABLE))
2638 hal_trace_output_linefeed();
2639 hal_trace_flush_buffer();
2640 hal_sys_timer_delay(MS_TO_TICKS(5));
2641 #endif
2642
2643 // Tag failure for simulation environment
2644 hal_cmu_simu_fail();
2645
2646 #ifndef IN_SUBSYS
2647 #ifdef CRASH_REBOOT
2648 hal_sw_bootmode_set(HAL_SW_BOOTMODE_REBOOT|HAL_SW_BOOTMODE_REBOOT_FROM_CRASH);
2649 pmu_reboot();
2650 #else
2651 hal_iomux_set_analog_i2c();
2652 hal_iomux_set_jtag();
2653 hal_cmu_jtag_clock_enable();
2654 #endif
2655 #endif
2656
2657 SAFE_PROGRAM_STOP();
2658 }
2659
get_cpu_id_tag(void)2660 __STATIC_FORCEINLINE uint32_t get_cpu_id_tag(void)
2661 {
2662 uint32_t cpu_id;
2663 #ifdef CP_TRACE_ENABLE
2664 cpu_id = get_cpu_id();
2665 #elif defined(__ARM_ARCH_ISA_ARM)
2666 cpu_id = 0xAAAA0000 | (get_cpu_id() & 0xFFFF);
2667 #else
2668 cpu_id = 0;
2669 #endif
2670 return cpu_id;
2671 }
2672
hal_trace_assert_dump_internal(ASSERT_DUMP_ARGS)2673 static void NORETURN USED hal_trace_assert_dump_internal(ASSERT_DUMP_ARGS)
2674 {
2675 const uint32_t *p_regs;
2676 struct ASSERT_INFO_T info;
2677 int i;
2678
2679 crash_occurs[get_cpu_id()] = true;
2680
2681 int_lock_global();
2682
2683 p_regs = (const uint32_t *)crash_buf;
2684 for (i = 0; i < ARRAY_SIZE(info.R); i++) {
2685 info.R[i] = p_regs[i];
2686 }
2687 #ifndef __ARM_ARCH_ISA_ARM
2688 info.MSP = p_regs[ARRAY_SIZE(info.R)];
2689 info.PSP = p_regs[ARRAY_SIZE(info.R) + 1];
2690 #endif
2691
2692 info.ID = HAL_TRACE_ASSERT_ID;
2693 info.CPU_ID = get_cpu_id_tag();
2694 #if (defined(DEBUG) || defined(REL_TRACE_ENABLE)) && defined(ASSERT_SHOW_FILE_FUNC)
2695 info.FILE = file;
2696 #elif (defined(DEBUG) || defined(REL_TRACE_ENABLE)) && defined(ASSERT_SHOW_FILE)
2697 info.FILE = scope;
2698 #else
2699 info.FILE = NULL;
2700 #endif
2701 #if (defined(DEBUG) || defined(REL_TRACE_ENABLE)) && defined(ASSERT_SHOW_FILE_FUNC)
2702 info.FUNC = func;
2703 #elif (defined(DEBUG) || defined(REL_TRACE_ENABLE)) && defined(ASSERT_SHOW_FUNC)
2704 info.FUNC = scope;
2705 #else
2706 info.FUNC = NULL;
2707 #endif
2708 #if (defined(DEBUG) || defined(REL_TRACE_ENABLE)) && (defined(ASSERT_SHOW_FILE_FUNC) || defined(ASSERT_SHOW_FILE) || defined(ASSERT_SHOW_FUNC))
2709 info.LINE = line;
2710 #else
2711 info.LINE = 0;
2712 #endif
2713 info.FMT = fmt;
2714 #ifndef __ARM_ARCH_ISA_ARM
2715 info.CONTROL = __get_CONTROL();
2716 #ifdef __ARM_ARCH_8M_MAIN__
2717 info.MSPLIM = __get_MSPLIM();
2718 info.PSPLIM = __get_PSPLIM();
2719 #endif
2720 #endif
2721
2722 *(volatile uint32_t *)RAM_BASE = (uint32_t)&info;
2723
2724 #ifdef ASSERT_MUTE_CODEC
2725 bool crash_mute = true;
2726 #ifdef CP_TRACE_ENABLE
2727 if (get_cpu_id()) {
2728 // Forbid CP to access CODEC
2729 crash_mute = false;
2730 }
2731 #endif
2732 if (crash_mute) {
2733 hal_codec_crash_mute();
2734 }
2735 #endif
2736
2737 #if (defined(DEBUG) || defined(REL_TRACE_ENABLE))
2738
2739 static const char POSSIBLY_UNUSED desc_file[] = "FILE : ";
2740 static const char POSSIBLY_UNUSED desc_func[] = "FUNCTION: ";
2741 static const char POSSIBLY_UNUSED desc_line[] = "LINE : ";
2742 int len;
2743 va_list ap;
2744
2745 #ifdef CP_TRACE_ENABLE
2746 // Release all the possible trace locks
2747 hal_trace_cp_force_unlock();
2748 #endif
2749 // Continue the trace
2750 hal_trace_force_continue();
2751
2752 #ifdef CRASH_DUMP_ENABLE
2753 bool full_dump = true;
2754
2755 #ifdef CP_TRACE_ENABLE
2756 if (get_cpu_id()) {
2757 full_dump = false;
2758 if (cp_notify_cb) {
2759 cp_notify_cb(HAL_TRACE_STATE_CRASH_ASSERT_START);
2760 }
2761 }
2762 #endif
2763
2764 if (full_dump) {
2765 #ifdef TRACE_TO_APP
2766 hal_trace_app_notify_callback(HAL_TRACE_STATE_CRASH_ASSERT_START);
2767 #endif
2768 }
2769 #endif
2770
2771 hal_trace_flush_buffer();
2772
2773 hal_sysfreq_req(HAL_SYSFREQ_USER_INIT, HAL_CMU_FREQ_52M);
2774
2775 len = hal_trace_print_time(TR_LEVEL_CRITICAL, TR_MODULE_NONE, &crash_buf[0], sizeof(crash_buf));
2776 if (len > 0) {
2777 hal_trace_output_linefeed();
2778 hal_trace_output((unsigned char *)crash_buf, len);
2779 }
2780 len = snprintf(&crash_buf[0], sizeof(crash_buf), NEW_LINE_STR "### ASSERT @ 0x%08X ###" NEW_LINE_STR, (unsigned)info.R[14]);
2781 hal_trace_output((unsigned char *)crash_buf, len);
2782
2783 #if defined(ASSERT_SHOW_FILE_FUNC) || defined(ASSERT_SHOW_FILE) || defined(ASSERT_SHOW_FUNC)
2784 const char separate_line[] = "----------------------------------------" NEW_LINE_STR;
2785 #ifdef ASSERT_SHOW_FILE
2786 const char *file = scope;
2787 #elif defined(ASSERT_SHOW_FUNC)
2788 const char *func = scope;
2789 #endif
2790
2791 #if defined(ASSERT_SHOW_FILE_FUNC) || defined(ASSERT_SHOW_FILE)
2792 hal_trace_output((const unsigned char *)desc_file, sizeof(desc_file) - 1);
2793 hal_trace_output((const unsigned char *)file, strlen(file));
2794 hal_trace_output_linefeed();
2795 #endif
2796
2797 #if defined(ASSERT_SHOW_FILE_FUNC) || defined(ASSERT_SHOW_FUNC)
2798 hal_trace_output((const unsigned char *)desc_func, sizeof(desc_func) - 1);
2799 hal_trace_output((const unsigned char *)func, strlen(func));
2800 hal_trace_output_linefeed();
2801 #endif
2802
2803 hal_trace_output((const unsigned char *)desc_line, sizeof(desc_func) - 1);
2804 len = snprintf(crash_buf, sizeof(crash_buf), "%u", line);
2805 hal_trace_output((const unsigned char *)crash_buf, len);
2806 hal_trace_output_linefeed();
2807
2808 hal_trace_output((unsigned char *)separate_line, sizeof(separate_line) - 1);
2809
2810 hal_trace_flush_buffer();
2811 #endif
2812
2813 va_start(ap, fmt);
2814 len = hal_trace_format_va(0, crash_buf, sizeof(crash_buf), fmt, ap);
2815 va_end(ap);
2816
2817 hal_trace_output((unsigned char *)crash_buf, len);
2818
2819 hal_trace_flush_buffer();
2820
2821 #ifdef ASSERT_VERBOSE_DUMP
2822 hal_trace_print_common_registers(info.R);
2823 hal_trace_print_special_stack_registers(info.MSP, info.PSP);
2824
2825 hal_trace_print_stack(info.R[13]);
2826
2827 hal_trace_print_backtrace(info.R[13], TRACE_BACKTRACE_SEARCH_WORD, TRACE_BACKTRACE_NUM);
2828
2829 hal_trace_output_linefeed();
2830
2831 hal_trace_flush_buffer();
2832 #endif
2833
2834 #ifdef CRASH_DUMP_ENABLE
2835 if (full_dump) {
2836 hal_trace_crash_dump_callback();
2837 hal_trace_flush_buffer();
2838 hal_sys_timer_delay(MS_TO_TICKS(5));
2839
2840 #ifdef CORE_DUMP
2841 {
2842 static CrashCatcherAssertRegisters regs;
2843
2844 regs.msp = info.MSP;
2845 regs.psp = info.PSP;
2846 regs.assertPSR = __get_xPSR();
2847 regs.R.r0 = info.R[0];
2848 regs.R.r1 = info.R[1];
2849 regs.R.r2 = info.R[2];
2850 regs.R.r3 = info.R[3];
2851 regs.R.r4 = info.R[4];
2852 regs.R.r5 = info.R[5];
2853 regs.R.r6 = info.R[6];
2854 regs.R.r7 = info.R[7];
2855 regs.R.r8 = info.R[8];
2856 regs.R.r9 = info.R[9];
2857 regs.R.r10 = info.R[10];
2858 regs.R.r11 = info.R[11];
2859 regs.R.r12 = info.R[12];
2860 regs.R.sp = info.R[13];
2861 regs.R.lr = info.R[14];
2862 /*
2863 * ASSERT's pc is not important, but who calling it is more important,
2864 * and just setting it to lr as normal assert dump.
2865 */
2866 regs.R.pc = info.R[14];
2867 regs.R.psr = regs.assertPSR;
2868
2869 AssertCatcher_Entry(®s);
2870 }
2871 hal_sys_timer_delay(MS_TO_TICKS(5));
2872 #endif
2873
2874 #ifdef TRACE_TO_APP
2875 hal_trace_app_notify_callback(HAL_TRACE_STATE_CRASH_END);
2876 #endif
2877 }
2878
2879 #ifdef CP_TRACE_ENABLE
2880 if (get_cpu_id()) {
2881 if (cp_notify_cb) {
2882 cp_notify_cb(HAL_TRACE_STATE_CRASH_END);
2883 }
2884 SAFE_PROGRAM_STOP();
2885 }
2886 #endif
2887 #endif // CRASH_DUMP_ENABLE
2888
2889 #endif // DEBUG || REL_TRACE_ENABLE
2890
2891 hal_trace_crash_end();
2892 }
2893
hal_trace_assert_dump(ASSERT_DUMP_ARGS)2894 void NORETURN NAKED WEAK hal_trace_assert_dump(ASSERT_DUMP_ARGS)
2895 {
2896 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) && !defined(DEBUG)
2897 // No way to read out the debug information. Just stop here
2898 SAFE_PROGRAM_STOP();
2899 #endif
2900
2901 #if defined(CHIP_BEST1501SIMU) || defined(CHIP_BEST1600SIMU)
2902 hal_cmu_simu_set_val(0xffffffff);
2903 #ifdef FPGA
2904 while(1);
2905 #endif
2906 #endif
2907
2908 asm volatile (
2909 "sub sp, sp, #4*(2+" TO_STRING(ASSERT_STACK_RESERVED) ");"
2910 ".cfi_def_cfa_offset 4*(2+" TO_STRING(ASSERT_STACK_RESERVED) ");"
2911 "push {r0-r5};"
2912 ".cfi_adjust_cfa_offset 4*6;"
2913 ".cfi_offset r0, -(4*(6+2+" TO_STRING(ASSERT_STACK_RESERVED) "));"
2914 ".cfi_offset r1, -(4*(5+2+" TO_STRING(ASSERT_STACK_RESERVED) "));"
2915 ".cfi_offset r2, -(4*(4+2+" TO_STRING(ASSERT_STACK_RESERVED) "));"
2916 ".cfi_offset r3, -(4*(3+2+" TO_STRING(ASSERT_STACK_RESERVED) "));"
2917 ".cfi_offset r4, -(4*(2+2+" TO_STRING(ASSERT_STACK_RESERVED) "));"
2918 ".cfi_offset r5, -(4*(1+2+" TO_STRING(ASSERT_STACK_RESERVED) "));"
2919 "ldr r0, =crash_buf;"
2920 "ldr r1, [sp];"
2921 "str r1, [r0], #4;"
2922 "ldr r1, [sp, #4];"
2923 "str r1, [r0], #4;"
2924 "stmia r0!, {r2-r12};"
2925 "add r1, sp, #4*(6+2+" TO_STRING(ASSERT_STACK_RESERVED) ");"
2926 "movs r5, r1;"
2927 "str r1, [r0], #4;"
2928 "str lr, [r0], #4;"
2929 #ifndef __ARM_ARCH_ISA_ARM
2930 // Check CONTROL.SPSEL (bit[1])
2931 "mrs r3, control;"
2932 "tst r3, #0x02;"
2933 "itte ne;"
2934 // r1 is still the original SP
2935 "movne r2, r1;"
2936 "mrsne r1, msp;"
2937 "mrseq r2, psp;"
2938 #endif
2939 "str r1, [r0], #4;"
2940 "str r2, [r0], #4;"
2941 #if (ASSERT_STACK_ARG_WORD != 8)
2942 #error "Bad ASSERT_STACK_ARG_WORD: should be 8"
2943 #endif
2944 // Save assert arguments in stack (ASSERT_STACK_ARG_WORD)
2945 "add r4, sp, #4*6;"
2946 "ldmia r5!, {r0-r3};"
2947 "stmia r4!, {r0-r3};"
2948 "ldmia r5!, {r0-r3};"
2949 "stmia r4!, {r0-r3};"
2950 "str lr, [r4];"
2951 ".cfi_offset lr, -(4*(2+" TO_STRING(STACK_DUMP_CNT_PREV) "));"
2952 "pop {r0-r5};"
2953 ".cfi_restore r5;"
2954 ".cfi_restore r4;"
2955 ".cfi_restore r3;"
2956 ".cfi_restore r2;"
2957 ".cfi_restore r1;"
2958 ".cfi_restore r0;"
2959 ".cfi_adjust_cfa_offset -4*6;"
2960 "bl hal_trace_assert_dump_internal;"
2961 );
2962 }
2963
2964 #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)2965 static void hal_trace_fill_exception_info(struct EXCEPTION_INFO_T *info, const uint32_t *regs, const uint32_t *extra, uint32_t extra_len)
2966 {
2967 info->ID = HAL_TRACE_EXCEPTION_ID;
2968 info->CPU_ID = get_cpu_id_tag();
2969 info->REGS = regs;
2970 #ifdef __ARM_ARCH_ISA_ARM
2971 info->extra = extra;
2972 info->extra_len = extra_len;
2973 #else
2974 info->MSP = regs[18];
2975 info->PSP = __get_PSP();
2976 info->PRIMASK = (regs[17] & 0xFF);
2977 info->FAULTMASK = ((regs[17] >> 8) & 0xFF);
2978 info->BASEPRI = ((regs[17] >> 16) & 0xFF);
2979 info->CONTROL = ((regs[17] >> 24) & 0xFF);
2980 info->ICSR = SCB->ICSR;
2981 info->AIRCR = SCB->AIRCR;
2982 info->SCR = SCB->SCR;
2983 info->CCR = SCB->CCR;
2984 info->SHCSR = SCB->SHCSR;
2985 info->CFSR = SCB->CFSR;
2986 info->HFSR = SCB->HFSR;
2987 info->AFSR = SCB->AFSR;
2988 info->DFSR = SCB->DFSR;
2989 info->MMFAR = SCB->MMFAR;
2990 info->BFAR = SCB->BFAR;
2991 #ifdef __ARM_ARCH_8M_MAIN__
2992 info->MSPLIM = __get_MSPLIM();
2993 info->PSPLIM = __get_PSPLIM();
2994 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
2995 info->SFSR = SAU->SFSR;
2996 info->SFAR = SAU->SFAR;
2997 info->MSP_NS = __TZ_get_MSP_NS();
2998 info->PSP_NS = __TZ_get_PSP_NS();
2999 info->MSPLIM_NS = __TZ_get_MSPLIM_NS();
3000 info->PSPLIM_NS = __TZ_get_PSPLIM_NS();
3001 info->PRIMASK_NS = __TZ_get_PRIMASK_NS();
3002 info->FAULTMASK_NS = __TZ_get_FAULTMASK_NS();
3003 info->BASEPRI_NS = __TZ_get_BASEPRI_NS();
3004 info->CONTROL_NS = __TZ_get_CONTROL_NS();
3005 #endif
3006 #endif
3007 #endif
3008 }
3009
3010 #if (defined(DEBUG) || defined(REL_TRACE_ENABLE))
3011 #ifdef __ARM_ARCH_ISA_ARM
hal_trace_print_fault_info_ca(const struct EXCEPTION_INFO_T * info)3012 static void hal_trace_print_fault_info_ca(const struct EXCEPTION_INFO_T *info)
3013 {
3014 const struct FAULT_REGS_T *fregs;
3015 const uint32_t *extra;
3016 //uint32_t extra_len;
3017 enum EXCEPTION_ID_T id;
3018 int len;
3019 uint32_t val;
3020 const char *desc;
3021
3022 fregs = (const struct FAULT_REGS_T*)info->REGS;
3023 extra = info->extra;
3024 //extra_len = info->extra_len;
3025
3026 id = (enum EXCEPTION_ID_T)extra[0];
3027
3028 len = snprintf(crash_buf, sizeof(crash_buf), "PC =%08X", (unsigned)fregs->r[15]);
3029 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", ExceptionNumber=%d" NEW_LINE_STR, id);
3030 hal_trace_output((unsigned char *)crash_buf, len);
3031
3032 hal_trace_print_common_registers(fregs->r);
3033
3034 len = snprintf(crash_buf, sizeof(crash_buf), "SPSR=%08X", (unsigned)fregs->spsr);
3035 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", APSR=%c%c%c%c%c",
3036 (fregs->spsr & (1 << 31)) ? 'N' : 'n',
3037 (fregs->spsr & (1 << 30)) ? 'Z' : 'z',
3038 (fregs->spsr & (1 << 29)) ? 'C' : 'c',
3039 (fregs->spsr & (1 << 28)) ? 'V' : 'v',
3040 (fregs->spsr & (1 << 27)) ? 'Q' : 'q'
3041 );
3042 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", XC=%c%c%c%c%c",
3043 (fregs->spsr & (1 << 9)) ? 'E' : 'e',
3044 (fregs->spsr & (1 << 8)) ? 'A' : 'a',
3045 (fregs->spsr & (1 << 7)) ? 'I' : 'i',
3046 (fregs->spsr & (1 << 6)) ? 'F' : 'f',
3047 (fregs->spsr & (1 << 5)) ? 'T' : 't'
3048 );
3049 val = fregs->spsr & 0x1F;
3050 if (val == 0x10) {
3051 desc = "USR";
3052 } else if (val == 0x11) {
3053 desc = "FIQ";
3054 } else if (val == 0x12) {
3055 desc = "IRQ";
3056 } else if (val == 0x13) {
3057 desc = "SVC";
3058 } else if (val == 0x16) {
3059 desc = "MON";
3060 } else if (val == 0x17) {
3061 desc = "ABT";
3062 } else if (val == 0x1A) {
3063 desc = "HYP";
3064 } else if (val == 0x1B) {
3065 desc = "UND";
3066 } else if (val == 0x1F) {
3067 desc = "SYS";
3068 } else {
3069 desc = "UNKNOWN";
3070 }
3071 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", MODE=%02X (%s)", (unsigned)val, desc);
3072 hal_trace_output((unsigned char *)crash_buf, len);
3073 hal_trace_output_linefeed();
3074 hal_trace_output_linefeed();
3075
3076 hal_trace_flush_buffer();
3077
3078 if (id == EXCEPTION_UNDEF) {
3079 } else if (id == EXCEPTION_SVC) {
3080 } else if (id == EXCEPTION_PABT) {
3081 } else if (id == EXCEPTION_DABT) {
3082 } else {
3083 }
3084 }
3085 #else
hal_trace_print_fault_info_cm(const struct EXCEPTION_INFO_T * info)3086 static void hal_trace_print_fault_info_cm(const struct EXCEPTION_INFO_T *info)
3087 {
3088 const uint32_t *regs;
3089 int len;
3090 uint32_t val;
3091
3092 regs = info->REGS;
3093
3094 len = snprintf(crash_buf, sizeof(crash_buf), "PC =%08X", (unsigned)regs[15]);
3095 val = __get_IPSR();
3096 if (val == 0) {
3097 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", ThreadMode");
3098 } else {
3099 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", ExceptionNumber=D'%d", (int)val - 16);
3100 }
3101 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", EXC_RETURN=%08X" NEW_LINE_STR, regs[19]);
3102 hal_trace_output((unsigned char *)crash_buf, len);
3103
3104 hal_trace_print_common_registers(regs);
3105 hal_trace_print_special_stack_registers(info->MSP, info->PSP);
3106 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
3107 hal_trace_print_special_stack_registers_ns(info->MSP_NS, info->PSP_NS);
3108 #endif
3109 hal_trace_output_linefeed();
3110
3111 len = snprintf(crash_buf, sizeof(crash_buf), "PRIMASK =%02X, FAULTMASK =%02X, BASEPRI =%02X, CONTROL =%02X" NEW_LINE_STR,
3112 (unsigned)info->PRIMASK, (unsigned)info->FAULTMASK, (unsigned)info->BASEPRI, (unsigned)info->CONTROL);
3113 hal_trace_output((unsigned char *)crash_buf, len);
3114 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
3115 len = snprintf(crash_buf, sizeof(crash_buf), "PRIMASK_NS=%02X, FAULTMASK_NS=%02X, BASEPRI_NS=%02X, CONTROL_NS=%02X" NEW_LINE_STR,
3116 (unsigned)info->PRIMASK_NS, (unsigned)info->FAULTMASK_NS, (unsigned)info->BASEPRI_NS, (unsigned)info->CONTROL_NS);
3117 hal_trace_output((unsigned char *)crash_buf, len);
3118 #endif
3119 hal_trace_output_linefeed();
3120
3121 len = snprintf(crash_buf, sizeof(crash_buf), "XPSR=%08X", (unsigned)regs[16]);
3122 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", APSR=%c%c%c%c%c",
3123 (regs[16] & (1 << 31)) ? 'N' : 'n',
3124 (regs[16] & (1 << 30)) ? 'Z' : 'z',
3125 (regs[16] & (1 << 29)) ? 'C' : 'c',
3126 (regs[16] & (1 << 28)) ? 'V' : 'v',
3127 (regs[16] & (1 << 27)) ? 'Q' : 'q'
3128 );
3129 val = regs[16] & 0x1FF;
3130 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", EPSR=%08X, IPSR=%03X", (unsigned)(regs[16] & 0x0700FC00), (unsigned)val);
3131 if (val == 0) {
3132 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (NoException)");
3133 }
3134 hal_trace_output((unsigned char *)crash_buf, len);
3135 hal_trace_output_linefeed();
3136 hal_trace_output_linefeed();
3137
3138 hal_trace_flush_buffer();
3139
3140 len = snprintf(crash_buf, sizeof(crash_buf), "ICSR =%08X, AIRCR=%08X, SCR =%08X, CCR =%08X" NEW_LINE_STR,
3141 (unsigned)info->ICSR, (unsigned)info->AIRCR, (unsigned)info->SCR, (unsigned)info->CCR);
3142 hal_trace_output((unsigned char *)crash_buf, len);
3143
3144 len = snprintf(crash_buf, sizeof(crash_buf), "SHCSR=%08X, CFSR =%08X, HFSR =%08X, AFSR =%08X" NEW_LINE_STR,
3145 (unsigned)info->SHCSR, (unsigned)info->CFSR, (unsigned)info->HFSR, (unsigned)info->AFSR);
3146 hal_trace_output((unsigned char *)crash_buf, len);
3147
3148 len = snprintf(crash_buf, sizeof(crash_buf), "DFSR =%08X", (unsigned)info->DFSR);
3149 hal_trace_output((unsigned char *)crash_buf, len);
3150 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
3151 len = snprintf(crash_buf, sizeof(crash_buf), ", SFSR =%08X", (unsigned)info->SFSR);
3152 hal_trace_output((unsigned char *)crash_buf, len);
3153 #endif
3154 hal_trace_output_linefeed();
3155
3156 len = snprintf(crash_buf, sizeof(crash_buf), "MMFAR=%08X, BFAR =%08X",
3157 (unsigned)info->MMFAR, (unsigned)info->BFAR);
3158 hal_trace_output((unsigned char *)crash_buf, len);
3159 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
3160 len = snprintf(crash_buf, sizeof(crash_buf), ", SFAR =%08X", (unsigned)info->SFAR);
3161 hal_trace_output((unsigned char *)crash_buf, len);
3162 #endif
3163 hal_trace_output_linefeed();
3164 hal_trace_output_linefeed();
3165
3166 if (info->HFSR & (1 << 30)) {
3167 len = snprintf(crash_buf, sizeof(crash_buf), "(Escalation HardFault)" NEW_LINE_STR);
3168 hal_trace_output((unsigned char *)crash_buf, len);
3169 }
3170
3171 len = snprintf(crash_buf, sizeof(crash_buf), "FaultInfo :");
3172 if ((info->SHCSR & 0x13F) == 0) {
3173 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (None)");
3174 } else {
3175 if (info->SHCSR & (1 << 0)) {
3176 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (MemFault)");
3177 }
3178 if (info->SHCSR & (1 << 1)) {
3179 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (BusFault)");
3180 }
3181 #ifdef __ARM_ARCH_8M_MAIN__
3182 if (info->SHCSR & (1 << 2)) {
3183 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (HardFault)");
3184 }
3185 #endif
3186 if (info->SHCSR & (1 << 3)) {
3187 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (UsageFault)");
3188 }
3189 #ifdef __ARM_ARCH_8M_MAIN__
3190 if (info->SHCSR & (1 << 4)) {
3191 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (SecureFault)");
3192 }
3193 if (info->SHCSR & (1 << 5)) {
3194 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (NMI)");
3195 }
3196 #endif
3197 if (info->SHCSR & (1 << 8)) {
3198 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Monitor)");
3199 }
3200 }
3201 hal_trace_output((unsigned char *)crash_buf, len);
3202 hal_trace_output_linefeed();
3203
3204 len = snprintf(crash_buf, sizeof(crash_buf), "FaultCause :");
3205 if (info->CFSR == 0) {
3206 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (None)");
3207 } else {
3208 if (info->CFSR & (1 << 0)) {
3209 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Instruction access violation)");
3210 }
3211 if (info->CFSR & (1 << 1)) {
3212 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Data access violation)");
3213 }
3214 if (info->CFSR & (1 << 3)) {
3215 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (MemFault on unstacking for a return from exception)");
3216 }
3217 if (info->CFSR & (1 << 4)) {
3218 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (MemFault on stacking for exception entry)");
3219 }
3220 if (info->CFSR & (1 << 5)) {
3221 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (MemFault during floating-point lazy state preservation)");
3222 }
3223 if (info->CFSR & (1 << 7)) {
3224 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (MMFAR valid)");
3225 }
3226 if (len) {
3227 hal_trace_output((unsigned char *)crash_buf, len);
3228 hal_trace_flush_buffer();
3229 len = 0;
3230 }
3231 if (info->CFSR & (1 << 8)) {
3232 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Instruction bus error)");
3233 }
3234 if (info->CFSR & (1 << 9)) {
3235 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Precise data bus error)");
3236 }
3237 #ifndef __ARM_ARCH_8M_MAIN__
3238 if (info->CFSR & (1 << 10)) {
3239 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Imprecise data bus error)");
3240 }
3241 #endif
3242 if (info->CFSR & (1 << 11)) {
3243 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (BusFault on unstacking for a return from exception)");
3244 }
3245 if (info->CFSR & (1 << 12)) {
3246 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (BusFault on stacking for exception entry)");
3247 }
3248 if (info->CFSR & (1 << 13)) {
3249 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (BusFault during floating-point lazy state preservation)");
3250 }
3251 if (info->CFSR & (1 << 15)) {
3252 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (BFAR valid)");
3253 }
3254 if (len) {
3255 hal_trace_output((unsigned char *)crash_buf, len);
3256 hal_trace_flush_buffer();
3257 len = 0;
3258 }
3259 if (info->CFSR & (1 << 16)) {
3260 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Undefined instruction UsageFault)");
3261 }
3262 if (info->CFSR & (1 << 17)) {
3263 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Invalid state UsageFault)");
3264 }
3265 if (info->CFSR & (1 << 18)) {
3266 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Invalid PC load by EXC_RETURN UsageFault)");
3267 }
3268 if (info->CFSR & (1 << 19)) {
3269 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (No coprocessor UsageFault)");
3270 }
3271 #ifdef __ARM_ARCH_8M_MAIN__
3272 if (info->CFSR & (1 << 20)) {
3273 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Stack overflow UsageFault)");
3274 }
3275 #endif
3276 if (info->CFSR & (1 << 24)) {
3277 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Unaligned access UsageFault)");
3278 }
3279 if (info->CFSR & (1 << 25)) {
3280 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Divide by zero UsageFault)");
3281 }
3282 }
3283 hal_trace_output((unsigned char *)crash_buf, len);
3284 hal_trace_output_linefeed();
3285
3286 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
3287 len = snprintf(crash_buf, sizeof(crash_buf), "SecFaultCause:");
3288 if (info->SFSR == 0) {
3289 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (None)");
3290 } else {
3291 if (info->SFSR & (1 << 0)) {
3292 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Invalid entry point)");
3293 }
3294 if (info->SFSR & (1 << 1)) {
3295 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Invalid integrity signature)");
3296 }
3297 if (info->SFSR & (1 << 2)) {
3298 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Invalid excpetion return)");
3299 }
3300 if (info->SFSR & (1 << 3)) {
3301 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Attribution unit violation)");
3302 }
3303 if (info->SFSR & (1 << 4)) {
3304 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Invalid transition)");
3305 }
3306 if (info->SFSR & (1 << 5)) {
3307 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Lazy floating-point state preservation error)");
3308 }
3309 if (info->SFSR & (1 << 6)) {
3310 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (SFAR valid)");
3311 }
3312 if (info->SFSR & (1 << 7)) {
3313 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Lazy state error)");
3314 }
3315 }
3316 hal_trace_output((unsigned char *)crash_buf, len);
3317 hal_trace_output_linefeed();
3318 #endif
3319
3320 len = snprintf(crash_buf, sizeof(crash_buf), "DebugEvent :");
3321 if (info->DFSR == 0) {
3322 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (None)");
3323 } else {
3324 if (info->DFSR & (1 << 0)) {
3325 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Halted)");
3326 }
3327 if (info->DFSR & (1 << 2)) {
3328 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Data Watchpoint Match)");
3329 }
3330 /*scan the all dwt functions*/
3331 volatile uint32_t *func = &DWT->FUNCTION0;
3332 uint32_t func_num = (DWT->CTRL >> 28) & 0xf;
3333
3334 for (int i = 0; i < func_num; i++) {
3335 if (*func & DWT_FUNCTION_MATCHED_Msk) {
3336 len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Function %d matched)", i);
3337 }
3338 func += 4;
3339 }
3340 }
3341
3342 hal_trace_output((unsigned char *)crash_buf, len);
3343 hal_trace_output_linefeed();
3344 }
3345 #endif
3346
hal_trace_print_fault_info(const struct EXCEPTION_INFO_T * info)3347 static void hal_trace_print_fault_info(const struct EXCEPTION_INFO_T *info)
3348 {
3349 #ifdef __ARM_ARCH_ISA_ARM
3350 hal_trace_print_fault_info_ca(info);
3351 #else
3352 hal_trace_print_fault_info_cm(info);
3353 #endif
3354 }
3355 #endif // DEBUG || REL_TRACE_ENABLE
3356
hal_trace_fault_dump(const uint32_t * regs,const uint32_t * extra,uint32_t extra_len)3357 void hal_trace_fault_dump(const uint32_t *regs, const uint32_t *extra, uint32_t extra_len)
3358 {
3359 struct EXCEPTION_INFO_T info;
3360
3361 crash_occurs[get_cpu_id()] = true;
3362 #if defined(CHIP_BEST1501SIMU) || defined(CHIP_BEST1600SIMU)
3363 hal_cmu_simu_set_val(0xdddddddd);
3364 #endif
3365
3366 int_lock_global();
3367
3368 hal_trace_fill_exception_info(&info, regs, extra, extra_len);
3369
3370 *(volatile uint32_t *)RAM_BASE = (uint32_t)&info;
3371
3372 #if (defined(DEBUG) || defined(REL_TRACE_ENABLE))
3373
3374 static const char title[] = NEW_LINE_STR "### EXCEPTION ###" NEW_LINE_STR;
3375 int len;
3376
3377 #ifdef CP_TRACE_ENABLE
3378 // Release all the possible trace locks
3379 hal_trace_cp_force_unlock();
3380 #endif
3381 // Continue the trace
3382 hal_trace_force_continue();
3383
3384 #ifdef CRASH_DUMP_ENABLE
3385 bool full_dump = true;
3386
3387 #ifdef CP_TRACE_ENABLE
3388 if (get_cpu_id()) {
3389 full_dump = false;
3390 if (cp_notify_cb) {
3391 cp_notify_cb(HAL_TRACE_STATE_CRASH_FAULT_START);
3392 }
3393 }
3394 #endif
3395
3396 if (full_dump) {
3397 #ifdef TRACE_TO_APP
3398 hal_trace_app_notify_callback(HAL_TRACE_STATE_CRASH_FAULT_START);
3399 #endif
3400 }
3401 #endif
3402
3403 hal_trace_flush_buffer();
3404
3405 hal_sysfreq_req(HAL_SYSFREQ_USER_INIT, HAL_CMU_FREQ_52M);
3406
3407 len = hal_trace_print_time(TR_LEVEL_CRITICAL, TR_MODULE_NONE, &crash_buf[0], sizeof(crash_buf));
3408 if (len > 0) {
3409 hal_trace_output_linefeed();
3410 hal_trace_output((unsigned char *)crash_buf, len);
3411 }
3412 hal_trace_output((unsigned char *)title, sizeof(title) - 1);
3413
3414 hal_trace_print_fault_info(&info);
3415
3416 hal_trace_flush_buffer();
3417
3418 hal_trace_print_stack(regs[13]);
3419
3420 hal_trace_print_backtrace(regs[13], TRACE_BACKTRACE_SEARCH_WORD, TRACE_BACKTRACE_NUM);
3421
3422 hal_trace_output_linefeed();
3423
3424 hal_trace_flush_buffer();
3425
3426 #ifdef CRASH_DUMP_ENABLE
3427 if (full_dump) {
3428 hal_trace_crash_dump_callback();
3429 hal_trace_flush_buffer();
3430
3431 #ifndef __ARM_ARCH_ISA_ARM
3432 #ifdef TRACE_TO_APP
3433 // Crash-Dump "Lite-Version"
3434 if (app_crash_custom_cb) {
3435 uint32_t *stack;
3436 app_crash_custom_cb((unsigned char *)regs,
3437 CRASH_DUMP_REGISTERS_NUM_BYTES);
3438 stack = (uint32_t *)(__get_MSP() & ~3);
3439 app_crash_custom_cb((unsigned char *)stack,
3440 ((CRASH_DUMP_STACK_NUM_BYTES)/2));
3441 stack = (uint32_t *)(__get_PSP() & ~3);
3442 app_crash_custom_cb((unsigned char *)stack,
3443 ((CRASH_DUMP_STACK_NUM_BYTES)/2));
3444 }
3445 #endif
3446
3447 #ifdef CORE_DUMP
3448 {
3449 static CrashCatcherExceptionRegisters eregs;
3450
3451 eregs.msp = info.MSP;
3452 eregs.psp = info.PSP;
3453 eregs.exceptionPSR = regs[16] & 0x0700FE00;
3454 eregs.r4 = regs[4];
3455 eregs.r5 = regs[5];
3456 eregs.r6 = regs[6];
3457 eregs.r7 = regs[7];
3458 eregs.r8 = regs[8];
3459 eregs.r9 = regs[9];
3460 eregs.r10 = regs[10];
3461 eregs.r11 = regs[11];
3462 eregs.exceptionLR = regs[19];
3463 CrashCatcher_Entry( &eregs);
3464 }
3465 #endif
3466 #endif // !__ARM_ARCH_ISA_ARM
3467
3468 #ifdef TRACE_TO_APP
3469 hal_trace_app_notify_callback(HAL_TRACE_STATE_CRASH_END);
3470 #endif
3471 }
3472
3473 #ifdef CP_TRACE_ENABLE
3474 if (get_cpu_id()) {
3475 if (cp_notify_cb) {
3476 cp_notify_cb(HAL_TRACE_STATE_CRASH_END);
3477 }
3478 SAFE_PROGRAM_STOP();
3479 }
3480 #endif
3481 #endif // CRASH_DUMP_ENABLE
3482
3483 #endif // DEBUG || REL_TRACE_ENABLE
3484
3485 hal_trace_crash_end();
3486 }
3487
3488 #ifndef __ARM_ARCH_ISA_ARM
hal_trace_fault_handler(void)3489 static void NAKED hal_trace_fault_handler(void)
3490 {
3491 // TODO: Save FP registers (and check lazy floating-point context preservation)
3492
3493 // Registers saved in SP
3494 // R0-R15 PSR SPECIAL_REGS MSP EXC_RETURN
3495
3496 asm volatile (
3497 // Get special_regs(primask/faultmask/basepri/control)
3498 "mrs r0, primask;"
3499 "mrs r1, faultmask;"
3500 "mrs r2, basepri;"
3501 "mrs r3, control;"
3502 "bfi r12, r0, #0, #8;"
3503 "bfi r12, r1, #8, #8;"
3504 "bfi r12, r2, #16, #8;"
3505 "bfi r12, r3, #24, #8;"
3506 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
3507 // Check EXC_RETURN.S (bit[6])
3508 "tst lr, #0x40;"
3509 "bne _get_sec_sp;"
3510 // EXC_RETURN.ES must be 1 here
3511 // Check EXC_RETURN.MODE (bit[3]) and CONTROL.SPSEL (bit[1])
3512 "ubfx r3, lr, #3, #1;"
3513 "mrs r2, control_ns;"
3514 "ubfx r2, r2, #1, #1;"
3515 "ands r3, r2;"
3516 "ite ne;"
3517 // Using PSP_NS
3518 "mrsne r3, psp_ns;"
3519 // Using MSP_NS
3520 "mrseq r3, msp_ns;"
3521 "b _save_msp_lr;"
3522 "_get_sec_sp:;"
3523 #endif
3524 // Check EXC_RETURN.MODE (bit[3]) and EXC_RETURN.SPSEL (bit[2])
3525 "and r3, lr, #0x0C;"
3526 "teq r3, #0x0C;"
3527 "ite eq;"
3528 // Using PSP
3529 "mrseq r3, psp;"
3530 // Using MSP
3531 "mrsne r3, msp;"
3532 "_save_msp_lr:;"
3533 // Save original MSP and current exception lr
3534 "mrs r0, msp;"
3535 "push {r0, lr};"
3536 ".cfi_def_cfa_offset 4*2;"
3537 ".cfi_rel_offset lr, 4*1;"
3538 #ifdef ARM_CMNS
3539 // -- Check EXC_RETURN.S (bit[6])
3540 "tst lr, #0x40;"
3541 "beq _check_fp_cntx;"
3542 // Save special_regs(primask/faultmask/basepri/control)
3543 "str r12, [sp, #-4]!;"
3544 // Save 0 as psr
3545 "mov r1, 0;"
3546 "str r1, [sp, #-4]!;"
3547 // Save 0 as pc
3548 "str r1, [sp, #-4]!;"
3549 // Save 0 as lr
3550 "str r1, [sp, #-4]!;"
3551 // Save sp
3552 "str r0, [sp, #-4]!;"
3553 // Save 0 as r0-12
3554 "str r1, [sp, #-4]!;"
3555 "str r1, [sp, #-4]!;"
3556 "str r1, [sp, #-4]!;"
3557 "str r1, [sp, #-4]!;"
3558 "str r1, [sp, #-4]!;"
3559 "str r1, [sp, #-4]!;"
3560 "str r1, [sp, #-4]!;"
3561 "str r1, [sp, #-4]!;"
3562 "str r1, [sp, #-4]!;"
3563 "str r1, [sp, #-4]!;"
3564 "str r1, [sp, #-4]!;"
3565 "str r1, [sp, #-4]!;"
3566 "str r1, [sp, #-4]!;"
3567 "b _call_fault_handler;"
3568 #elif defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
3569 // -- Check EXC_RETURN.DCRS (bit[5])
3570 "tst lr, #0x20;"
3571 "beq _get_callee_saved_regs;"
3572 // -- Check EXC_RETURN.ES (bit[0])
3573 "tst lr, #0x01;"
3574 "bne _check_fp_cntx;"
3575 "_get_callee_saved_regs:;"
3576 "add r3, #4*2;"
3577 "ldm r3!, {r4-r11};"
3578 #endif
3579 "_check_fp_cntx:;"
3580 // Check EXC_RETURN.FType (bit[4])
3581 "tst lr, #0x10;"
3582 "ite eq;"
3583 // FPU context saved
3584 "moveq r1, #1;"
3585 // No FPU context
3586 "movne r1, #0;"
3587 // Make room for r0-r15,psr,special_regs(primask/faultmask/basepri/control)
3588 "sub sp, #4*18;"
3589 ".cfi_adjust_cfa_offset 4*18;"
3590 // Save r4-r11
3591 "add r0, sp, #4*4;"
3592 "stm r0, {r4-r11};"
3593 ".cfi_rel_offset r4, 4*4;"
3594 ".cfi_rel_offset r5, 4*5;"
3595 ".cfi_rel_offset r6, 4*6;"
3596 ".cfi_rel_offset r7, 4*7;"
3597 ".cfi_rel_offset r8, 4*8;"
3598 ".cfi_rel_offset r9, 4*9;"
3599 ".cfi_rel_offset r10, 4*10;"
3600 ".cfi_rel_offset r11, 4*11;"
3601 // Save r0-r3
3602 "ldm r3, {r4-r7};"
3603 "stm sp, {r4-r7};"
3604 ".cfi_rel_offset r0, 4*0;"
3605 ".cfi_rel_offset r1, 4*1;"
3606 ".cfi_rel_offset r2, 4*2;"
3607 ".cfi_rel_offset r3, 4*3;"
3608 // Save r12
3609 "ldr r0, [r3, #4*4];"
3610 "str r0, [sp, #4*12];"
3611 ".cfi_rel_offset r12, 4*12;"
3612 // Save sp
3613 "teq r1, 0;"
3614 "itt eq;"
3615 "addeq r0, r3, #4*8;"
3616 "beq _done_stack_frame;"
3617 "add r0, r3, #4*(8+18);"
3618 "_done_stack_frame:;"
3619 // -- Check RETPSR.SPREALIGN (bit[9])
3620 "ldr r4, [r3, #4*7];"
3621 "tst r4, #(1 << 9);"
3622 "it ne;"
3623 "addne r0, #4;"
3624 "str r0, [sp, #4*13];"
3625 // Save lr
3626 "ldr r0, [r3, #4*5];"
3627 "str r0, [sp, #4*14];"
3628 // Save pc
3629 "ldr r0, [r3, #4*6];"
3630 "str r0, [sp, #4*15];"
3631 // Save PSR
3632 "ldr r0, [r3, #4*7];"
3633 "str r0, [sp, #4*16];"
3634 // Save special_regs(primask/faultmask/basepri/control)
3635 "str r12, [sp, #4*17];"
3636 "_call_fault_handler:;"
3637 // Invoke the fault handler
3638 "mov r0, sp;"
3639 "mov r1, 0;"
3640 "mov r2, 0;"
3641 "ldr r3, =hal_trace_fault_dump;"
3642 "blx r3;"
3643 // Restore r4-r7
3644 "add r0, sp, #4*4;"
3645 "ldm r0, {r4-r7};"
3646 // Restore sp
3647 "add sp, #18*4;"
3648 ".cfi_adjust_cfa_offset -4*18;"
3649 "pop {r0, lr};"
3650 ".cfi_adjust_cfa_offset -4*2;"
3651 ".cfi_restore lr;"
3652 ".cfi_def_cfa_offset 0;"
3653 "bx lr;"
3654 ""
3655 );
3656 }
3657 #endif
3658 #endif
3659
3660 //==============================================================================
3661 // TRACE RX
3662 //==============================================================================
3663
3664 #if (defined(DEBUG) || defined(REL_TRACE_ENABLE))
3665
3666 enum HAL_TRACE_RX_STATE_T {
3667 HAL_TRACE_RX_STATE_CLOSED = 0,
3668 HAL_TRACE_RX_STATE_OPENED,
3669 HAL_TRACE_RX_STATE_SLEEP,
3670 };
3671
3672 static enum HAL_TRACE_RX_STATE_T trace_rx_state;
3673 static uint8_t *trace_rx_buf;
3674 static uint32_t trace_rx_len;
3675 static HAL_TRACE_RX_CALLBACK_T trace_rx_cb;
3676
hal_trace_rx_start(void)3677 static void hal_trace_rx_start(void)
3678 {
3679 uint32_t desc_cnt = 1;
3680 union HAL_UART_IRQ_T mask;
3681 struct HAL_DMA_DESC_T dma_desc_rx;
3682 int ret;
3683
3684 mask.reg = 0;
3685 mask.BE = 0;
3686 mask.FE = 0;
3687 mask.OE = 0;
3688 mask.PE = 0;
3689 mask.RT = 1;
3690
3691 // TODO: Use stream mode
3692 ret = hal_uart_dma_recv_mask(trace_uart, trace_rx_buf, trace_rx_len, &dma_desc_rx, &desc_cnt, &mask);
3693 ASSERT(ret == 0, "%s: Failed to start dma rx: %d", __func__, ret);
3694 }
3695
hal_trace_rx_stop(void)3696 static void hal_trace_rx_stop(void)
3697 {
3698 union HAL_UART_IRQ_T mask;
3699
3700 hal_uart_stop_dma_recv(trace_uart);
3701
3702 mask.reg = 0;
3703 hal_uart_irq_set_mask(trace_uart, mask);
3704 }
3705
hal_trace_rx_irq_handler(uint32_t xfer_size,int dma_error,union HAL_UART_IRQ_T status)3706 static void hal_trace_rx_irq_handler(uint32_t xfer_size, int dma_error, union HAL_UART_IRQ_T status)
3707 {
3708 POSSIBLY_UNUSED int res = 0;
3709
3710 if (trace_rx_cb == NULL) {
3711 return;
3712 }
3713
3714 if (xfer_size) {
3715 res = trace_rx_cb(trace_rx_buf, xfer_size);
3716 //TRACE(0, "%s: trace_rx_cb (%p) prase data error: %d", __func__, trace_rx_cb, res);
3717 }
3718 if (xfer_size || status.RT) {
3719 if (trace_rx_state == HAL_TRACE_RX_STATE_OPENED) {
3720 hal_trace_rx_start();
3721 }
3722 }
3723 }
3724
hal_trace_rx_open(unsigned char * buf,unsigned int len,HAL_TRACE_RX_CALLBACK_T rx_callback)3725 int hal_trace_rx_open(unsigned char *buf, unsigned int len, HAL_TRACE_RX_CALLBACK_T rx_callback)
3726 {
3727 if (buf == NULL || len == 0 || rx_callback == NULL) {
3728 return 1;
3729 }
3730
3731 if (!hal_trace_is_uart_transport(trace_transport)) {
3732 return 2;
3733 }
3734
3735 #if (TRACE_BUF_SIZE <= 0)
3736 int ret;
3737
3738 trace_uart = HAL_UART_ID_0 + (trace_transport - HAL_TRACE_TRANSPORT_UART0);
3739 ret = hal_uart_open(trace_uart, &uart_cfg);
3740 if (ret) {
3741 return ret;
3742 }
3743 #endif
3744
3745 trace_rx_buf = buf;
3746 trace_rx_len = len;
3747 trace_rx_cb = rx_callback;
3748
3749 hal_uart_irq_set_dma_handler(trace_uart, hal_trace_rx_irq_handler, NULL);
3750
3751 if (trace_rx_state != HAL_TRACE_RX_STATE_OPENED) {
3752 trace_rx_state = HAL_TRACE_RX_STATE_OPENED;
3753 hal_trace_rx_start();
3754 }
3755
3756 return 0;
3757 }
3758
hal_trace_rx_close(void)3759 int hal_trace_rx_close(void)
3760 {
3761 uint32_t lock;
3762
3763 if (!hal_trace_is_uart_transport(trace_transport)) {
3764 return 2;
3765 }
3766
3767 lock = int_lock();
3768 hal_trace_rx_stop();
3769 trace_rx_state = HAL_TRACE_RX_STATE_CLOSED;
3770 int_unlock(lock);
3771
3772 trace_rx_buf = NULL;
3773 trace_rx_len = 0;
3774 trace_rx_cb = NULL;
3775
3776 #if (TRACE_BUF_SIZE <= 0)
3777 hal_uart_close(trace_uart);
3778 #endif
3779
3780 return 0;
3781 }
3782
hal_trace_rx_sleep(void)3783 int hal_trace_rx_sleep(void)
3784 {
3785 uint32_t lock;
3786
3787 if (trace_rx_state != HAL_TRACE_RX_STATE_OPENED) {
3788 return 1;
3789 }
3790
3791 lock = int_lock();
3792 hal_trace_rx_stop();
3793 trace_rx_state = HAL_TRACE_RX_STATE_SLEEP;
3794 int_unlock(lock);
3795
3796 return 0;
3797 }
3798
hal_trace_rx_wakeup(void)3799 int hal_trace_rx_wakeup(void)
3800 {
3801 if (trace_rx_state != HAL_TRACE_RX_STATE_SLEEP) {
3802 return 1;
3803 }
3804
3805 if (trace_rx_buf == NULL || trace_rx_len == 0 || trace_rx_cb == NULL) {
3806 return 2;
3807 }
3808
3809 trace_rx_state = HAL_TRACE_RX_STATE_OPENED;
3810 hal_trace_rx_start();
3811
3812 return 0;
3813 }
3814
3815 #endif
3816
3817 #ifdef TOTA_CRASH_DUMP_TOOL_ENABLE
hal_trace_crash_dump_printf(uint32_t attr,const char * fmt,...)3818 int hal_trace_crash_dump_printf(uint32_t attr, const char *fmt, ...)
3819 {
3820 int ret;
3821 va_list ap;
3822 char buf[120];
3823 int len = 0;
3824 enum TR_LEVEL_T level;
3825 enum TR_MODULE_T module;
3826
3827 if (attr & TR_ATTR_IMM) {
3828 hal_trace_flush_buffer();
3829 }
3830
3831 va_start(ap, fmt);
3832
3833 level = GET_BITFIELD(attr, TR_ATTR_LEVEL);
3834 module = GET_BITFIELD(attr, TR_ATTR_MOD);
3835
3836 #ifdef CRASH_DUMP_ENABLE
3837 if (!in_crash_dump)
3838 #endif
3839 {
3840 if (level > get_hal_trace_log_level()) {
3841 return 0;
3842 }
3843 if (level > TR_LEVEL_CRITICAL && (trace_mod_map[module >> 5] & (1 << (module & 0x1F))) == 0) {
3844 return 0;
3845 }
3846 }
3847
3848 len = 0;
3849 if ((attr & TR_ATTR_NO_TS) == 0)
3850 {
3851 len += hal_trace_print_time(level, module, &buf[len], sizeof(buf) - len);
3852 }
3853 len += hal_trace_format_va(attr, &buf[len], sizeof(buf) - len, fmt, ap);
3854 ret = hal_trace_output((unsigned char *)buf, len);
3855 va_end(ap);
3856
3857 if (attr & TR_ATTR_IMM) {
3858 hal_trace_flush_buffer();
3859 }
3860
3861 return ret;
3862 }
3863 #endif
3864
3865 #if (TRACE_BUF_SIZE > 0)
3866 #define UART_CRLF "\r\n"
3867 #define UART_LFCR "\n\r"
3868 #define UART_CR "\r"
3869 #define UART_LF "\n"
3870 #define UART_MAX_TEMP 128
hal_trace_output_crlf(const unsigned char * buf,unsigned int len,bool block_flag)3871 int hal_trace_output_crlf(const unsigned char *buf, unsigned int len,bool block_flag)
3872 {
3873 char p_str[UART_MAX_TEMP];
3874 char *p_data;
3875 uint32_t j;
3876 uint32_t str_len = len;
3877 if (buf == NULL)
3878 {
3879 return -1;
3880 }
3881 uint32_t lock;
3882 uint32_t avail = 0;
3883 if (block_flag)
3884 {
3885 lock = int_lock();
3886 if (p_trace->wptr >= p_trace->rptr) {
3887 avail = TRACE_BUF_SIZE - (p_trace->wptr - p_trace->rptr) - 1;
3888 } else {
3889 avail = (p_trace->rptr - p_trace->wptr) - 1;
3890 }
3891 int_unlock(lock);
3892 if (avail < (len+1024)) {
3893 hal_trace_flush_buffer();
3894 }
3895 }
3896 p_data = (char *)buf;
3897 j=0;
3898 for(int i =0;i<str_len;i++){
3899 p_str[j++] = p_data[i];
3900 if(p_data[i]=='\r' && p_data[i+1]!='\n'){
3901 p_str[j]='\n';
3902 j++;
3903 continue;
3904 }
3905 if(p_data[i]=='\n'){
3906 p_str[j-1] = '\r';
3907 p_str[j] = '\n';
3908 j++;
3909 continue;
3910 }
3911 if(j<UART_MAX_TEMP)
3912 {
3913 continue;
3914 }
3915 if(j>0){
3916 hal_trace_output((const unsigned char *)p_str,j);
3917 j=0;
3918 }
3919 }
3920 if(j>0){
3921 hal_trace_output((const unsigned char *)p_str,j);
3922 j = 0;
3923 }
3924 return len;
3925 }
hal_trace_output_block(const unsigned char * buf,unsigned int len)3926 int hal_trace_output_block(const unsigned char *buf, unsigned int len)
3927 {
3928 uint32_t lock;
3929 uint32_t avail = 0;
3930 lock = int_lock();
3931 if (p_trace->wptr >= p_trace->rptr) {
3932 avail = TRACE_BUF_SIZE - (p_trace->wptr - p_trace->rptr) - 1;
3933 } else {
3934 avail = (p_trace->rptr - p_trace->wptr) - 1;
3935 }
3936 int_unlock(lock);
3937 if (avail < (len+1024)) {
3938 hal_trace_flush_buffer();
3939 }
3940
3941 return hal_trace_output((unsigned char *)buf, len);
3942 }
3943 #endif
3944
3945 #ifndef __ARM_ARCH_ISA_ARM
3946 #define A7_TRACE_TAG "A7_TRACE:"
3947 int _print_a7_flush = 0;
hal_trace_print_a7_flush(int onoff)3948 void hal_trace_print_a7_flush(int onoff)
3949 {
3950 _print_a7_flush = onoff;
3951 TRACE(0, "%s onoff=%d", __FUNCTION__, onoff);
3952 }
3953
hal_trace_print_a7(const unsigned char * buf,unsigned int buf_len)3954 void hal_trace_print_a7(const unsigned char *buf, unsigned int buf_len)
3955 {
3956 /* check platform trace on/off */
3957 if (get_hal_trace_onoff() == 1)
3958 {
3959 return;
3960 }
3961
3962 /* output trace by local driver */
3963 if (buf && (buf_len > 0)) {
3964 if (_print_a7_flush == 0) // don't add A7_TRACE_TAG for A7 crashdump
3965 hal_trace_output((const unsigned char *)A7_TRACE_TAG, sizeof(A7_TRACE_TAG));
3966 hal_trace_output(buf, buf_len);
3967 if (_print_a7_flush) {
3968 hal_trace_flush_buffer();
3969 }
3970 }
3971 }
3972 #endif
3973