Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2020 Intel Corporation.
3 : : *
4 : : * SPDX-License-Identifier: Apache-2.0
5 : : */
6 : :
7 : : #ifndef ZEPHYR_INCLUDE_DEBUG_COREDUMP_H_
8 : : #define ZEPHYR_INCLUDE_DEBUG_COREDUMP_H_
9 : :
10 : : /* Query ID */
11 : : enum coredump_query_id {
12 : : /*
13 : : * Returns error code from backend.
14 : : */
15 : : COREDUMP_QUERY_GET_ERROR,
16 : :
17 : : /*
18 : : * Check if there is a stored coredump from backend.
19 : : *
20 : : * Returns 1 if there is a stored coredump.
21 : : * 0 if none.
22 : : * -ENOTSUP if this query is not supported.
23 : : * Otherwise, error code from backend.
24 : : */
25 : : COREDUMP_QUERY_HAS_STORED_DUMP,
26 : :
27 : : COREDUMP_QUERY_MAX
28 : : };
29 : :
30 : : /* Command ID */
31 : : enum coredump_cmd_id {
32 : : /*
33 : : * Clear error code from backend.
34 : : *
35 : : * Returns 0 if successful, failed otherwise.
36 : : */
37 : : COREDUMP_CMD_CLEAR_ERROR,
38 : :
39 : : /*
40 : : * Verify that the stored coredump is valid.
41 : : *
42 : : * Returns 1 if valid.
43 : : * 0 if not valid or no stored coredump.
44 : : * -ENOTSUP if this command is not supported.
45 : : * Otherwise, error code from backend.
46 : : */
47 : : COREDUMP_CMD_VERIFY_STORED_DUMP,
48 : :
49 : : /*
50 : : * Erase the stored coredump.
51 : : *
52 : : * Returns 0 if successful.
53 : : * -ENOTSUP if this command is not supported.
54 : : * Otherwise, error code from backend.
55 : : */
56 : : COREDUMP_CMD_ERASE_STORED_DUMP,
57 : :
58 : : COREDUMP_CMD_MAX
59 : : };
60 : :
61 : : #ifdef CONFIG_DEBUG_COREDUMP
62 : :
63 : : #include <toolchain.h>
64 : : #include <arch/cpu.h>
65 : : #include <sys/byteorder.h>
66 : :
67 : : #define COREDUMP_HDR_VER 1
68 : :
69 : : #define COREDUMP_ARCH_HDR_ID 'A'
70 : :
71 : : #define COREDUMP_MEM_HDR_ID 'M'
72 : : #define COREDUMP_MEM_HDR_VER 1
73 : :
74 : : /* Target code */
75 : : enum coredump_tgt_code {
76 : : COREDUMP_TGT_UNKNOWN = 0,
77 : : COREDUMP_TGT_X86,
78 : : COREDUMP_TGT_X86_64,
79 : : COREDUMP_TGT_ARM_CORTEX_M,
80 : : COREDUMP_TGT_RISC_V,
81 : : COREDUMP_TGT_XTENSA,
82 : : };
83 : :
84 : : /* Coredump header */
85 : : struct coredump_hdr_t {
86 : : /* 'Z', 'E' */
87 : : char id[2];
88 : :
89 : : /* Header version */
90 : : uint16_t hdr_version;
91 : :
92 : : /* Target code */
93 : : uint16_t tgt_code;
94 : :
95 : : /* Pointer size in Log2 */
96 : : uint8_t ptr_size_bits;
97 : :
98 : : uint8_t flag;
99 : :
100 : : /* Coredump Reason given */
101 : : unsigned int reason;
102 : : } __packed;
103 : :
104 : : /* Architecture-specific block header */
105 : : struct coredump_arch_hdr_t {
106 : : /* COREDUMP_ARCH_HDR_ID */
107 : : char id;
108 : :
109 : : /* Header version */
110 : : uint16_t hdr_version;
111 : :
112 : : /* Number of bytes in this block (excluding header) */
113 : : uint16_t num_bytes;
114 : : } __packed;
115 : :
116 : : /* Memory block header */
117 : : struct coredump_mem_hdr_t {
118 : : /* COREDUMP_MEM_HDR_ID */
119 : : char id;
120 : :
121 : : /* Header version */
122 : : uint16_t hdr_version;
123 : :
124 : : /* Address of start of memory region */
125 : : uintptr_t start;
126 : :
127 : : /* Address of end of memory region */
128 : : uintptr_t end;
129 : : } __packed;
130 : :
131 : : typedef void (*coredump_backend_start_t)(void);
132 : : typedef void (*coredump_backend_end_t)(void);
133 : : typedef void (*coredump_backend_buffer_output_t)(uint8_t *buf, size_t buflen);
134 : : typedef int (*coredump_backend_query_t)(enum coredump_query_id query_id,
135 : : void *arg);
136 : : typedef int (*coredump_backend_cmd_t)(enum coredump_cmd_id cmd_id,
137 : : void *arg);
138 : :
139 : : struct coredump_backend_api {
140 : : /* Signal to backend of the start of coredump. */
141 : : coredump_backend_start_t start;
142 : :
143 : : /* Signal to backend of the end of coredump. */
144 : : coredump_backend_end_t end;
145 : :
146 : : /* Raw buffer output */
147 : : coredump_backend_buffer_output_t buffer_output;
148 : :
149 : : /* Perform query on backend */
150 : : coredump_backend_query_t query;
151 : :
152 : : /* Perform command on backend */
153 : : coredump_backend_cmd_t cmd;
154 : : };
155 : :
156 : : void coredump(unsigned int reason, const z_arch_esf_t *esf,
157 : : struct k_thread *thread);
158 : : void coredump_memory_dump(uintptr_t start_addr, uintptr_t end_addr);
159 : : void coredump_buffer_output(uint8_t *buf, size_t buflen);
160 : :
161 : : int coredump_query(enum coredump_query_id query_id, void *arg);
162 : : int coredump_cmd(enum coredump_cmd_id cmd_id, void *arg);
163 : :
164 : : #else
165 : :
166 : 0 : void coredump(unsigned int reason, const z_arch_esf_t *esf,
167 : : struct k_thread *thread)
168 : : {
169 : 0 : }
170 : :
171 : 0 : void coredump_memory_dump(uintptr_t start_addr, uintptr_t end_addr)
172 : : {
173 : 0 : }
174 : :
175 : 0 : void coredump_buffer_output(uint8_t *buf, size_t buflen)
176 : : {
177 : 0 : }
178 : :
179 : 0 : int coredump_query(enum coredump_query_id query_id, void *arg)
180 : : {
181 : 0 : return -ENOTSUP;
182 : : }
183 : :
184 : 0 : int coredump_cmd(enum coredump_cmd_id query_id, void *arg)
185 : : {
186 : 0 : return -ENOTSUP;
187 : : }
188 : :
189 : : #endif /* CONFIG_DEBUG_COREDUMP */
190 : :
191 : : /**
192 : : * @defgroup coredump_apis Coredump APIs
193 : : * @brief Coredump APIs
194 : : * @{
195 : : */
196 : :
197 : : /**
198 : : * @fn void coredump(unsigned int reason, const z_arch_esf_t *esf, struct k_thread *thread);
199 : : * @brief Perform coredump.
200 : : *
201 : : * Normally, this is called inside z_fatal_error() to generate coredump
202 : : * when a fatal error is encountered. This can also be called on demand
203 : : * whenever a coredump is desired.
204 : : *
205 : : * @param reason Reason for the fatal error
206 : : * @param esf Exception context
207 : : * @param thread Thread information to dump
208 : : */
209 : :
210 : : /**
211 : : * @fn void coredump_memory_dump(uintptr_t start_addr, uintptr_t end_addr);
212 : : * @brief Dump memory region
213 : : *
214 : : * @param start_addr Start address of memory region to be dumped
215 : : * @param end_addr End address of memory region to be dumped
216 : : */
217 : :
218 : : /**
219 : : * @fn int coredump_buffer_output(uint8_t *buf, size_t buflen);
220 : : * @brief Output the buffer via coredump
221 : : *
222 : : * This outputs the buffer of byte array to the coredump backend.
223 : : * For example, this can be called to output the coredump section
224 : : * containing registers, or a section for memory dump.
225 : : *
226 : : * @param buf Buffer to be send to coredump output
227 : : * @param buflen Buffer length
228 : : */
229 : :
230 : : /**
231 : : * @fn int coredump_query(enum coredump_query_id query_id, void *arg);
232 : : * @brief Perform query on coredump subsystem.
233 : : *
234 : : * Query the coredump subsystem for information, for example, if there is
235 : : * an error.
236 : : *
237 : : * @param[in] query_id Query ID
238 : : * @param[in,out] arg Pointer to argument for exchanging information
239 : : * @return Depends on the query
240 : : */
241 : :
242 : : /**
243 : : * @fn int coredump_cmd(enum coredump_cmd_id cmd_id, void *arg);
244 : : * @brief Perform command on coredump subsystem.
245 : : *
246 : : * Perform certain on coredump subsystem, for example, output the stored
247 : : * coredump via logging.
248 : : *
249 : : * @param[in] cmd_id Command ID
250 : : * @param[in,out] arg Pointer to argument for exchanging information
251 : : * @return Depends on the command
252 : : */
253 : :
254 : : /**
255 : : * @}
256 : : */
257 : :
258 : : #endif /* ZEPHYR_INCLUDE_DEBUG_COREDUMP_H_ */
|