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 #include "los_process_pri.h"
40 #ifdef LOSCFG_FS_VFS
41 #include "console.h"
42 #endif
43 #ifdef LOSCFG_SHELL_DMESG
44 #include "dmesg_pri.h"
45 #endif
46 #ifdef LOSCFG_SAVE_EXCINFO
47 #include "los_excinfo_pri.h"
48 #endif
49 #include "los_exc_pri.h"
50 #include "los_sched_pri.h"
51
52 #define SIZEBUF 256
53
54 const CHAR *g_logString[] = {
55 "EMG",
56 "COMMON",
57 "ERR",
58 "WARN",
59 "INFO",
60 "DEBUG",
61 "TRACE"
62 };
63
OsLogLvGet(INT32 level)64 const CHAR *OsLogLvGet(INT32 level)
65 {
66 return g_logString[level];
67 }
68
ErrorMsg(VOID)69 STATIC VOID ErrorMsg(VOID)
70 {
71 const CHAR *p = "Output illegal string! vsnprintf_s failed!\n";
72 UartPuts(p, (UINT32)strlen(p), UART_WITH_LOCK);
73 }
74
UartOutput(const CHAR * str,UINT32 len,BOOL isLock)75 STATIC VOID UartOutput(const CHAR *str, UINT32 len, BOOL isLock)
76 {
77 #ifdef LOSCFG_SHELL_DMESG
78 if (!OsCheckUartLock()) {
79 UartPuts(str, len, isLock);
80 }
81 if (isLock != UART_WITHOUT_LOCK) {
82 (VOID)OsLogMemcpyRecord(str, len);
83 }
84 #else
85 UartPuts(str, len, isLock);
86 #endif
87 }
88
89 #ifdef LOSCFG_PLATFORM_CONSOLE
ConsoleOutput(const CHAR * str,UINT32 len)90 STATIC VOID ConsoleOutput(const CHAR *str, UINT32 len)
91 {
92 ssize_t written = 0;
93 ssize_t cnt;
94 ssize_t toWrite = len;
95
96 for (;;) {
97 cnt = write(STDOUT_FILENO, str + written, (size_t)toWrite);
98 if ((cnt < 0) || ((cnt == 0) && ((!OsPreemptable()) || (OS_INT_ACTIVE))) || (toWrite == cnt)) {
99 break;
100 }
101 written += cnt;
102 toWrite -= cnt;
103 }
104 }
105 #endif
106
OutputControl(const CHAR * str,UINT32 len,OutputType type)107 VOID OutputControl(const CHAR *str, UINT32 len, OutputType type)
108 {
109 switch (type) {
110 case CONSOLE_OUTPUT:
111 #ifdef LOSCFG_PLATFORM_CONSOLE
112 if (ConsoleEnable() == TRUE) {
113 ConsoleOutput(str, len);
114 break;
115 }
116 #endif
117 /* fall-through */
118 case UART_OUTPUT:
119 UartOutput(str, len, UART_WITH_LOCK);
120 break;
121 case EXC_OUTPUT:
122 UartPuts(str, len, UART_WITH_LOCK);
123 break;
124 default:
125 break;
126 }
127 return;
128 }
129
OsVprintfFree(CHAR * buf,UINT32 bufLen)130 STATIC VOID OsVprintfFree(CHAR *buf, UINT32 bufLen)
131 {
132 if (bufLen != SIZEBUF) {
133 (VOID)LOS_MemFree(m_aucSysMem0, buf);
134 }
135 }
136
OsVprintf(const CHAR * fmt,va_list ap,OutputType type)137 VOID OsVprintf(const CHAR *fmt, va_list ap, OutputType type)
138 {
139 INT32 len;
140 const CHAR *errMsgMalloc = "OsVprintf, malloc failed!\n";
141 const CHAR *errMsgLen = "OsVprintf, length overflow!\n";
142 CHAR aBuf[SIZEBUF] = {0};
143 CHAR *bBuf = NULL;
144 UINT32 bufLen = SIZEBUF;
145 UINT32 systemStatus;
146
147 bBuf = aBuf;
148 len = vsnprintf_s(bBuf, bufLen, bufLen - 1, fmt, ap);
149 if ((len == -1) && (*bBuf == '\0')) {
150 /* parameter is illegal or some features in fmt dont support */
151 ErrorMsg();
152 return;
153 }
154
155 while (len == -1) {
156 /* bBuf is not enough */
157 OsVprintfFree(bBuf, bufLen);
158
159 bufLen = bufLen << 1;
160 if ((INT32)bufLen <= 0) {
161 UartPuts(errMsgLen, (UINT32)strlen(errMsgLen), UART_WITH_LOCK);
162 return;
163 }
164 bBuf = (CHAR *)LOS_MemAlloc(m_aucSysMem0, bufLen);
165 if (bBuf == NULL) {
166 UartPuts(errMsgMalloc, (UINT32)strlen(errMsgMalloc), UART_WITH_LOCK);
167 return;
168 }
169 len = vsnprintf_s(bBuf, bufLen, bufLen - 1, fmt, ap);
170 if (*bBuf == '\0') {
171 /* parameter is illegal or some features in fmt dont support */
172 (VOID)LOS_MemFree(m_aucSysMem0, bBuf);
173 ErrorMsg();
174 return;
175 }
176 }
177 *(bBuf + len) = '\0';
178
179 systemStatus = OsGetSystemStatus();
180 if ((systemStatus == OS_SYSTEM_NORMAL) || (systemStatus == OS_SYSTEM_EXC_OTHER_CPU)) {
181 OutputControl(bBuf, len, type);
182 } else if (systemStatus == OS_SYSTEM_EXC_CURR_CPU) {
183 OutputControl(bBuf, len, EXC_OUTPUT);
184 }
185 OsVprintfFree(bBuf, bufLen);
186 }
187
UartVprintf(const CHAR * fmt,va_list ap)188 VOID UartVprintf(const CHAR *fmt, va_list ap)
189 {
190 OsVprintf(fmt, ap, UART_OUTPUT);
191 }
192
UartPrintf(const CHAR * fmt,...)193 __attribute__((noinline)) VOID UartPrintf(const CHAR *fmt, ...)
194 {
195 va_list ap;
196 va_start(ap, fmt);
197 OsVprintf(fmt, ap, UART_OUTPUT);
198 va_end(ap);
199 }
200
201 #ifndef LOSCFG_LIBC_NEWLIB
dprintf(const CHAR * fmt,...)202 __attribute__((noinline)) VOID dprintf(const CHAR *fmt, ...)
203 {
204 va_list ap;
205 va_start(ap, fmt);
206 OsVprintf(fmt, ap, CONSOLE_OUTPUT);
207 #ifdef LOSCFG_SAVE_EXCINFO
208 if (OsGetSystemStatus() == OS_SYSTEM_EXC_CURR_CPU) {
209 WriteExcBufVa(fmt, ap);
210 }
211 #endif
212 va_end(ap);
213 }
214 #endif
215
LkDprintf(const CHAR * fmt,va_list ap)216 VOID LkDprintf(const CHAR *fmt, va_list ap)
217 {
218 OsVprintf(fmt, ap, CONSOLE_OUTPUT);
219 #ifdef LOSCFG_SAVE_EXCINFO
220 if (OsGetSystemStatus() == OS_SYSTEM_EXC_CURR_CPU) {
221 WriteExcBufVa(fmt, ap);
222 }
223 #endif
224 }
225
226 #ifdef LOSCFG_SHELL_DMESG
DmesgPrintf(const CHAR * fmt,va_list ap)227 VOID DmesgPrintf(const CHAR *fmt, va_list ap)
228 {
229 OsVprintf(fmt, ap, CONSOLE_OUTPUT);
230 }
231 #endif
232
233 #ifdef LOSCFG_PLATFORM_UART_WITHOUT_VFS
printf(const CHAR * fmt,...)234 __attribute__((noinline)) INT32 printf(const CHAR *fmt, ...)
235 {
236 va_list ap;
237 va_start(ap, fmt);
238 OsVprintf(fmt, ap, UART_OUTPUT);
239 va_end(ap);
240 return 0;
241 }
242 #endif
243
syslog(INT32 level,const CHAR * fmt,...)244 __attribute__((noinline)) VOID syslog(INT32 level, const CHAR *fmt, ...)
245 {
246 va_list ap;
247 va_start(ap, fmt);
248 OsVprintf(fmt, ap, CONSOLE_OUTPUT);
249 va_end(ap);
250 (VOID)level;
251 }
252
ExcPrintf(const CHAR * fmt,...)253 __attribute__((noinline)) VOID ExcPrintf(const CHAR *fmt, ...)
254 {
255 va_list ap;
256 va_start(ap, fmt);
257 /* uart output without print-spinlock */
258 OsVprintf(fmt, ap, EXC_OUTPUT);
259 va_end(ap);
260 }
261
PrintExcInfo(const CHAR * fmt,...)262 VOID PrintExcInfo(const CHAR *fmt, ...)
263 {
264 va_list ap;
265 va_start(ap, fmt);
266 /* uart output without print-spinlock */
267 OsVprintf(fmt, ap, EXC_OUTPUT);
268 #ifdef LOSCFG_SAVE_EXCINFO
269 WriteExcBufVa(fmt, ap);
270 #endif
271 va_end(ap);
272 }
273
274 #ifndef LOSCFG_SHELL_LK
LOS_LkPrint(INT32 level,const CHAR * func,INT32 line,const CHAR * fmt,...)275 VOID LOS_LkPrint(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, ...)
276 {
277 va_list ap;
278
279 if (level > PRINT_LEVEL) {
280 return;
281 }
282
283 if ((level != LOS_COMMON_LEVEL) && ((level > LOS_EMG_LEVEL) && (level <= LOS_TRACE_LEVEL))) {
284 PRINTK("[%s][%s:%s]", g_logString[level],
285 ((OsCurrProcessGet() == NULL) ? "NULL" : OsCurrProcessGet()->processName),
286 ((OsCurrTaskGet() == NULL) ? "NULL" : OsCurrTaskGet()->taskName));
287 }
288
289 va_start(ap, fmt);
290 OsVprintf(fmt, ap, CONSOLE_OUTPUT);
291 #ifdef LOSCFG_SAVE_EXCINFO
292 if (OsGetSystemStatus() == OS_SYSTEM_EXC_CURR_CPU) {
293 WriteExcBufVa(fmt, ap);
294 }
295 #endif
296 va_end(ap);
297 }
298 #endif
299
300