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