1 /* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
2 
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 
16 #include "tensorflow/lite/micro/debug_log.h"
17 
18 #include <cstdint>
19 #include <cstdio>
20 #include <cstring>
21 
22 // Print to debug console by default. One can define next to extend destinations
23 // set: EMSDP_LOG_TO_MEMORY
24 //   : fill .debug_log memory region (data section) with passed chars.
25 // EMSDP_LOG_TO_HOST
26 //   : Use MetaWare HostLink to print output log. Requires Synopsys MetaWare
27 //   debugger
28 // EMSDP_LOG_TO_UART
29 //   : use default debug UART (out to FTDI channel 0). The same USB Port is used
30 //   for JTAG.
31 #define EMSDP_LOG_TO_UART
32 
33 // Memory size for symbols dump in EMSDP_LOG_TO_MEMORY destination
34 #define EMSDP_LOG_TO_MEMORY_SIZE (2 * 1024)
35 
36 // EMSDP Debug UART related defines (registers and bits)
37 #define EMSDP_DBG_UART_BASE (0xF0004000U)
38 #define DW_UART_CPR_FIFO_STAT (1 << 10)
39 #define DW_UART_USR_TFNF (0x02)
40 #define DW_UART_LSR_TXD_EMPTY (0x20)
41 
42 // EMSDP UART registers map (only necessairy fields)
43 typedef volatile struct dw_uart_reg {
44   uint32_t DATA; /* data in/out and DLL */
45   uint32_t RES1[4];
46   uint32_t LSR; /* Line Status Register */
47   uint32_t RES2[25];
48   uint32_t USR; /* UART status register */
49   uint32_t RES3[29];
50   uint32_t CPR; /* Component parameter register */
51 } DW_UART_REG;
52 
53 // For simplicity we assume U-boot has already initialized debug console during
54 // application loading (or on reset). Hence, we use only status and data
55 // registers to organize blocking loop for printing symbols. No input and no IRQ
56 // handling. See embarc_osp repository for full EMSDP uart driver.
57 // (https://github.com/foss-for-synopsys-dwc-arc-processors/embarc_osp)
DbgUartSendStr(const char * s)58 void DbgUartSendStr(const char* s) {
59   DW_UART_REG* uart_reg_ptr = (DW_UART_REG*)(EMSDP_DBG_UART_BASE);
60   const char* src = s;
61   while (*src) {
62     // Check uart status to send char
63     bool uart_is_ready = false;
64     if (uart_reg_ptr->CPR & DW_UART_CPR_FIFO_STAT)
65       uart_is_ready = ((uart_reg_ptr->USR & DW_UART_USR_TFNF) != 0);
66     else
67       uart_is_ready = ((uart_reg_ptr->LSR & DW_UART_LSR_TXD_EMPTY) != 0);
68 
69     // Send char if uart is ready.
70     if (uart_is_ready) uart_reg_ptr->DATA = *src++;
71   }
72 }
73 
74 // Simple dump of symbols to a pre-allocated memory region.
75 // When total log exceeds memory region size, cursor is moved to its begining.
76 // The memory region can be viewed afterward with debugger.
77 // It can be viewed/read with debugger afterward.
LogToMem(const char * s)78 void LogToMem(const char* s) {
79   static int cursor = 0;
80 #pragma Bss(".debug_log")
81   static volatile char debug_log_mem[EMSDP_LOG_TO_MEMORY_SIZE];
82 #pragma Bss()
83 
84   const char* src = s;
85   while (*src) {
86     debug_log_mem[cursor] = *src++;
87     cursor = (cursor < EMSDP_LOG_TO_MEMORY_SIZE) ? cursor + 1 : 0;
88   }
89   debug_log_mem[cursor] = '^';
90 }
91 
DebugLog(const char * s)92 extern "C" void DebugLog(const char* s) {
93 #ifndef TF_LITE_STRIP_ERROR_STRINGS
94 
95 #if defined EMSDP_LOG_TO_UART
96   DbgUartSendStr(s);
97 #endif
98 
99 #if defined EMSDP_LOG_TO_MEMORY
100 #warning \
101     "EMSDP_LOG_TO_MEMORY is defined. View .debug_log memory region for stdout"
102   LogToMem(s);
103 #endif
104 
105 #if defined EMSDP_LOG_TO_HOST
106 #warning "EMSDP_LOG_TO_HOST is defined. Ensure hostlib is linked."
107   fprintf(stderr, "%s", s);
108 #endif
109 
110 #endif  // TF_LITE_STRIP_ERROR_STRINGS
111 }
112