1 /*
2 * Copyright (c) 2021 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <inttypes.h>
8
9 #ifndef ZEPHYR_INCLUDE_ARCH_XTENSA_GDBSTUB_SYS_H_
10 #define ZEPHYR_INCLUDE_ARCH_XTENSA_GDBSTUB_SYS_H_
11
12 #ifdef CONFIG_GDBSTUB
13
14 #define XTREG_GRP_MASK 0x0F00
15 #define XTREG_GRP_GENERAL 0x0000
16 #define XTREG_GRP_ADDR 0x0100
17 #define XTREG_GRP_SPECIAL 0x0200
18 #define XTREG_GRP_USER 0x0300
19
20 /**
21 * @brief Register description for GDB stub.
22 *
23 * Values are based on gdb/gdb/xtensa-config.c in the Xtensa overlay,
24 * where registers are defined using XTREG() macro:
25 * XTREG(index,ofs,bsz,sz,al,tnum,flg,cp,ty,gr,name,fet,sto,mas,ct,x,y)
26 *
27 * Translation:
28 * idx : index
29 * regno : tnum
30 * 0x00xx : General Registers (A0 - A15, PC)
31 * 0x01xx : Address Registers (AR0 - AR31/AR63)
32 * 0x02xx : Special Registers (access via RSR/WSR)
33 * 0x03xx : User Registers (access via RUR/WUR)
34 * byte_size : sz
35 * gpkt_offset : ofs
36 */
37 struct xtensa_register {
38 /** Register value */
39 uint32_t val;
40
41 /** GDB register index (for p/P packets) */
42 uint8_t idx;
43
44 /** Size of register */
45 uint8_t byte_size;
46
47 /** Xtensa register number */
48 uint16_t regno;
49
50 /**
51 * Offset of this register in GDB G-packet.
52 * -1 if register is not in G-packet.
53 */
54 int16_t gpkt_offset;
55
56 /**
57 * Offset of saved register in stack frame.
58 * 0 if not saved in stack frame.
59 */
60 int8_t stack_offset;
61
62 /** Sequence number */
63 uint8_t seqno;
64
65 /**
66 * Set to 1 if register should not be written
67 * to during debugging.
68 */
69 uint8_t is_read_only:1;
70 };
71
72 /* Due to Xtensa SoCs being highly configurable,
73 * the register files between SoCs are not identical.
74 *
75 * This means generic registers can, sometimes, have
76 * different offsets from start of register files
77 * needed to communicate with GDB.
78 *
79 * Therefore, it is better to defer to the SoC layer
80 * for proper support for GDB.
81 */
82 #include <gdbstub/soc.h>
83
84 /**
85 * @brief Architecture specific GDB context.
86 */
87 struct gdb_ctx {
88 /** Exception reason */
89 unsigned int exception;
90
91 /** Register descriptions */
92 struct xtensa_register *regs;
93
94 /** Number of registers */
95 uint8_t num_regs;
96
97 /** Sequence number */
98 uint8_t seqno;
99
100 /** Index in register descriptions of A0 register */
101 uint8_t a0_idx;
102
103 /** Index in register descriptions of AR0 register */
104 uint8_t ar_idx;
105
106 /** Index in register descriptions of WINDOWBASE register */
107 uint8_t wb_idx;
108 };
109
110 /**
111 * Test if the register is a logical address register (A0 - A15).
112 *
113 * @retval true if register is A0 - A15
114 * @retval false if register is not A0 - A15
115 */
gdb_xtensa_is_logical_addr_reg(struct xtensa_register * reg)116 static inline bool gdb_xtensa_is_logical_addr_reg(struct xtensa_register *reg)
117 {
118 if (reg->regno < 16) {
119 return true;
120 } else {
121 return false;
122 }
123 }
124
125 /**
126 * Test if the register is a address register (AR0 - AR31/AR63).
127 *
128 * @retval true if register is AR0 - AR31/AR63
129 * @retval false if not
130 */
gdb_xtensa_is_address_reg(struct xtensa_register * reg)131 static inline bool gdb_xtensa_is_address_reg(struct xtensa_register *reg)
132 {
133 if ((reg->regno & XTREG_GRP_MASK) == XTREG_GRP_ADDR) {
134 return true;
135 } else {
136 return false;
137 }
138 }
139
140 /**
141 * Test if the register is a special register that needs to be
142 * accessed via RSR/WSR.
143 *
144 * @retval true if special register
145 * @retval false if not
146 */
gdb_xtensa_is_special_reg(struct xtensa_register * reg)147 static inline bool gdb_xtensa_is_special_reg(struct xtensa_register *reg)
148 {
149 if ((reg->regno & XTREG_GRP_MASK) == XTREG_GRP_SPECIAL) {
150 return true;
151 } else {
152 return false;
153 }
154 }
155
156 /**
157 * Test if the register is a user register that needs to be
158 * accessed via RUR/WUR.
159 *
160 * @retval true if user register
161 * @retval false if not
162 */
gdb_xtensa_is_user_reg(struct xtensa_register * reg)163 static inline bool gdb_xtensa_is_user_reg(struct xtensa_register *reg)
164 {
165 if ((reg->regno & XTREG_GRP_MASK) == XTREG_GRP_USER) {
166 return true;
167 } else {
168 return false;
169 }
170 }
171
172 #endif /* CONFIG_GDBSTUB */
173
174 #endif /* ZEPHYR_INCLUDE_ARCH_XTENSA_GDBSTUB_SYS_H_ */
175