LCOV - code coverage report
Current view: top level - zephyr/debug - coredump.h Hit Total Coverage
Test: new.info Lines: 11 16 68.8 %
Date: 2024-12-22 00:14:23

          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 os_services
      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 1.14