1 /*
2  * Copyright (c) 2020 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <string.h>
8 #include <zephyr/debug/coredump.h>
9 
10 #define ARCH_HDR_VER			2
11 
12 uint32_t z_arm_coredump_fault_sp;
13 
14 struct arm_arch_block {
15 	struct {
16 		uint32_t	r0;
17 		uint32_t	r1;
18 		uint32_t	r2;
19 		uint32_t	r3;
20 		uint32_t	r12;
21 		uint32_t	lr;
22 		uint32_t	pc;
23 		uint32_t	xpsr;
24 		uint32_t	sp;
25 
26 		/* callee registers - optionally collected in V2 */
27 		uint32_t	r4;
28 		uint32_t	r5;
29 		uint32_t	r6;
30 		uint32_t	r7;
31 		uint32_t	r8;
32 		uint32_t	r9;
33 		uint32_t	r10;
34 		uint32_t	r11;
35 	} r;
36 } __packed;
37 
38 /*
39  * This might be too large for stack space if defined
40  * inside function. So do it here.
41  */
42 static struct arm_arch_block arch_blk;
43 
arch_coredump_info_dump(const struct arch_esf * esf)44 void arch_coredump_info_dump(const struct arch_esf *esf)
45 {
46 	struct coredump_arch_hdr_t hdr = {
47 		.id = COREDUMP_ARCH_HDR_ID,
48 		.hdr_version = ARCH_HDR_VER,
49 		.num_bytes = sizeof(arch_blk),
50 	};
51 
52 	/* Nothing to process */
53 	if (esf == NULL) {
54 		return;
55 	}
56 
57 	(void)memset(&arch_blk, 0, sizeof(arch_blk));
58 
59 	/*
60 	 * 17 registers expected by GDB.
61 	 * Not all are in ESF but the GDB stub
62 	 * will need to send all 17 as one packet.
63 	 * The stub will need to send undefined
64 	 * for registers not presented in coredump.
65 	 */
66 	arch_blk.r.r0 = esf->basic.r0;
67 	arch_blk.r.r1 = esf->basic.r1;
68 	arch_blk.r.r2 = esf->basic.r2;
69 	arch_blk.r.r3 = esf->basic.r3;
70 	arch_blk.r.r12 = esf->basic.ip;
71 	arch_blk.r.lr = esf->basic.lr;
72 	arch_blk.r.pc = esf->basic.pc;
73 	arch_blk.r.xpsr = esf->basic.xpsr;
74 
75 	arch_blk.r.sp = z_arm_coredump_fault_sp;
76 
77 #if defined(CONFIG_EXTRA_EXCEPTION_INFO)
78 	if (esf->extra_info.callee) {
79 		arch_blk.r.r4  = esf->extra_info.callee->v1;
80 		arch_blk.r.r5  = esf->extra_info.callee->v2;
81 		arch_blk.r.r6  = esf->extra_info.callee->v3;
82 		arch_blk.r.r7  = esf->extra_info.callee->v4;
83 		arch_blk.r.r8  = esf->extra_info.callee->v5;
84 		arch_blk.r.r9  = esf->extra_info.callee->v6;
85 		arch_blk.r.r10 = esf->extra_info.callee->v7;
86 		arch_blk.r.r11 = esf->extra_info.callee->v8;
87 	}
88 #endif
89 
90 	/* Send for output */
91 	coredump_buffer_output((uint8_t *)&hdr, sizeof(hdr));
92 	coredump_buffer_output((uint8_t *)&arch_blk, sizeof(arch_blk));
93 }
94 
arch_coredump_tgt_code_get(void)95 uint16_t arch_coredump_tgt_code_get(void)
96 {
97 	return COREDUMP_TGT_ARM_CORTEX_M;
98 }
99