treewide: Move device_tree to commonlib
[coreboot2.git] / payloads / libpayload / arch / arm / gdb.c
blob2a8eb310b23b2bbd4a0c72345fee9b94e9bb5f80
1 /*
2 * Copyright 2014 Google Inc.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of
7 * the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but without any warranty; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <exception.h>
16 #include <gdb.h>
17 #include <libpayload.h>
19 struct gdb_regs
21 u32 r[16];
22 struct fp_reg
24 u8 byte[12];
25 } __packed f[8];
26 u32 fps;
27 u32 cpsr;
28 } __packed;
30 static const u8 type_to_signal[] = {
31 [EXC_UNDEF] = GDB_SIGILL,
32 [EXC_SWI] = GDB_SIGTRAP,
33 [EXC_PABORT] = GDB_SIGSEGV,
34 [EXC_DABORT] = GDB_SIGSEGV,
37 /* Scratch value to write reentrant exception states to. We never read it. */
38 static struct exception_state sentinel_exception_state;
40 static int gdb_exception_hook(u32 type)
42 if (!gdb_handle_reentrant_exception()) {
43 if (type >= ARRAY_SIZE(type_to_signal) || !type_to_signal[type])
44 return 0;
45 exception_state_ptr = &sentinel_exception_state;
46 gdb_command_loop(type_to_signal[type]);
49 exception_state_ptr = &exception_state;
50 return 1;
53 void gdb_arch_init(void)
55 exception_install_hook(&gdb_exception_hook);
58 void gdb_arch_enter(void)
60 u32 *sp;
62 asm volatile ("mov %0, %%sp" : "=r"(sp) );
64 /* Avoid reentrant exceptions, just call the hook if in one already. */
65 if (sp >= exception_stack && sp <= exception_stack_end)
66 gdb_exception_hook(EXC_SWI);
67 else
68 asm volatile ("svc #0");
71 int gdb_arch_set_single_step(int on)
73 /* GDB seems to only need this on x86, ARM works fine without it. */
74 return -1;
77 void gdb_arch_encode_regs(struct gdb_message *message)
79 gdb_message_encode_bytes(message, exception_state.regs,
80 sizeof(exception_state.regs));
81 gdb_message_encode_zero_bytes(message,
82 offsetof(struct gdb_regs, cpsr) - offsetof(struct gdb_regs, f));
83 gdb_message_encode_bytes(message, &exception_state.cpsr,
84 sizeof(exception_state.cpsr));
87 void gdb_arch_decode_regs(int offset, struct gdb_message *message)
89 const int cpsr_hex_offset = offsetof(struct gdb_regs, cpsr) * 2;
90 gdb_message_decode_bytes(message, offset,
91 exception_state.regs, sizeof(exception_state.regs));
92 gdb_message_decode_bytes(message, offset + cpsr_hex_offset,
93 &exception_state.cpsr, sizeof(exception_state.cpsr));