blob: 2b4a86a1bb9b2be6f350fd8d15596faf0eaab3db [file] [log] [blame]
/*
* Copyright (c) 2020 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <zephyr/debug/coredump.h>
#define ARCH_HDR_VER 2
uint32_t z_arm_coredump_fault_sp;
struct arm_arch_block {
struct {
uint32_t r0;
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r12;
uint32_t lr;
uint32_t pc;
uint32_t xpsr;
uint32_t sp;
/* callee registers - optionally collected in V2 */
uint32_t r4;
uint32_t r5;
uint32_t r6;
uint32_t r7;
uint32_t r8;
uint32_t r9;
uint32_t r10;
uint32_t r11;
} r;
} __packed;
/*
* This might be too large for stack space if defined
* inside function. So do it here.
*/
static struct arm_arch_block arch_blk;
void arch_coredump_info_dump(const z_arch_esf_t *esf)
{
struct coredump_arch_hdr_t hdr = {
.id = COREDUMP_ARCH_HDR_ID,
.hdr_version = ARCH_HDR_VER,
.num_bytes = sizeof(arch_blk),
};
/* Nothing to process */
if (esf == NULL) {
return;
}
(void)memset(&arch_blk, 0, sizeof(arch_blk));
/*
* 17 registers expected by GDB.
* Not all are in ESF but the GDB stub
* will need to send all 17 as one packet.
* The stub will need to send undefined
* for registers not presented in coredump.
*/
arch_blk.r.r0 = esf->basic.r0;
arch_blk.r.r1 = esf->basic.r1;
arch_blk.r.r2 = esf->basic.r2;
arch_blk.r.r3 = esf->basic.r3;
arch_blk.r.r12 = esf->basic.ip;
arch_blk.r.lr = esf->basic.lr;
arch_blk.r.pc = esf->basic.pc;
arch_blk.r.xpsr = esf->basic.xpsr;
arch_blk.r.sp = z_arm_coredump_fault_sp;
#if defined(CONFIG_EXTRA_EXCEPTION_INFO)
if (esf->extra_info.callee) {
arch_blk.r.r4 = esf->extra_info.callee->v1;
arch_blk.r.r5 = esf->extra_info.callee->v2;
arch_blk.r.r6 = esf->extra_info.callee->v3;
arch_blk.r.r7 = esf->extra_info.callee->v4;
arch_blk.r.r8 = esf->extra_info.callee->v5;
arch_blk.r.r9 = esf->extra_info.callee->v6;
arch_blk.r.r10 = esf->extra_info.callee->v7;
arch_blk.r.r11 = esf->extra_info.callee->v8;
}
#endif
/* Send for output */
coredump_buffer_output((uint8_t *)&hdr, sizeof(hdr));
coredump_buffer_output((uint8_t *)&arch_blk, sizeof(arch_blk));
}
uint16_t arch_coredump_tgt_code_get(void)
{
return COREDUMP_TGT_ARM_CORTEX_M;
}