1 /*
2  * Copyright (c) 2020 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <string.h>
8 #include <zephyr/kernel.h>
9 #include <zephyr/debug/coredump.h>
10 
11 #define ARCH_HDR_VER			1
12 
13 struct x86_arch_block {
14 	uint32_t	vector;
15 	uint32_t	code;
16 
17 	struct {
18 		uint32_t	eax;
19 		uint32_t	ecx;
20 		uint32_t	edx;
21 		uint32_t	ebx;
22 		uint32_t	esp;
23 		uint32_t	ebp;
24 		uint32_t	esi;
25 		uint32_t	edi;
26 		uint32_t	eip;
27 		uint32_t	eflags;
28 		uint32_t	cs;
29 	} r;
30 } __packed;
31 
32 /*
33  * This might be too large for stack space if defined
34  * inside function. So do it here.
35  */
36 static struct x86_arch_block arch_blk;
37 
arch_coredump_info_dump(const struct arch_esf * esf)38 void arch_coredump_info_dump(const struct arch_esf *esf)
39 {
40 	struct coredump_arch_hdr_t hdr = {
41 		.id = COREDUMP_ARCH_HDR_ID,
42 		.hdr_version = ARCH_HDR_VER,
43 		.num_bytes = sizeof(arch_blk),
44 	};
45 
46 	/* Nothing to process */
47 	if (esf == NULL) {
48 		return;
49 	}
50 
51 	(void)memset(&arch_blk, 0, sizeof(arch_blk));
52 
53 	arch_blk.vector = z_x86_exception_vector;
54 	arch_blk.code = esf->errorCode;
55 
56 	/*
57 	 * 16 registers expected by GDB.
58 	 * Not all are in ESF but the GDB stub
59 	 * will need to send all 16 as one packet.
60 	 * The stub will need to send undefined
61 	 * for registers not presented in coredump.
62 	 */
63 	arch_blk.r.eax = esf->eax;
64 	arch_blk.r.ebx = esf->ebx;
65 	arch_blk.r.ecx = esf->ecx;
66 	arch_blk.r.edx = esf->edx;
67 	arch_blk.r.esp = esf->esp;
68 	arch_blk.r.ebp = esf->ebp;
69 	arch_blk.r.esi = esf->esi;
70 	arch_blk.r.edi = esf->edi;
71 	arch_blk.r.eip = esf->eip;
72 	arch_blk.r.eflags = esf->eflags;
73 	arch_blk.r.cs = esf->cs & 0xFFFFU;
74 
75 	/* Send for output */
76 	coredump_buffer_output((uint8_t *)&hdr, sizeof(hdr));
77 	coredump_buffer_output((uint8_t *)&arch_blk, sizeof(arch_blk));
78 }
79 
arch_coredump_tgt_code_get(void)80 uint16_t arch_coredump_tgt_code_get(void)
81 {
82 	return COREDUMP_TGT_X86;
83 }
84 
85 #if defined(CONFIG_DEBUG_COREDUMP_DUMP_THREAD_PRIV_STACK)
arch_coredump_priv_stack_dump(struct k_thread * thread)86 void arch_coredump_priv_stack_dump(struct k_thread *thread)
87 {
88 	struct z_x86_thread_stack_header *hdr_stack_obj;
89 	uintptr_t start_addr, end_addr;
90 
91 #if defined(CONFIG_THREAD_STACK_MEM_MAPPED)
92 	hdr_stack_obj = (struct z_x86_thread_stack_header *)thread->stack_info.mapped.addr;
93 #else
94 	hdr_stack_obj = (struct z_x86_thread_stack_header *)thread->stack_obj;
95 #endif /* CONFIG_THREAD_STACK_MEM_MAPPED) */
96 
97 	start_addr = (uintptr_t)&hdr_stack_obj->privilege_stack[0];
98 	end_addr = start_addr + sizeof(hdr_stack_obj->privilege_stack);
99 
100 	coredump_memory_dump(start_addr, end_addr);
101 }
102 #endif /* CONFIG_DEBUG_COREDUMP_DUMP_THREAD_PRIV_STACK */
103