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 54const CHAR *g_logString[] = { 55 "EMG", 56 "COMMON", 57 "ERR", 58 "WARN", 59 "INFO", 60 "DEBUG", 61 "TRACE" 62}; 63 64const CHAR *OsLogLvGet(INT32 level) 65{ 66 return g_logString[level]; 67} 68 69STATIC 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 75STATIC 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 90STATIC 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 107VOID 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 130STATIC VOID OsVprintfFree(CHAR *buf, UINT32 bufLen) 131{ 132 if (bufLen != SIZEBUF) { 133 (VOID)LOS_MemFree(m_aucSysMem0, buf); 134 } 135} 136 137VOID 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 188VOID UartVprintf(const CHAR *fmt, va_list ap) 189{ 190 OsVprintf(fmt, ap, UART_OUTPUT); 191} 192 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 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 216VOID 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 227VOID 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 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 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 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 262VOID 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 275VOID 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