1 /*
2 * Copyright (c) 2020 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <errno.h>
8 #include <zephyr/sys/util.h>
9
10 #include <zephyr/debug/coredump.h>
11 #include "coredump_internal.h"
12
13 #include <zephyr/logging/log.h>
14 #include <zephyr/logging/log_ctrl.h>
15
16 LOG_MODULE_REGISTER(coredump, CONFIG_DEBUG_COREDUMP_LOG_LEVEL);
17
18 /* Length of buffer of printable size */
19 #define LOG_BUF_SZ 64
20
21 /* Length of buffer of printable size plus null character */
22 #define LOG_BUF_SZ_RAW (LOG_BUF_SZ + 1)
23
24 /* Log Buffer */
25 static char log_buf[LOG_BUF_SZ_RAW];
26
27 static int error;
28
coredump_logging_backend_start(void)29 static void coredump_logging_backend_start(void)
30 {
31 /* Reset error */
32 error = 0;
33
34 while (LOG_PROCESS()) {
35 ;
36 }
37
38 LOG_PANIC();
39 LOG_ERR(COREDUMP_PREFIX_STR COREDUMP_BEGIN_STR);
40 }
41
coredump_logging_backend_end(void)42 static void coredump_logging_backend_end(void)
43 {
44 if (error != 0) {
45 LOG_ERR(COREDUMP_PREFIX_STR COREDUMP_ERROR_STR);
46 }
47
48 LOG_ERR(COREDUMP_PREFIX_STR COREDUMP_END_STR);
49 }
50
coredump_logging_backend_buffer_output(uint8_t * buf,size_t buflen)51 static void coredump_logging_backend_buffer_output(uint8_t *buf, size_t buflen)
52 {
53 uint8_t log_ptr = 0;
54 size_t remaining = buflen;
55 size_t i = 0;
56
57 if ((buf == NULL) || (buflen == 0)) {
58 error = -EINVAL;
59 remaining = 0;
60 }
61
62 while (remaining > 0) {
63 if (hex2char(buf[i] >> 4, &log_buf[log_ptr]) < 0) {
64 error = -EINVAL;
65 break;
66 }
67 log_ptr++;
68
69 if (hex2char(buf[i] & 0xf, &log_buf[log_ptr]) < 0) {
70 error = -EINVAL;
71 break;
72 }
73 log_ptr++;
74
75 i++;
76 remaining--;
77
78 if ((log_ptr >= LOG_BUF_SZ) || (remaining == 0)) {
79 log_buf[log_ptr] = '\0';
80 LOG_ERR(COREDUMP_PREFIX_STR "%s", log_buf);
81 log_ptr = 0;
82 }
83 }
84 }
85
coredump_logging_backend_query(enum coredump_query_id query_id,void * arg)86 static int coredump_logging_backend_query(enum coredump_query_id query_id,
87 void *arg)
88 {
89 int ret;
90
91 switch (query_id) {
92 case COREDUMP_QUERY_GET_ERROR:
93 ret = error;
94 break;
95 default:
96 ret = -ENOTSUP;
97 break;
98 }
99
100 return ret;
101 }
102
coredump_logging_backend_cmd(enum coredump_cmd_id cmd_id,void * arg)103 static int coredump_logging_backend_cmd(enum coredump_cmd_id cmd_id,
104 void *arg)
105 {
106 int ret;
107
108 switch (cmd_id) {
109 case COREDUMP_CMD_CLEAR_ERROR:
110 ret = 0;
111 error = 0;
112 break;
113 default:
114 ret = -ENOTSUP;
115 break;
116 }
117
118 return ret;
119 }
120
121
122 struct coredump_backend_api coredump_backend_logging = {
123 .start = coredump_logging_backend_start,
124 .end = coredump_logging_backend_end,
125 .buffer_output = coredump_logging_backend_buffer_output,
126 .query = coredump_logging_backend_query,
127 .cmd = coredump_logging_backend_cmd,
128 };
129