• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /*
33    +-------------------------------------------------------+
34    | Info |          log_space                             |
35    +-------------------------------------------------------+
36    |
37    |__buffer_space
38 
39 Case A:
40    +-------------------------------------------------------+
41    |           |#############################|             |
42    +-------------------------------------------------------+
43                |                             |
44               Head                           Tail
45 Case B:
46    +-------------------------------------------------------+
47    |##########|                                    |#######|
48    +-------------------------------------------------------+
49               |                                    |
50               Tail                                 Head
51 */
52 
53 #ifdef LOSCFG_SHELL_DMESG
54 #include "dmesg_pri.h"
55 #include "show.h"
56 #include "shcmd.h"
57 #include "securec.h"
58 #include "stdlib.h"
59 #include "unistd.h"
60 #include "los_init.h"
61 #include "los_task.h"
62 
63 
64 #define BUF_MAX_INDEX (g_logBufSize - 1)
65 
66 LITE_OS_SEC_BSS STATIC SPIN_LOCK_INIT(g_dmesgSpin);
67 
68 STATIC DmesgInfo *g_dmesgInfo = NULL;
69 STATIC UINT32 g_logBufSize = 0;
70 STATIC VOID *g_mallocAddr = NULL;
71 STATIC UINT32 g_dmesgLogLevel = 3;
72 STATIC UINT32 g_consoleLock = 0;
73 STATIC UINT32 g_uartLock = 0;
74 STATIC const CHAR *g_levelString[] = {
75     "EMG",
76     "COMMON",
77     "ERR",
78     "WARN",
79     "INFO",
80     "DEBUG"
81 };
82 
OsLockConsole(VOID)83 STATIC VOID OsLockConsole(VOID)
84 {
85     g_consoleLock = 1;
86 }
87 
OsUnlockConsole(VOID)88 STATIC VOID OsUnlockConsole(VOID)
89 {
90     g_consoleLock = 0;
91 }
92 
OsLockUart(VOID)93 STATIC VOID OsLockUart(VOID)
94 {
95     g_uartLock = 1;
96 }
97 
OsUnlockUart(VOID)98 STATIC VOID OsUnlockUart(VOID)
99 {
100     g_uartLock = 0;
101 }
102 
OsCheckError(VOID)103 STATIC UINT32 OsCheckError(VOID)
104 {
105     if (g_dmesgInfo == NULL) {
106         return LOS_NOK;
107     }
108 
109     if (g_dmesgInfo->logSize > g_logBufSize) {
110         return LOS_NOK;
111     }
112 
113     if (((g_dmesgInfo->logSize == g_logBufSize) || (g_dmesgInfo->logSize == 0)) &&
114         (g_dmesgInfo->logTail != g_dmesgInfo->logHead)) {
115         return LOS_NOK;
116     }
117 
118     return LOS_OK;
119 }
120 
OsDmesgRead(CHAR * buf,UINT32 len)121 STATIC INT32 OsDmesgRead(CHAR *buf, UINT32 len)
122 {
123     UINT32 readLen;
124     UINT32 logSize = g_dmesgInfo->logSize;
125     UINT32 head = g_dmesgInfo->logHead;
126     UINT32 tail = g_dmesgInfo->logTail;
127     CHAR *logBuf = g_dmesgInfo->logBuf;
128     errno_t ret;
129 
130     if (OsCheckError()) {
131         return -1;
132     }
133     if (logSize == 0) {
134         return 0;
135     }
136 
137     readLen = len < logSize ? len : logSize;
138 
139     if (head < tail) { /* Case A */
140         ret = memcpy_s(buf, len, logBuf + head, readLen);
141         if (ret != EOK) {
142             return -1;
143         }
144         g_dmesgInfo->logHead += readLen;
145         g_dmesgInfo->logSize -= readLen;
146     } else { /* Case B */
147         if (readLen <= (g_logBufSize - head)) {
148             ret = memcpy_s(buf, len, logBuf + head, readLen);
149             if (ret != EOK) {
150                 return -1;
151             }
152             g_dmesgInfo->logHead += readLen;
153             g_dmesgInfo->logSize -= readLen;
154         } else {
155             ret = memcpy_s(buf, len, logBuf + head, g_logBufSize - head);
156             if (ret != EOK) {
157                 return -1;
158             }
159 
160             ret = memcpy_s(buf + g_logBufSize - head, len - (g_logBufSize - head),
161                            logBuf, readLen - (g_logBufSize - head));
162             if (ret != EOK) {
163                 return -1;
164             }
165             g_dmesgInfo->logHead = readLen - (g_logBufSize - head);
166             g_dmesgInfo->logSize -= readLen;
167         }
168     }
169     return (INT32)readLen;
170 }
171 
OsCopyToNew(const VOID * addr,UINT32 size)172 STATIC INT32 OsCopyToNew(const VOID *addr, UINT32 size)
173 {
174     UINT32 copyStart = 0;
175     UINT32 copyLen;
176     CHAR *temp = NULL;
177     CHAR *newBuf = (CHAR *)addr + sizeof(DmesgInfo);
178     UINT32 bufSize = size - sizeof(DmesgInfo);
179     INT32 ret;
180     UINT32 intSave;
181 
182     LOS_SpinLockSave(&g_dmesgSpin, &intSave);
183     if (g_dmesgInfo->logSize == 0) {
184         LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
185         return 0;
186     }
187 
188     temp = (CHAR *)malloc(g_dmesgInfo->logSize);
189     if (temp == NULL) {
190         LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
191         return -1;
192     }
193 
194     (VOID)memset_s(temp, g_dmesgInfo->logSize, 0, g_dmesgInfo->logSize);
195     copyLen = ((bufSize < g_dmesgInfo->logSize) ? bufSize : g_dmesgInfo->logSize);
196     if (bufSize < g_dmesgInfo->logSize) {
197         copyStart = g_dmesgInfo->logSize - bufSize;
198     }
199 
200     ret = OsDmesgRead(temp, g_dmesgInfo->logSize);
201     if (ret <= 0) {
202         goto FREE_OUT;
203     }
204 
205     /* if new buf size smaller than logSize */
206     ret = memcpy_s(newBuf, bufSize, temp + copyStart, copyLen);
207     if (ret != EOK) {
208         goto FREE_OUT;
209     }
210     LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
211     free(temp);
212 
213     return (INT32)copyLen;
214 
215 FREE_OUT:
216     LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
217     PRINT_ERR("%s,%d failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
218     free(temp);
219     return -1;
220 }
221 
OsDmesgResetMem(const VOID * addr,UINT32 size)222 STATIC UINT32 OsDmesgResetMem(const VOID *addr, UINT32 size)
223 {
224     VOID *temp = NULL;
225     INT32 copyLen;
226     UINT32 intSave;
227 
228     if (size <= sizeof(DmesgInfo)) {
229         return LOS_NOK;
230     }
231 
232     LOS_SpinLockSave(&g_dmesgSpin, &intSave);
233     temp = g_dmesgInfo;
234     LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
235     copyLen = OsCopyToNew(addr, size);
236     if (copyLen < 0) {
237         return LOS_NOK;
238     }
239 
240     LOS_SpinLockSave(&g_dmesgSpin, &intSave);
241     g_logBufSize = size - sizeof(DmesgInfo);
242     g_dmesgInfo = (DmesgInfo *)addr;
243     g_dmesgInfo->logBuf = (CHAR *)addr + sizeof(DmesgInfo);
244     g_dmesgInfo->logSize = copyLen;
245     g_dmesgInfo->logTail = ((copyLen == g_logBufSize) ? 0 : copyLen);
246     g_dmesgInfo->logHead = 0;
247 
248     /* if old mem came from malloc */
249     if (temp == g_mallocAddr) {
250         goto FREE_OUT;
251     }
252     LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
253 
254     return LOS_OK;
255 
256 FREE_OUT:
257     g_mallocAddr = NULL;
258     LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
259     free(temp);
260     return LOS_OK;
261 }
262 
OsDmesgChangeSize(UINT32 size)263 STATIC UINT32 OsDmesgChangeSize(UINT32 size)
264 {
265     VOID *temp = NULL;
266     INT32 copyLen;
267     CHAR *newString = NULL;
268     UINT32 intSave;
269 
270     if (size == 0) {
271         return LOS_NOK;
272     }
273 
274     newString = (CHAR *)malloc(size + sizeof(DmesgInfo));
275     if (newString == NULL) {
276         return LOS_NOK;
277     }
278 
279     LOS_SpinLockSave(&g_dmesgSpin, &intSave);
280     temp = g_dmesgInfo;
281     LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
282 
283     copyLen = OsCopyToNew(newString, size + sizeof(DmesgInfo));
284     if (copyLen < 0) {
285         goto ERR_OUT;
286     }
287 
288     LOS_SpinLockSave(&g_dmesgSpin, &intSave);
289     g_logBufSize = size;
290     g_dmesgInfo = (DmesgInfo *)newString;
291     g_dmesgInfo->logBuf = (CHAR *)newString + sizeof(DmesgInfo);
292     g_dmesgInfo->logSize = copyLen;
293     g_dmesgInfo->logTail = ((copyLen == g_logBufSize) ? 0 : copyLen);
294     g_dmesgInfo->logHead = 0;
295 
296     if (temp == g_mallocAddr) {
297         goto FREE_OUT;
298     }
299     g_mallocAddr = newString;
300     LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
301 
302     return LOS_OK;
303 
304 ERR_OUT:
305     free(newString);
306     return LOS_NOK;
307 FREE_OUT:
308     g_mallocAddr = newString;
309     LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
310     free(temp);
311     return LOS_OK;
312 }
313 
OsCheckConsoleLock(VOID)314 UINT32 OsCheckConsoleLock(VOID)
315 {
316     return g_consoleLock;
317 }
318 
OsCheckUartLock(VOID)319 UINT32 OsCheckUartLock(VOID)
320 {
321     return g_uartLock;
322 }
323 
OsDmesgInit(VOID)324 UINT32 OsDmesgInit(VOID)
325 {
326     CHAR* buffer = NULL;
327 
328     buffer = (CHAR *)malloc(KERNEL_LOG_BUF_SIZE + sizeof(DmesgInfo));
329     if (buffer == NULL) {
330         return LOS_NOK;
331     }
332     g_mallocAddr = buffer;
333     g_dmesgInfo = (DmesgInfo *)buffer;
334     g_dmesgInfo->logHead = 0;
335     g_dmesgInfo->logTail = 0;
336     g_dmesgInfo->logSize = 0;
337     g_dmesgInfo->logBuf = buffer + sizeof(DmesgInfo);
338     g_logBufSize = KERNEL_LOG_BUF_SIZE;
339 
340     return LOS_OK;
341 }
342 
OsLogRecordChar(CHAR c)343 STATIC CHAR OsLogRecordChar(CHAR c)
344 {
345     *(g_dmesgInfo->logBuf + g_dmesgInfo->logTail++) = c;
346 
347     if (g_dmesgInfo->logTail > BUF_MAX_INDEX) {
348         g_dmesgInfo->logTail = 0;
349     }
350 
351     if (g_dmesgInfo->logSize < g_logBufSize) {
352         (g_dmesgInfo->logSize)++;
353     } else {
354         g_dmesgInfo->logHead = g_dmesgInfo->logTail;
355     }
356     return c;
357 }
358 
OsLogRecordStr(const CHAR * str,UINT32 len)359 UINT32 OsLogRecordStr(const CHAR *str, UINT32 len)
360 {
361     UINT32 i = 0;
362     UINTPTR intSave;
363 
364     LOS_SpinLockSave(&g_dmesgSpin, &intSave);
365     while (len--) {
366         (VOID)OsLogRecordChar(str[i]);
367         i++;
368     }
369     LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
370     return i;
371 }
372 
OsBufFullWrite(const CHAR * dst,UINT32 logLen)373 STATIC VOID OsBufFullWrite(const CHAR *dst, UINT32 logLen)
374 {
375     UINT32 bufSize = g_logBufSize;
376     UINT32 tail = g_dmesgInfo->logTail;
377     CHAR *buf = g_dmesgInfo->logBuf;
378     errno_t ret;
379 
380     if (!logLen || (dst == NULL)) {
381         return;
382     }
383     if (logLen > bufSize) { /* full re-write */
384         ret = memcpy_s(buf + tail, bufSize - tail, dst, bufSize - tail);
385         if (ret != EOK) {
386             PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
387             return;
388         }
389         ret = memcpy_s(buf, bufSize, dst + bufSize - tail, tail);
390         if (ret != EOK) {
391             PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
392             return;
393         }
394 
395         OsBufFullWrite(dst + bufSize, logLen - bufSize);
396     } else {
397         if (logLen > (bufSize - tail)) { /* need cycle back to start */
398             ret = memcpy_s(buf + tail, bufSize - tail, dst, bufSize - tail);
399             if (ret != EOK) {
400                 PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
401                 return;
402             }
403             ret = memcpy_s(buf, bufSize, dst + bufSize - tail, logLen - (bufSize - tail));
404             if (ret != EOK) {
405                 PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
406                 return;
407             }
408 
409             g_dmesgInfo->logTail = logLen - (bufSize - tail);
410             g_dmesgInfo->logHead = g_dmesgInfo->logTail;
411         } else { /* no need cycle back to start */
412             ret = memcpy_s(buf + tail, bufSize - tail, dst, logLen);
413             if (ret != EOK) {
414                 PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
415                 return;
416             }
417             g_dmesgInfo->logTail += logLen;
418             if (g_dmesgInfo->logTail > BUF_MAX_INDEX) {
419                 g_dmesgInfo->logTail = 0;
420             }
421             g_dmesgInfo->logHead = g_dmesgInfo->logTail;
422         }
423     }
424 }
425 
OsWriteTailToHead(const CHAR * dst,UINT32 logLen)426 STATIC VOID OsWriteTailToHead(const CHAR *dst, UINT32 logLen)
427 {
428     UINT32 writeLen;
429     UINT32 bufSize = g_logBufSize;
430     UINT32 logSize = g_dmesgInfo->logSize;
431     UINT32 tail = g_dmesgInfo->logTail;
432     CHAR *buf = g_dmesgInfo->logBuf;
433     errno_t ret;
434 
435     if ((!logLen) || (dst == NULL)) {
436         return;
437     }
438     if (logLen > (bufSize - logSize)) { /* space-need > space-remain */
439         writeLen = bufSize - logSize;
440         ret = memcpy_s(buf + tail, bufSize - tail, dst, writeLen);
441         if (ret != EOK) {
442             PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
443             return;
444         }
445 
446         g_dmesgInfo->logTail = g_dmesgInfo->logHead;
447         g_dmesgInfo->logSize = g_logBufSize;
448         OsBufFullWrite(dst + writeLen, logLen - writeLen);
449     } else {
450         ret = memcpy_s(buf + tail, bufSize - tail, dst, logLen);
451         if (ret != EOK) {
452             PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
453             return;
454         }
455 
456         g_dmesgInfo->logTail += logLen;
457         g_dmesgInfo->logSize += logLen;
458     }
459 }
460 
OsWriteTailToEnd(const CHAR * dst,UINT32 logLen)461 STATIC VOID OsWriteTailToEnd(const CHAR *dst, UINT32 logLen)
462 {
463     UINT32 writeLen;
464     UINT32 bufSize = g_logBufSize;
465     UINT32 tail = g_dmesgInfo->logTail;
466     CHAR *buf = g_dmesgInfo->logBuf;
467     errno_t ret;
468 
469     if ((!logLen) || (dst == NULL)) {
470         return;
471     }
472     if (logLen >= (bufSize - tail)) { /* need cycle to start ,then became B */
473         writeLen = bufSize - tail;
474         ret = memcpy_s(buf + tail, writeLen, dst, writeLen);
475         if (ret != EOK) {
476             PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
477             return;
478         }
479 
480         g_dmesgInfo->logSize += writeLen;
481         g_dmesgInfo->logTail = 0;
482         if (g_dmesgInfo->logSize == g_logBufSize) { /* Tail = Head is 0 */
483             OsBufFullWrite(dst + writeLen, logLen - writeLen);
484         } else {
485             OsWriteTailToHead(dst + writeLen, logLen - writeLen);
486         }
487     } else { /* just do serial copy */
488         ret = memcpy_s(buf + tail, bufSize - tail, dst, logLen);
489         if (ret != EOK) {
490             PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
491             return;
492         }
493 
494         g_dmesgInfo->logTail += logLen;
495         g_dmesgInfo->logSize += logLen;
496     }
497 }
498 
OsLogMemcpyRecord(const CHAR * buf,UINT32 logLen)499 INT32 OsLogMemcpyRecord(const CHAR *buf, UINT32 logLen)
500 {
501     UINT32 intSave;
502 
503     LOS_SpinLockSave(&g_dmesgSpin, &intSave);
504     if (OsCheckError()) {
505         LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
506         return -1;
507     }
508     if (g_dmesgInfo->logSize < g_logBufSize) {
509         if (g_dmesgInfo->logHead <= g_dmesgInfo->logTail) {
510             OsWriteTailToEnd(buf, logLen);
511         } else {
512             OsWriteTailToHead(buf, logLen);
513         }
514     } else {
515         OsBufFullWrite(buf, logLen);
516     }
517     LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
518 
519     return LOS_OK;
520 }
521 
OsLogShow(VOID)522 VOID OsLogShow(VOID)
523 {
524     UINT32 intSave;
525     UINT32 index;
526     UINT32 i = 0;
527     CHAR *p = NULL;
528 
529     LOS_SpinLockSave(&g_dmesgSpin, &intSave);
530     index = g_dmesgInfo->logHead;
531 
532     p = (CHAR *)malloc(g_dmesgInfo->logSize + 1);
533     if (p == NULL) {
534         LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
535         return;
536     }
537     (VOID)memset_s(p, g_dmesgInfo->logSize + 1, 0, g_dmesgInfo->logSize + 1);
538 
539     while (i < g_dmesgInfo->logSize) {
540         *(p + i) = *(g_dmesgInfo->logBuf + index++);
541         if (index > BUF_MAX_INDEX) {
542             index = 0;
543         }
544         i++;
545         if (index == g_dmesgInfo->logTail) {
546             break;
547         }
548     }
549     LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
550     UartPuts(p, i, UART_WITH_LOCK);
551     free(p);
552 }
553 
OsDmesgLvSet(const CHAR * level)554 STATIC INT32 OsDmesgLvSet(const CHAR *level)
555 {
556     UINT32 levelNum, ret;
557     CHAR *p = NULL;
558 
559     levelNum = strtoul(level, &p, 0);
560     if (*p != 0) {
561         PRINTK("dmesg: invalid option or parameter.\n");
562         return -1;
563     }
564 
565     ret = LOS_DmesgLvSet(levelNum);
566     if (ret == LOS_OK) {
567         PRINTK("Set current dmesg log level %s\n", g_levelString[g_dmesgLogLevel]);
568         return LOS_OK;
569     } else {
570         PRINTK("current dmesg log level %s\n", g_levelString[g_dmesgLogLevel]);
571         PRINTK("dmesg -l [num] can access as 0:EMG 1:COMMON 2:ERROR 3:WARN 4:INFO 5:DEBUG\n");
572         return -1;
573     }
574 }
575 
OsDmesgMemSizeSet(const CHAR * size)576 STATIC INT32 OsDmesgMemSizeSet(const CHAR *size)
577 {
578     UINT32 sizeVal;
579     CHAR *p = NULL;
580 
581     sizeVal = strtoul(size, &p, 0);
582     if (sizeVal > MAX_KERNEL_LOG_BUF_SIZE) {
583         goto ERR_OUT;
584     }
585 
586     if (!(LOS_DmesgMemSet(NULL, sizeVal))) {
587         PRINTK("Set dmesg buf size %u success\n", sizeVal);
588         return LOS_OK;
589     } else {
590         goto ERR_OUT;
591     }
592 
593 ERR_OUT:
594     PRINTK("Set dmesg buf size %u fail\n", sizeVal);
595     return LOS_NOK;
596 }
OsDmesgLvGet(VOID)597 UINT32 OsDmesgLvGet(VOID)
598 {
599     return g_dmesgLogLevel;
600 }
601 
LOS_DmesgLvSet(UINT32 level)602 UINT32 LOS_DmesgLvSet(UINT32 level)
603 {
604     if (level > 5) { /* 5: count of level */
605         return LOS_NOK;
606     }
607 
608     g_dmesgLogLevel = level;
609     return LOS_OK;
610 }
611 
LOS_DmesgClear(VOID)612 VOID LOS_DmesgClear(VOID)
613 {
614     UINT32 intSave;
615 
616     LOS_SpinLockSave(&g_dmesgSpin, &intSave);
617     (VOID)memset_s(g_dmesgInfo->logBuf, g_logBufSize, 0, g_logBufSize);
618     g_dmesgInfo->logHead = 0;
619     g_dmesgInfo->logTail = 0;
620     g_dmesgInfo->logSize = 0;
621     LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
622 }
623 
LOS_DmesgMemSet(const VOID * addr,UINT32 size)624 UINT32 LOS_DmesgMemSet(const VOID *addr, UINT32 size)
625 {
626     UINT32 ret = 0;
627 
628     if (addr == NULL) {
629         ret = OsDmesgChangeSize(size);
630     } else {
631         ret = OsDmesgResetMem(addr, size);
632     }
633     return ret;
634 }
635 
LOS_DmesgRead(CHAR * buf,UINT32 len)636 INT32 LOS_DmesgRead(CHAR *buf, UINT32 len)
637 {
638     INT32 ret;
639     UINT32 intSave;
640 
641     if (buf == NULL) {
642         return -1;
643     }
644     if (len == 0) {
645         return 0;
646     }
647 
648     LOS_SpinLockSave(&g_dmesgSpin, &intSave);
649     ret = OsDmesgRead(buf, len);
650     LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
651     return ret;
652 }
653 
OsDmesgWrite2File(const CHAR * fullpath,const CHAR * buf,UINT32 logSize)654 INT32 OsDmesgWrite2File(const CHAR *fullpath, const CHAR *buf, UINT32 logSize)
655 {
656     INT32 ret;
657 
658     INT32 fd = open(fullpath, O_CREAT | O_RDWR | O_APPEND, 0644); /* 0644:file right */
659     if (fd < 0) {
660         return -1;
661     }
662     ret = write(fd, buf, logSize);
663     (VOID)close(fd);
664     return ret;
665 }
666 
667 #ifdef LOSCFG_FS_VFS
LOS_DmesgToFile(const CHAR * filename)668 INT32 LOS_DmesgToFile(const CHAR *filename)
669 {
670     CHAR *fullpath = NULL;
671     CHAR *buf = NULL;
672     INT32 ret;
673     CHAR *shellWorkingDirectory = OsShellGetWorkingDirectory();
674     UINT32 logSize, bufSize, head, tail, intSave;
675     CHAR *logBuf = NULL;
676 
677     LOS_SpinLockSave(&g_dmesgSpin, &intSave);
678     if (OsCheckError()) {
679         LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
680         return -1;
681     }
682     logSize = g_dmesgInfo->logSize;
683     bufSize = g_logBufSize;
684     head = g_dmesgInfo->logHead;
685     tail = g_dmesgInfo->logTail;
686     logBuf = g_dmesgInfo->logBuf;
687     LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
688 
689     ret = vfs_normalize_path(shellWorkingDirectory, filename, &fullpath);
690     if (ret != 0) {
691         return -1;
692     }
693 
694     buf = (CHAR *)malloc(logSize);
695     if (buf == NULL) {
696         goto ERR_OUT2;
697     }
698 
699     if (head < tail) {
700         ret = memcpy_s(buf, logSize, logBuf + head, logSize);
701         if (ret != EOK) {
702             goto ERR_OUT3;
703         }
704     } else {
705         ret = memcpy_s(buf, logSize, logBuf + head, bufSize - head);
706         if (ret != EOK) {
707             goto ERR_OUT3;
708         }
709         ret = memcpy_s(buf + bufSize - head, logSize - (bufSize - head), logBuf, tail);
710         if (ret != EOK) {
711             goto ERR_OUT3;
712         }
713     }
714 
715     ret = OsDmesgWrite2File(fullpath, buf, logSize);
716 ERR_OUT3:
717     free(buf);
718 ERR_OUT2:
719     free(fullpath);
720     return ret;
721 }
722 #else
LOS_DmesgToFile(CHAR * filename)723 INT32 LOS_DmesgToFile(CHAR *filename)
724 {
725     (VOID)filename;
726     PRINTK("File operation need VFS\n");
727     return -1;
728 }
729 #endif
730 
731 
OsShellCmdDmesg(INT32 argc,const CHAR ** argv)732 INT32 OsShellCmdDmesg(INT32 argc, const CHAR **argv)
733 {
734     if (argc == 1) {
735         PRINTK("\n");
736         OsLogShow();
737         return LOS_OK;
738     } else if (argc == 2) { /* 2: count of parameters */
739         if (argv == NULL) {
740             goto ERR_OUT;
741         }
742 
743         if (!strcmp(argv[1], "-c")) {
744             PRINTK("\n");
745             OsLogShow();
746             LOS_DmesgClear();
747             return LOS_OK;
748         } else if (!strcmp(argv[1], "-C")) {
749             LOS_DmesgClear();
750             return LOS_OK;
751         } else if (!strcmp(argv[1], "-D")) {
752             OsLockConsole();
753             return LOS_OK;
754         } else if (!strcmp(argv[1], "-E")) {
755             OsUnlockConsole();
756             return LOS_OK;
757         } else if (!strcmp(argv[1], "-L")) {
758             OsLockUart();
759             return LOS_OK;
760         } else if (!strcmp(argv[1], "-U")) {
761             OsUnlockUart();
762             return LOS_OK;
763         }
764     } else if (argc == 3) { /* 3: count of parameters */
765         if (argv == NULL) {
766             goto ERR_OUT;
767         }
768 
769         if (!strcmp(argv[1], ">")) {
770             if (LOS_DmesgToFile((CHAR *)argv[2]) < 0) { /* 2:index of parameters */
771                 PRINTK("Dmesg write log to %s fail \n", argv[2]); /* 2:index of parameters */
772                 return -1;
773             } else {
774                 PRINTK("Dmesg write log to %s success \n", argv[2]); /* 2:index of parameters */
775                 return LOS_OK;
776             }
777         } else if (!strcmp(argv[1], "-l")) {
778             return OsDmesgLvSet(argv[2]); /* 2:index of parameters */
779         } else if (!strcmp(argv[1], "-s")) {
780             return OsDmesgMemSizeSet(argv[2]); /* 2:index of parameters */
781         }
782     }
783 
784 ERR_OUT:
785     PRINTK("dmesg: invalid option or parameter.\n");
786     return -1;
787 }
788 
789 SHELLCMD_ENTRY(dmesg_shellcmd, CMD_TYPE_STD, "dmesg", XARGS, (CmdCallBackFunc)OsShellCmdDmesg);
790 LOS_MODULE_INIT(OsDmesgInit, LOS_INIT_LEVEL_EARLIEST);
791 
792 #endif
793