1/** \file
2 * \brief x86-specific parts of in-kernel GDB stub.
3 *
4 * This file implements x86 architecture support for the kernel-side GDB stubs.
5 */
6
7/*
8 * Copyright (c) 2007, 2008, 2009, ETH Zurich.
9 * All rights reserved.
10 *
11 * This file is distributed under the terms in the attached LICENSE file.
12 * If you do not find this file, copies can be found by writing to:
13 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
14 */
15
16#include <kernel.h>
17#include <stdio.h>
18#include <gdb_stub.h>
19#include <barrelfish_kpi/cpu.h>
20#include <exec.h>
21
22/**
23 * \brief X86_32 register set
24 *
25 * As defined by GDB.
26 */
27enum x86_32_register_nums {
28    X86_32_EAX_REG, X86_32_EBX_REG, X86_32_ECX_REG, X86_32_EDX_REG,
29    X86_32_ESI_REG, X86_32_EDI_REG, X86_32_EBP_REG, X86_32_ESP_REG,
30    X86_32_EIP_REG, X86_32_EFLAGS_REG, X86_32_CS_REG, X86_32_SS_REG,
31
32/* these are not saved/used, and currently avoided
33    DS_REG, ES_REG, FS_REG, GS_REG,
34*/
35
36/* these are not used yet:
37    ST0_REG, ST1_REG, ST2_REG, ST3_REG, ST4_REG, ST5_REG, ST6_REG, ST7_REG,
38
39    FCTRL_REG, FSTAT_REG, FTAG_REG, FISEG_REG,
40    FIOFF_REG, FOSEG_REG, FOOFF_REG, FOP_REG,
41
42    XMM0_REG, XMM1_REG, XMM2_REG, XMM3_REG, XMM4_REG, XMM5_REG,
43    XMM6_REG, XMM7_REG, XMM8_REG, XMM9_REG, XMM10_REG, XMM11_REG,
44    XMM12_REG, XMM13_REG, XMM14_REG, XMM15_REG,
45    MXCSR_REG
46*/
47
48    X86_32_ARCH_NUMREGS /* not a real register; must be last! See also NUM_REGS. */
49};
50
51uintptr_t *gdb_arch_registers;
52
53__asm__ (
54    ".global gdb_handle_exception       \n"
55    "gdb_handle_exception:              \n"
56    /* "mov gdb_stack_top(%rip), %rsp      \n" */
57    "jmp gdb_handle_exception_onstack   \n"
58);
59
60/** \brief Entry point for an exception; we are now on our own stack.
61 *
62 * This function sets up the GDB-format register save frame, constructs the
63 * initial message to the remote GDB and calls into the generic debugger entry
64 * point.
65 */
66void gdb_handle_exception_onstack(int vector, uintptr_t * NONNULL
67        COUNT(NUM_REGS) save_area);
68void gdb_handle_exception_onstack(int vector, uintptr_t * NONNULL
69        COUNT(NUM_REGS) save_area)
70{
71    printf("No GDB backend\n");
72    halt();
73}
74
75/** \brief Get the value of a single register in the frame.
76 * \param regnum register number (as defined by the #gdb_register_nums enum)
77 * \param value pointer to location in which to return current value
78 * \return Zero on success, nonzero on failure (invalid regnum).
79 */
80int gdb_arch_get_register(int regnum, uintptr_t *value)
81{
82    panic("NYI");
83    return -1;
84}
85
86/** \brief Set the value of a single register in the frame.
87 * \param regnum register number (as defined by the #gdb_register_nums enum)
88 * \param value new value
89 * \return Zero on success, nonzero on failure (invalid regnum).
90 */
91int gdb_arch_set_register(int regnum, uintptr_t value)
92{
93    panic("NYI");
94    return -1;
95}
96
97/** \brief Resume execution.
98 *
99 * Resumes execution with the CPU state stored in the #gdb_arch_registers frame.
100 */
101void gdb_resume(void);
102void gdb_resume(void)
103{
104    panic("NYI");
105}
106
107/** \brief Resume program execution.
108 * \param addr Address to resume at, or 0 to continue at last address.
109 */
110void gdb_arch_continue(lvaddr_t addr)
111{
112    gdb_resume(); /* doesn't return */
113}
114
115/** \brief Single-step program execution.
116 * \param addr Address to resume at, or 0 to continue at last address.
117 */
118void gdb_arch_single_step(lvaddr_t addr)
119{
120    gdb_resume(); /* doesn't return */
121}
122
123/** \brief Writes a byte to an arbitrary address in kernel memory.
124 * \return Zero on success, nonzero on error (invalid address)
125 */
126int gdb_arch_write_byte(uint8_t *addr, uint8_t val)
127{
128    panic("NYI");
129    return 0;
130}
131
132/** \brief Reads a byte from an arbitrary address in kernel memory.
133 * \return Zero on success, nonzero on error (invalid address)
134 */
135int gdb_arch_read_byte(uint8_t *addr, uint8_t *val)
136{
137    panic("NYI");
138    return 0;
139}
140