1 // Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #ifndef ESP_CORE_DUMP_PRIV_H_
15 #define ESP_CORE_DUMP_PRIV_H_
16 
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20 
21 #include "esp_err.h"
22 #include "esp_attr.h"
23 #include "esp_log.h"
24 #include "esp_rom_sys.h"
25 #include "sdkconfig.h"
26 #include "esp_private/panic_internal.h"
27 #include "core_dump_checksum.h"
28 
29 #define ESP_COREDUMP_LOG( level, format, ... )  if (LOG_LOCAL_LEVEL >= level)   { esp_rom_printf(DRAM_STR(format), esp_log_early_timestamp(), (const char *)TAG, ##__VA_ARGS__); }
30 #define ESP_COREDUMP_LOGE( format, ... )  ESP_COREDUMP_LOG(ESP_LOG_ERROR, LOG_FORMAT(E, format), ##__VA_ARGS__)
31 #define ESP_COREDUMP_LOGW( format, ... )  ESP_COREDUMP_LOG(ESP_LOG_WARN, LOG_FORMAT(W, format), ##__VA_ARGS__)
32 #define ESP_COREDUMP_LOGI( format, ... )  ESP_COREDUMP_LOG(ESP_LOG_INFO, LOG_FORMAT(I, format), ##__VA_ARGS__)
33 #define ESP_COREDUMP_LOGD( format, ... )  ESP_COREDUMP_LOG(ESP_LOG_DEBUG, LOG_FORMAT(D, format), ##__VA_ARGS__)
34 #define ESP_COREDUMP_LOGV( format, ... )  ESP_COREDUMP_LOG(ESP_LOG_VERBOSE, LOG_FORMAT(V, format), ##__VA_ARGS__)
35 
36 /**
37  * @brief Assertion to be verified in a release context. Cannot be muted.
38  */
39 #define ESP_COREDUMP_ASSERT( condition ) if(!(condition)){ abort(); } else { }
40 
41 /**
42  * @brief Assertion to be verified in a debug context. Can be muted.
43  */
44 #define ESP_COREDUMP_DEBUG_ASSERT( condition ) assert(condition)
45 
46 /**
47  * @brief Logging should only be enabled if the core dump is not written to
48  * the UART.
49  */
50 #if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH
51 #define ESP_COREDUMP_LOG_PROCESS( format, ... )  ESP_COREDUMP_LOGD(format, ##__VA_ARGS__)
52 #else
53 #define ESP_COREDUMP_LOG_PROCESS( format, ... )  do{/*(__VA_ARGS__);*/}while(0)
54 #endif
55 
56 #define COREDUMP_MAX_TASK_STACK_SIZE        (64*1024)
57 
58 /**
59  * @brief The following macros defined below are used to create a version
60  * numbering. This number is then used in the core dump header.
61  *
62  * @note COREDUMP_VERSION_CHIP is defined in ports header.
63  */
64 #define COREDUMP_VERSION_MAKE(_maj_, _min_) ( \
65                                                 (((COREDUMP_VERSION_CHIP)&0xFFFF) << 16) | \
66                                                 (((_maj_)&0xFF) << 8) | \
67                                                 (((_min_)&0xFF) << 0) \
68                                             )
69 #define COREDUMP_VERSION_BIN                0
70 #define COREDUMP_VERSION_ELF                1
71 
72 /* legacy bin coredumps (before IDF v4.1) has version set to 1 */
73 #define COREDUMP_VERSION_BIN_LEGACY         COREDUMP_VERSION_MAKE(COREDUMP_VERSION_BIN, 1) // -> 0x0001
74 #define COREDUMP_VERSION_BIN_CURRENT        COREDUMP_VERSION_MAKE(COREDUMP_VERSION_BIN, 2) // -> 0x0002
75 #define COREDUMP_VERSION_ELF_CRC32          COREDUMP_VERSION_MAKE(COREDUMP_VERSION_ELF, 0) // -> 0x0100
76 #define COREDUMP_VERSION_ELF_SHA256         COREDUMP_VERSION_MAKE(COREDUMP_VERSION_ELF, 1) // -> 0x0101
77 #define COREDUMP_CURR_TASK_MARKER           0xDEADBEEF
78 #define COREDUMP_CURR_TASK_NOT_FOUND        -1
79 
80 /**
81  * @brief Macro defining the size of the cache used to write the core dump.
82  */
83 #define COREDUMP_CACHE_SIZE 32
84 
85 /**
86  * @brief If the core dump has to be written to an encrypted flash, the
87  * smallest data block we can write to it is 16 bytes long. Thus, this macro
88  * MUST be a multiple of 16.
89  */
90 #if (COREDUMP_CACHE_SIZE % 16) != 0
91     #error "Coredump cache size must be a multiple of 16"
92 #endif
93 
94 
95 typedef struct _core_dump_write_data_t
96 {
97     uint32_t off; /*!< Current offset of data being written */
98     uint8_t  cached_data[COREDUMP_CACHE_SIZE]; /*!< Cache used to write to flash */
99     uint8_t  cached_bytes; /*!< Number of bytes filled in the cached */
100     core_dump_checksum_ctx* checksum_ctx; /*!< Checksum context */
101 } core_dump_write_data_t;
102 
103 
104 /**
105  * @brief Types below define the signatures of the callbacks that are used
106  * to output a core dump. The destination of the dump is implementation
107  * dependant.
108  */
109 typedef esp_err_t (*esp_core_dump_write_prepare_t)(core_dump_write_data_t* priv, uint32_t *data_len);
110 typedef esp_err_t (*esp_core_dump_write_start_t)(core_dump_write_data_t* priv);
111 typedef esp_err_t (*esp_core_dump_write_end_t)(core_dump_write_data_t* priv);
112 typedef esp_err_t (*esp_core_dump_flash_write_data_t)(core_dump_write_data_t* priv,
113                                                       void * data,
114                                                       uint32_t data_len);
115 
116 
117 /**
118  * @brief Core dump emitter control structure.
119  * This structure contains the functions that are called in order to write
120  * the core dump to the destination (UART or flash).
121  * The function are called in this order:
122  * - prepare
123  * - start
124  * - write (called once or more)
125  * - end
126  */
127 typedef struct _core_dump_write_config_t
128 {
129     esp_core_dump_write_prepare_t    prepare;  /*!< Function called for sanity checks */
130     esp_core_dump_write_start_t      start; /*!< Function called at the beginning of data writing */
131     esp_core_dump_flash_write_data_t write; /*!< Function called to write data chunk */
132     esp_core_dump_write_end_t        end; /*!< Function called once all data have been written */
133     core_dump_write_data_t*          priv; /*!< Private context to pass to every function of this structure */
134 } core_dump_write_config_t;
135 
136 /**
137  * @brief Core dump data header
138  * This header predecesses the actual core dump data (ELF or binary). */
139 typedef struct _core_dump_header_t
140 {
141     uint32_t data_len;  /*!< Data length */
142     uint32_t version;   /*!< Core dump version */
143     uint32_t tasks_num; /*!< Number of tasks */
144     uint32_t tcb_sz;    /*!< Size of a TCB, in bytes */
145     uint32_t mem_segs_num; /*!< Number of memory segments */
146 } core_dump_header_t;
147 
148 /**
149  * @brief Core dump task data header
150  * The main goal of this definition is to add typing to the code.
151  */
152 typedef void* core_dump_task_handle_t;
153 
154 /**
155  * @brief Header for the tasks
156  */
157 typedef struct _core_dump_task_header_t
158 {
159     core_dump_task_handle_t tcb_addr;    /*!< TCB address */
160     uint32_t                stack_start; /*!< Start of the stack address */
161     uint32_t                stack_end;   /*!< End of the stack address */
162 } core_dump_task_header_t;
163 
164 /**
165  * @brief Core dump memory segment header
166  */
167 typedef struct _core_dump_mem_seg_header_t
168 {
169     uint32_t start; /*!< Memory region start address */
170     uint32_t size;  /*!< Memory region size */
171 } core_dump_mem_seg_header_t;
172 
173 /**
174  * @brief Core dump flash init function
175  */
176 void esp_core_dump_flash_init(void);
177 
178 
179 /**
180  * @brief Common core dump write function
181  */
182 void esp_core_dump_write(panic_info_t *info, core_dump_write_config_t *write_cfg);
183 
184 #ifdef __cplusplus
185 }
186 #endif
187 
188 #endif
189