259 lines
5.8 KiB
C
259 lines
5.8 KiB
C
/*
|
|
* Copyright (c) 2020 Intel Corporation.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#ifndef ZEPHYR_INCLUDE_DEBUG_COREDUMP_H_
|
|
#define ZEPHYR_INCLUDE_DEBUG_COREDUMP_H_
|
|
|
|
/* Query ID */
|
|
enum coredump_query_id {
|
|
/*
|
|
* Returns error code from backend.
|
|
*/
|
|
COREDUMP_QUERY_GET_ERROR,
|
|
|
|
/*
|
|
* Check if there is a stored coredump from backend.
|
|
*
|
|
* Returns 1 if there is a stored coredump.
|
|
* 0 if none.
|
|
* -ENOTSUP if this query is not supported.
|
|
* Otherwise, error code from backend.
|
|
*/
|
|
COREDUMP_QUERY_HAS_STORED_DUMP,
|
|
|
|
COREDUMP_QUERY_MAX
|
|
};
|
|
|
|
/* Command ID */
|
|
enum coredump_cmd_id {
|
|
/*
|
|
* Clear error code from backend.
|
|
*
|
|
* Returns 0 if successful, failed otherwise.
|
|
*/
|
|
COREDUMP_CMD_CLEAR_ERROR,
|
|
|
|
/*
|
|
* Verify that the stored coredump is valid.
|
|
*
|
|
* Returns 1 if valid.
|
|
* 0 if not valid or no stored coredump.
|
|
* -ENOTSUP if this command is not supported.
|
|
* Otherwise, error code from backend.
|
|
*/
|
|
COREDUMP_CMD_VERIFY_STORED_DUMP,
|
|
|
|
/*
|
|
* Erase the stored coredump.
|
|
*
|
|
* Returns 0 if successful.
|
|
* -ENOTSUP if this command is not supported.
|
|
* Otherwise, error code from backend.
|
|
*/
|
|
COREDUMP_CMD_ERASE_STORED_DUMP,
|
|
|
|
COREDUMP_CMD_MAX
|
|
};
|
|
|
|
#ifdef CONFIG_DEBUG_COREDUMP
|
|
|
|
#include <toolchain.h>
|
|
#include <arch/cpu.h>
|
|
#include <sys/byteorder.h>
|
|
|
|
#define COREDUMP_HDR_VER 1
|
|
|
|
#define COREDUMP_ARCH_HDR_ID 'A'
|
|
|
|
#define COREDUMP_MEM_HDR_ID 'M'
|
|
#define COREDUMP_MEM_HDR_VER 1
|
|
|
|
/* Target code */
|
|
enum coredump_tgt_code {
|
|
COREDUMP_TGT_UNKNOWN = 0,
|
|
COREDUMP_TGT_X86,
|
|
COREDUMP_TGT_X86_64,
|
|
COREDUMP_TGT_ARM_CORTEX_M,
|
|
COREDUMP_TGT_RISC_V,
|
|
COREDUMP_TGT_XTENSA,
|
|
};
|
|
|
|
/* Coredump header */
|
|
struct coredump_hdr_t {
|
|
/* 'Z', 'E' */
|
|
char id[2];
|
|
|
|
/* Header version */
|
|
uint16_t hdr_version;
|
|
|
|
/* Target code */
|
|
uint16_t tgt_code;
|
|
|
|
/* Pointer size in Log2 */
|
|
uint8_t ptr_size_bits;
|
|
|
|
uint8_t flag;
|
|
|
|
/* Coredump Reason given */
|
|
unsigned int reason;
|
|
} __packed;
|
|
|
|
/* Architecture-specific block header */
|
|
struct coredump_arch_hdr_t {
|
|
/* COREDUMP_ARCH_HDR_ID */
|
|
char id;
|
|
|
|
/* Header version */
|
|
uint16_t hdr_version;
|
|
|
|
/* Number of bytes in this block (excluding header) */
|
|
uint16_t num_bytes;
|
|
} __packed;
|
|
|
|
/* Memory block header */
|
|
struct coredump_mem_hdr_t {
|
|
/* COREDUMP_MEM_HDR_ID */
|
|
char id;
|
|
|
|
/* Header version */
|
|
uint16_t hdr_version;
|
|
|
|
/* Address of start of memory region */
|
|
uintptr_t start;
|
|
|
|
/* Address of end of memory region */
|
|
uintptr_t end;
|
|
} __packed;
|
|
|
|
typedef void (*coredump_backend_start_t)(void);
|
|
typedef void (*coredump_backend_end_t)(void);
|
|
typedef void (*coredump_backend_buffer_output_t)(uint8_t *buf, size_t buflen);
|
|
typedef int (*coredump_backend_query_t)(enum coredump_query_id query_id,
|
|
void *arg);
|
|
typedef int (*coredump_backend_cmd_t)(enum coredump_cmd_id cmd_id,
|
|
void *arg);
|
|
|
|
struct coredump_backend_api {
|
|
/* Signal to backend of the start of coredump. */
|
|
coredump_backend_start_t start;
|
|
|
|
/* Signal to backend of the end of coredump. */
|
|
coredump_backend_end_t end;
|
|
|
|
/* Raw buffer output */
|
|
coredump_backend_buffer_output_t buffer_output;
|
|
|
|
/* Perform query on backend */
|
|
coredump_backend_query_t query;
|
|
|
|
/* Perform command on backend */
|
|
coredump_backend_cmd_t cmd;
|
|
};
|
|
|
|
void coredump(unsigned int reason, const z_arch_esf_t *esf,
|
|
struct k_thread *thread);
|
|
void coredump_memory_dump(uintptr_t start_addr, uintptr_t end_addr);
|
|
void coredump_buffer_output(uint8_t *buf, size_t buflen);
|
|
|
|
int coredump_query(enum coredump_query_id query_id, void *arg);
|
|
int coredump_cmd(enum coredump_cmd_id cmd_id, void *arg);
|
|
|
|
#else
|
|
|
|
void coredump(unsigned int reason, const z_arch_esf_t *esf,
|
|
struct k_thread *thread)
|
|
{
|
|
}
|
|
|
|
void coredump_memory_dump(uintptr_t start_addr, uintptr_t end_addr)
|
|
{
|
|
}
|
|
|
|
void coredump_buffer_output(uint8_t *buf, size_t buflen)
|
|
{
|
|
}
|
|
|
|
int coredump_query(enum coredump_query_id query_id, void *arg)
|
|
{
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
int coredump_cmd(enum coredump_cmd_id query_id, void *arg)
|
|
{
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
#endif /* CONFIG_DEBUG_COREDUMP */
|
|
|
|
/**
|
|
* @defgroup coredump_apis Coredump APIs
|
|
* @brief Coredump APIs
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @fn void coredump(unsigned int reason, const z_arch_esf_t *esf, struct k_thread *thread);
|
|
* @brief Perform coredump.
|
|
*
|
|
* Normally, this is called inside z_fatal_error() to generate coredump
|
|
* when a fatal error is encountered. This can also be called on demand
|
|
* whenever a coredump is desired.
|
|
*
|
|
* @param reason Reason for the fatal error
|
|
* @param esf Exception context
|
|
* @param thread Thread information to dump
|
|
*/
|
|
|
|
/**
|
|
* @fn void coredump_memory_dump(uintptr_t start_addr, uintptr_t end_addr);
|
|
* @brief Dump memory region
|
|
*
|
|
* @param start_addr Start address of memory region to be dumped
|
|
* @param end_addr End address of memory region to be dumped
|
|
*/
|
|
|
|
/**
|
|
* @fn int coredump_buffer_output(uint8_t *buf, size_t buflen);
|
|
* @brief Output the buffer via coredump
|
|
*
|
|
* This outputs the buffer of byte array to the coredump backend.
|
|
* For example, this can be called to output the coredump section
|
|
* containing registers, or a section for memory dump.
|
|
*
|
|
* @param buf Buffer to be send to coredump output
|
|
* @param buflen Buffer length
|
|
*/
|
|
|
|
/**
|
|
* @fn int coredump_query(enum coredump_query_id query_id, void *arg);
|
|
* @brief Perform query on coredump subsystem.
|
|
*
|
|
* Query the coredump subsystem for information, for example, if there is
|
|
* an error.
|
|
*
|
|
* @param[in] query_id Query ID
|
|
* @param[in,out] arg Pointer to argument for exchanging information
|
|
* @return Depends on the query
|
|
*/
|
|
|
|
/**
|
|
* @fn int coredump_cmd(enum coredump_cmd_id cmd_id, void *arg);
|
|
* @brief Perform command on coredump subsystem.
|
|
*
|
|
* Perform certain on coredump subsystem, for example, output the stored
|
|
* coredump via logging.
|
|
*
|
|
* @param[in] cmd_id Command ID
|
|
* @param[in,out] arg Pointer to argument for exchanging information
|
|
* @return Depends on the command
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
#endif /* ZEPHYR_INCLUDE_DEBUG_COREDUMP_H_ */
|