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