LCOV - code coverage report
Current view: top level - zephyr/debug - coredump.h Coverage Total Hit
Test: new.info Lines: 68.8 % 16 11
Test Date: 2025-09-05 16:43:28

            Line data    Source code
       1            0 : /*
       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              : #include <stddef.h>
      11              : #include <stdint.h>
      12              : #include <sys/types.h>
      13              : 
      14              : /*
      15              :  * Define COREDUMP_*_STR as public to allow coredump_backend_other to re-use
      16              :  * these strings if necessary
      17              :  */
      18            0 : #define COREDUMP_BEGIN_STR      "BEGIN#"
      19            0 : #define COREDUMP_END_STR        "END#"
      20            0 : #define COREDUMP_ERROR_STR      "ERROR CANNOT DUMP#"
      21              : 
      22              : /*
      23              :  * Need to prefix coredump strings to make it easier to parse
      24              :  * as log module adds its own prefixes.
      25              :  */
      26            0 : #define COREDUMP_PREFIX_STR     "#CD:"
      27              : 
      28              : /**
      29              :  * @file
      30              :  *
      31              :  * @defgroup coredump_apis Coredump APIs
      32              :  * @ingroup debug
      33              :  * @brief Coredump APIs
      34              :  * @{
      35              :  */
      36              : 
      37              : 
      38              : /** Query ID */
      39            1 : enum coredump_query_id {
      40              :         /**
      41              :          * Returns error code from backend.
      42              :          */
      43              :         COREDUMP_QUERY_GET_ERROR,
      44              : 
      45              :         /**
      46              :          * Check if there is a stored coredump from backend.
      47              :          *
      48              :          * Returns:
      49              :          * - 1 if there is a stored coredump, 0 if none.
      50              :          * - -ENOTSUP if this query is not supported.
      51              :          * - Otherwise, error code from backend.
      52              :          */
      53              :         COREDUMP_QUERY_HAS_STORED_DUMP,
      54              : 
      55              :         /**
      56              :          * Returns:
      57              :          * - coredump raw size from backend, 0 if none.
      58              :          * - -ENOTSUP if this query is not supported.
      59              :          * - Otherwise, error code from backend.
      60              :          */
      61              :         COREDUMP_QUERY_GET_STORED_DUMP_SIZE,
      62              : 
      63              :         /**
      64              :          * Max value for query ID.
      65              :          */
      66              :         COREDUMP_QUERY_MAX
      67              : };
      68              : 
      69              : /** Command ID */
      70            1 : enum coredump_cmd_id {
      71              :         /**
      72              :          * Clear error code from backend.
      73              :          *
      74              :          * Returns 0 if successful, failed otherwise.
      75              :          */
      76              :         COREDUMP_CMD_CLEAR_ERROR,
      77              : 
      78              :         /**
      79              :          * Verify that the stored coredump is valid.
      80              :          *
      81              :          * Returns:
      82              :          * - 1 if valid.
      83              :          * - 0 if not valid or no stored coredump.
      84              :          * - -ENOTSUP if this command is not supported.
      85              :          * - Otherwise, error code from backend.
      86              :          */
      87              :         COREDUMP_CMD_VERIFY_STORED_DUMP,
      88              : 
      89              :         /**
      90              :          * Erase the stored coredump.
      91              :          *
      92              :          * Returns:
      93              :          * - 0 if successful.
      94              :          * - -ENOTSUP if this command is not supported.
      95              :          * - Otherwise, error code from backend.
      96              :          */
      97              :         COREDUMP_CMD_ERASE_STORED_DUMP,
      98              : 
      99              :         /**
     100              :          * Copy the raw stored coredump.
     101              :          *
     102              :          * Returns:
     103              :          * - copied size if successful
     104              :          * - 0 if stored coredump is not found
     105              :          * - -ENOTSUP if this command is not supported.
     106              :          * - Otherwise, error code from backend.
     107              :          */
     108              :         COREDUMP_CMD_COPY_STORED_DUMP,
     109              : 
     110              :         /**
     111              :          * Invalidate the stored coredump. This is faster than
     112              :          * erasing the whole partition.
     113              :          *
     114              :          * Returns:
     115              :          * - 0 if successful.
     116              :          * - -ENOTSUP if this command is not supported.
     117              :          * - Otherwise, error code from backend.
     118              :          */
     119              :         COREDUMP_CMD_INVALIDATE_STORED_DUMP,
     120              : 
     121              :         /**
     122              :          * Max value for command ID.
     123              :          */
     124              :         COREDUMP_CMD_MAX
     125              : };
     126              : 
     127              : /** Coredump copy command (@ref COREDUMP_CMD_COPY_STORED_DUMP) argument definition */
     128            1 : struct coredump_cmd_copy_arg {
     129              :         /** Copy offset */
     130            1 :         off_t offset;
     131              : 
     132              :         /** Copy destination buffer */
     133            1 :         uint8_t *buffer;
     134              : 
     135              :         /** Copy length */
     136            1 :         size_t length;
     137              : };
     138              : 
     139              : #ifdef CONFIG_DEBUG_COREDUMP
     140              : 
     141              : #include <zephyr/toolchain.h>
     142              : #include <zephyr/arch/cpu.h>
     143              : #include <zephyr/sys/byteorder.h>
     144              : 
     145              : #define COREDUMP_HDR_VER                2
     146              : 
     147              : #define COREDUMP_ARCH_HDR_ID            'A'
     148              : 
     149              : #define THREADS_META_HDR_ID             'T'
     150              : #define THREADS_META_HDR_VER            1
     151              : 
     152              : #define COREDUMP_MEM_HDR_ID             'M'
     153              : #define COREDUMP_MEM_HDR_VER            1
     154              : 
     155              : /* Target code */
     156              : enum coredump_tgt_code {
     157              :         COREDUMP_TGT_UNKNOWN = 0,
     158              :         COREDUMP_TGT_X86,
     159              :         COREDUMP_TGT_X86_64,
     160              :         COREDUMP_TGT_ARM_CORTEX_M,
     161              :         COREDUMP_TGT_RISC_V,
     162              :         COREDUMP_TGT_XTENSA,
     163              :         COREDUMP_TGT_ARM64,
     164              : };
     165              : 
     166              : /* Coredump header */
     167              : struct coredump_hdr_t {
     168              :         /* 'Z', 'E' */
     169              :         char            id[2];
     170              : 
     171              :         /* Header version */
     172              :         uint16_t        hdr_version;
     173              : 
     174              :         /* Target code */
     175              :         uint16_t        tgt_code;
     176              : 
     177              :         /* Pointer size in Log2 */
     178              :         uint8_t         ptr_size_bits;
     179              : 
     180              :         uint8_t         flag;
     181              : 
     182              :         /* Coredump Reason given */
     183              :         unsigned int    reason;
     184              : } __packed;
     185              : 
     186              : /* Architecture-specific block header */
     187              : struct coredump_arch_hdr_t {
     188              :         /* COREDUMP_ARCH_HDR_ID */
     189              :         char            id;
     190              : 
     191              :         /* Header version */
     192              :         uint16_t        hdr_version;
     193              : 
     194              :         /* Number of bytes in this block (excluding header) */
     195              :         uint16_t        num_bytes;
     196              : } __packed;
     197              : 
     198              : /* Threads metadata header */
     199              : struct coredump_threads_meta_hdr_t {
     200              :         /* THREADS_META_HDR_ID */
     201              :         char            id;
     202              : 
     203              :         /* Header version */
     204              :         uint16_t        hdr_version;
     205              : 
     206              :         /* Number of bytes in this block (excluding header) */
     207              :         uint16_t        num_bytes;
     208              : } __packed;
     209              : 
     210              : /* Memory block header */
     211              : struct coredump_mem_hdr_t {
     212              :         /* COREDUMP_MEM_HDR_ID */
     213              :         char            id;
     214              : 
     215              :         /* Header version */
     216              :         uint16_t        hdr_version;
     217              : 
     218              :         /* Address of start of memory region */
     219              :         uintptr_t       start;
     220              : 
     221              :         /* Address of end of memory region */
     222              :         uintptr_t       end;
     223              : } __packed;
     224              : 
     225              : typedef void (*coredump_backend_start_t)(void);
     226              : typedef void (*coredump_backend_end_t)(void);
     227              : typedef void (*coredump_backend_buffer_output_t)(uint8_t *buf, size_t buflen);
     228              : typedef int (*coredump_backend_query_t)(enum coredump_query_id query_id,
     229              :                                         void *arg);
     230              : typedef int (*coredump_backend_cmd_t)(enum coredump_cmd_id cmd_id,
     231              :                                       void *arg);
     232              : 
     233              : struct coredump_backend_api {
     234              :         /* Signal to backend of the start of coredump. */
     235              :         coredump_backend_start_t                start;
     236              : 
     237              :         /* Signal to backend of the end of coredump. */
     238              :         coredump_backend_end_t                  end;
     239              : 
     240              :         /* Raw buffer output */
     241              :         coredump_backend_buffer_output_t        buffer_output;
     242              : 
     243              :         /* Perform query on backend */
     244              :         coredump_backend_query_t                query;
     245              : 
     246              :         /* Perform command on backend */
     247              :         coredump_backend_cmd_t                  cmd;
     248              : };
     249              : 
     250              : void coredump(unsigned int reason, const struct arch_esf *esf,
     251              :               struct k_thread *thread);
     252              : void coredump_memory_dump(uintptr_t start_addr, uintptr_t end_addr);
     253              : void coredump_buffer_output(uint8_t *buf, size_t buflen);
     254              : 
     255              : int coredump_query(enum coredump_query_id query_id, void *arg);
     256              : int coredump_cmd(enum coredump_cmd_id cmd_id, void *arg);
     257              : 
     258              : #else
     259              : 
     260            1 : static inline void coredump(unsigned int reason, const struct arch_esf *esf,
     261              :                             struct k_thread *thread)
     262              : {
     263              :         ARG_UNUSED(reason);
     264              :         ARG_UNUSED(esf);
     265              :         ARG_UNUSED(thread);
     266              : }
     267              : 
     268            1 : static inline void coredump_memory_dump(uintptr_t start_addr, uintptr_t end_addr)
     269              : {
     270              :         ARG_UNUSED(start_addr);
     271              :         ARG_UNUSED(end_addr);
     272              : }
     273              : 
     274            1 : static inline void coredump_buffer_output(uint8_t *buf, size_t buflen)
     275              : {
     276              :         ARG_UNUSED(buf);
     277              :         ARG_UNUSED(buflen);
     278              : }
     279              : 
     280            1 : static inline int coredump_query(enum coredump_query_id query_id, void *arg)
     281              : {
     282              :         ARG_UNUSED(query_id);
     283              :         ARG_UNUSED(arg);
     284              :         return -ENOTSUP;
     285              : }
     286              : 
     287            1 : static inline int coredump_cmd(enum coredump_cmd_id query_id, void *arg)
     288              : {
     289              :         ARG_UNUSED(query_id);
     290              :         ARG_UNUSED(arg);
     291              :         return -ENOTSUP;
     292              : }
     293              : 
     294              : #endif /* CONFIG_DEBUG_COREDUMP */
     295              : 
     296              : /**
     297              :  * @fn void coredump(unsigned int reason, const struct arch_esf *esf, struct k_thread *thread);
     298              :  * @brief Perform coredump.
     299              :  *
     300              :  * Normally, this is called inside z_fatal_error() to generate coredump
     301              :  * when a fatal error is encountered. This can also be called on demand
     302              :  * whenever a coredump is desired.
     303              :  *
     304              :  * @param reason Reason for the fatal error
     305              :  * @param esf Exception context
     306              :  * @param thread Thread information to dump
     307              :  */
     308              : 
     309              : /**
     310              :  * @fn void coredump_memory_dump(uintptr_t start_addr, uintptr_t end_addr);
     311              :  * @brief Dump memory region
     312              :  *
     313              :  * @param start_addr Start address of memory region to be dumped
     314              :  * @param end_addr End address of memory region to be dumped
     315              :  */
     316              : 
     317              : /**
     318              :  * @fn int coredump_buffer_output(uint8_t *buf, size_t buflen);
     319              :  * @brief Output the buffer via coredump
     320              :  *
     321              :  * This outputs the buffer of byte array to the coredump backend.
     322              :  * For example, this can be called to output the coredump section
     323              :  * containing registers, or a section for memory dump.
     324              :  *
     325              :  * @param buf Buffer to be send to coredump output
     326              :  * @param buflen Buffer length
     327              :  */
     328              : 
     329              : /**
     330              :  * @fn int coredump_query(enum coredump_query_id query_id, void *arg);
     331              :  * @brief Perform query on coredump subsystem.
     332              :  *
     333              :  * Query the coredump subsystem for information, for example, if there is
     334              :  * an error.
     335              :  *
     336              :  * @param[in] query_id Query ID
     337              :  * @param[in,out] arg Pointer to argument for exchanging information
     338              :  * @return Depends on the query
     339              :  */
     340              : 
     341              : /**
     342              :  * @fn int coredump_cmd(enum coredump_cmd_id cmd_id, void *arg);
     343              :  * @brief Perform command on coredump subsystem.
     344              :  *
     345              :  * Perform command on coredump subsystem, for example, output the stored
     346              :  * coredump via logging.
     347              :  *
     348              :  * @param[in] cmd_id Command ID
     349              :  * @param[in,out] arg Pointer to argument for exchanging information
     350              :  * @return Depends on the command
     351              :  */
     352              : 
     353              : /**
     354              :  * @}
     355              :  */
     356              : 
     357              : #endif /* ZEPHYR_INCLUDE_DEBUG_COREDUMP_H_ */
        

Generated by: LCOV version 2.0-1