| /* |
| * Copyright (c) 2021 Facebook, Inc. and its affiliates |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <string.h> |
| #include <zephyr/debug/coredump.h> |
| |
| #define ARCH_HDR_VER 1 |
| |
| struct riscv_arch_block { |
| struct { |
| uint32_t ra; |
| uint32_t tp; |
| uint32_t t0; |
| uint32_t t1; |
| uint32_t t2; |
| uint32_t a0; |
| uint32_t a1; |
| uint32_t a2; |
| uint32_t a3; |
| uint32_t a4; |
| uint32_t a5; |
| #if !defined(CONFIG_RISCV_ISA_RV32E) |
| uint32_t a6; |
| uint32_t a7; |
| uint32_t t3; |
| uint32_t t4; |
| uint32_t t5; |
| uint32_t t6; |
| #endif /* !CONFIG_RISCV_ISA_RV32E */ |
| uint32_t pc; |
| } r; |
| } __packed; |
| |
| /* |
| * This might be too large for stack space if defined |
| * inside function. So do it here. |
| */ |
| static struct riscv_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)); |
| |
| /* |
| * 33 registers expected by GDB. Not all are in ESF but the GDB stub will need |
| * to send all 33 as one packet. The stub will need to send undefined for |
| * registers not presented in coredump. |
| */ |
| arch_blk.r.ra = esf->ra; |
| arch_blk.r.t0 = esf->t0; |
| arch_blk.r.t1 = esf->t1; |
| arch_blk.r.t2 = esf->t2; |
| arch_blk.r.a0 = esf->a0; |
| arch_blk.r.a1 = esf->a1; |
| arch_blk.r.a2 = esf->a2; |
| arch_blk.r.a3 = esf->a3; |
| arch_blk.r.a4 = esf->a4; |
| arch_blk.r.a5 = esf->a5; |
| #if !defined(CONFIG_RISCV_ISA_RV32E) |
| arch_blk.r.t3 = esf->t3; |
| arch_blk.r.t4 = esf->t4; |
| arch_blk.r.t5 = esf->t5; |
| arch_blk.r.t6 = esf->t6; |
| arch_blk.r.a6 = esf->a6; |
| arch_blk.r.a7 = esf->a7; |
| #endif /* !CONFIG_RISCV_ISA_RV32E */ |
| arch_blk.r.pc = esf->mepc; |
| |
| /* 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_RISC_V; |
| } |