• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&regs);
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