1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "los_base.h"
33 #ifdef LOSCFG_LIB_LIBC
34 #include "stdlib.h"
35 #include "unistd.h"
36 #endif
37 #include "los_hwi.h"
38 #include "los_memory_pri.h"
39 #ifdef LOSCFG_FS_VFS
40 #include "console.h"
41 #endif
42 #ifdef LOSCFG_SHELL_DMESG
43 #include "dmesg_pri.h"
44 #endif
45 #ifdef LOSCFG_SAVE_EXCINFO
46 #include "los_excinfo_pri.h"
47 #endif
48 #include "los_exc_pri.h"
49 #include "los_sched_pri.h"
50
51 #define SIZEBUF 256
52
53 const CHAR *g_logString[] = {
54 "EMG",
55 "COMMON",
56 "ERR",
57 "WARN",
58 "INFO",
59 "DEBUG",
60 "TRACE"
61 };
62
OsLogLvGet(INT32 level)63 const CHAR *OsLogLvGet(INT32 level)
64 {
65 return g_logString[level];
66 }
67
ErrorMsg(VOID)68 STATIC VOID ErrorMsg(VOID)
69 {
70 const CHAR *p = "Output illegal string! vsnprintf_s failed!\n";
71 UartPuts(p, (UINT32)strlen(p), UART_WITH_LOCK);
72 }
73
UartOutput(const CHAR * str,UINT32 len,BOOL isLock)74 STATIC VOID UartOutput(const CHAR *str, UINT32 len, BOOL isLock)
75 {
76 #ifdef LOSCFG_SHELL_DMESG
77 if (!OsCheckUartLock()) {
78 UartPuts(str, len, isLock);
79 }
80 if (isLock != UART_WITHOUT_LOCK) {
81 (VOID)OsLogMemcpyRecord(str, len);
82 }
83 #else
84 UartPuts(str, len, isLock);
85 #endif
86 }
87
88 #ifdef LOSCFG_PLATFORM_CONSOLE
ConsoleOutput(const CHAR * str,UINT32 len)89 STATIC VOID ConsoleOutput(const CHAR *str, UINT32 len)
90 {
91 ssize_t writen = 0;
92 ssize_t cnt;
93 ssize_t toWrite = len;
94
95 for (;;) {
96 cnt = write(STDOUT_FILENO, str + writen, (size_t)toWrite);
97 if ((cnt < 0) || ((cnt == 0) && ((!OsPreemptable()) || (OS_INT_ACTIVE))) || (toWrite == cnt)) {
98 break;
99 }
100 writen += cnt;
101 toWrite -= cnt;
102 }
103 }
104 #endif
105
OutputControl(const CHAR * str,UINT32 len,OutputType type)106 VOID OutputControl(const CHAR *str, UINT32 len, OutputType type)
107 {
108 switch (type) {
109 case CONSOLE_OUTPUT:
110 #ifdef LOSCFG_PLATFORM_CONSOLE
111 if (ConsoleEnable() == TRUE) {
112 ConsoleOutput(str, len);
113 break;
114 }
115 #endif
116 /* fall-through */
117 case UART_OUTPUT:
118 UartOutput(str, len, UART_WITH_LOCK);
119 break;
120 case EXC_OUTPUT:
121 UartPuts(str, len, UART_WITH_LOCK);
122 break;
123 default:
124 break;
125 }
126 return;
127 }
128
OsVprintfFree(CHAR * buf,UINT32 bufLen)129 STATIC VOID OsVprintfFree(CHAR *buf, UINT32 bufLen)
130 {
131 if (bufLen != SIZEBUF) {
132 (VOID)LOS_MemFree(m_aucSysMem0, buf);
133 }
134 }
135
OsVprintf(const CHAR * fmt,va_list ap,OutputType type)136 VOID OsVprintf(const CHAR *fmt, va_list ap, OutputType type)
137 {
138 INT32 len;
139 const CHAR *errMsgMalloc = "OsVprintf, malloc failed!\n";
140 const CHAR *errMsgLen = "OsVprintf, length overflow!\n";
141 CHAR aBuf[SIZEBUF] = {0};
142 CHAR *bBuf = NULL;
143 UINT32 bufLen = SIZEBUF;
144 UINT32 systemStatus;
145
146 bBuf = aBuf;
147 len = vsnprintf_s(bBuf, bufLen, bufLen - 1, fmt, ap);
148 if ((len == -1) && (*bBuf == '\0')) {
149 /* parameter is illegal or some features in fmt dont support */
150 ErrorMsg();
151 return;
152 }
153
154 while (len == -1) {
155 /* bBuf is not enough */
156 OsVprintfFree(bBuf, bufLen);
157
158 bufLen = bufLen << 1;
159 if ((INT32)bufLen <= 0) {
160 UartPuts(errMsgLen, (UINT32)strlen(errMsgLen), UART_WITH_LOCK);
161 return;
162 }
163 bBuf = (CHAR *)LOS_MemAlloc(m_aucSysMem0, bufLen);
164 if (bBuf == NULL) {
165 UartPuts(errMsgMalloc, (UINT32)strlen(errMsgMalloc), UART_WITH_LOCK);
166 return;
167 }
168 len = vsnprintf_s(bBuf, bufLen, bufLen - 1, fmt, ap);
169 if (*bBuf == '\0') {
170 /* parameter is illegal or some features in fmt dont support */
171 (VOID)LOS_MemFree(m_aucSysMem0, bBuf);
172 ErrorMsg();
173 return;
174 }
175 }
176 *(bBuf + len) = '\0';
177
178 systemStatus = OsGetSystemStatus();
179 if ((systemStatus == OS_SYSTEM_NORMAL) || (systemStatus == OS_SYSTEM_EXC_OTHER_CPU)) {
180 OutputControl(bBuf, len, type);
181 } else if (systemStatus == OS_SYSTEM_EXC_CURR_CPU) {
182 OutputControl(bBuf, len, EXC_OUTPUT);
183 }
184 OsVprintfFree(bBuf, bufLen);
185 }
186
UartVprintf(const CHAR * fmt,va_list ap)187 VOID UartVprintf(const CHAR *fmt, va_list ap)
188 {
189 OsVprintf(fmt, ap, UART_OUTPUT);
190 }
191
UartPrintf(const CHAR * fmt,...)192 __attribute__((noinline)) VOID UartPrintf(const CHAR *fmt, ...)
193 {
194 va_list ap;
195 va_start(ap, fmt);
196 OsVprintf(fmt, ap, UART_OUTPUT);
197 va_end(ap);
198 }
199
dprintf(const CHAR * fmt,...)200 __attribute__ ((noinline)) VOID dprintf(const CHAR *fmt, ...)
201 {
202 va_list ap;
203 va_start(ap, fmt);
204 OsVprintf(fmt, ap, CONSOLE_OUTPUT);
205 #ifdef LOSCFG_SAVE_EXCINFO
206 if (OsGetSystemStatus() == OS_SYSTEM_EXC_CURR_CPU) {
207 WriteExcBufVa(fmt, ap);
208 }
209 #endif
210 va_end(ap);
211 }
212
LkDprintf(const CHAR * fmt,va_list ap)213 VOID LkDprintf(const CHAR *fmt, va_list ap)
214 {
215 OsVprintf(fmt, ap, CONSOLE_OUTPUT);
216 #ifdef LOSCFG_SAVE_EXCINFO
217 if (OsGetSystemStatus() == OS_SYSTEM_EXC_CURR_CPU) {
218 WriteExcBufVa(fmt, ap);
219 }
220 #endif
221 }
222
223 #ifdef LOSCFG_SHELL_DMESG
DmesgPrintf(const CHAR * fmt,va_list ap)224 VOID DmesgPrintf(const CHAR *fmt, va_list ap)
225 {
226 OsVprintf(fmt, ap, CONSOLE_OUTPUT);
227 }
228 #endif
229
230 #ifdef LOSCFG_PLATFORM_UART_WITHOUT_VFS
printf(const CHAR * fmt,...)231 __attribute__ ((noinline)) INT32 printf(const CHAR *fmt, ...)
232 {
233 va_list ap;
234 va_start(ap, fmt);
235 OsVprintf(fmt, ap, UART_OUTPUT);
236 va_end(ap);
237 return 0;
238 }
239 #endif
240
syslog(INT32 level,const CHAR * fmt,...)241 __attribute__((noinline)) VOID syslog(INT32 level, const CHAR *fmt, ...)
242 {
243 va_list ap;
244 va_start(ap, fmt);
245 OsVprintf(fmt, ap, CONSOLE_OUTPUT);
246 va_end(ap);
247 (VOID)level;
248 }
249
ExcPrintf(const CHAR * fmt,...)250 __attribute__((noinline)) VOID ExcPrintf(const CHAR *fmt, ...)
251 {
252 va_list ap;
253 va_start(ap, fmt);
254 /* uart output without print-spinlock */
255 OsVprintf(fmt, ap, EXC_OUTPUT);
256 va_end(ap);
257 }
258
PrintExcInfo(const CHAR * fmt,...)259 VOID PrintExcInfo(const CHAR *fmt, ...)
260 {
261 va_list ap;
262 va_start(ap, fmt);
263 /* uart output without print-spinlock */
264 OsVprintf(fmt, ap, EXC_OUTPUT);
265 #ifdef LOSCFG_SAVE_EXCINFO
266 WriteExcBufVa(fmt, ap);
267 #endif
268 va_end(ap);
269 }
270
271 #ifndef LOSCFG_SHELL_LK
LOS_LkPrint(INT32 level,const CHAR * func,INT32 line,const CHAR * fmt,...)272 VOID LOS_LkPrint(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, ...)
273 {
274 va_list ap;
275
276 if (level > PRINT_LEVEL) {
277 return;
278 }
279
280 if ((level != LOS_COMMON_LEVEL) && ((level > LOS_EMG_LEVEL) && (level <= LOS_TRACE_LEVEL))) {
281 dprintf("[%s]", g_logString[level]);
282 }
283
284 va_start(ap, fmt);
285 OsVprintf(fmt, ap, CONSOLE_OUTPUT);
286 #ifdef LOSCFG_SAVE_EXCINFO
287 if (OsGetSystemStatus() == OS_SYSTEM_EXC_CURR_CPU) {
288 WriteExcBufVa(fmt, ap);
289 }
290 #endif
291 va_end(ap);
292 }
293 #endif
294
295