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  * Register description fot 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 	/* Offset of this register in GDB G-packet.
51 	 * -1 if register is not in G-packet.
52 	 */
53 	int16_t		gpkt_offset;
54 
55 	/* Offset of saved register in stack frame.
56 	 * 0 if not saved in stack frame.
57 	 */
58 	int8_t		stack_offset;
59 
60 	/* Sequence number */
61 	uint8_t		seqno;
62 
63 	/* Set 1 to if register should not be written
64 	 * to during debugging.
65 	 */
66 	uint8_t		is_read_only:1;
67 };
68 
69 /* Due to Xtensa SoCs being highly configurable,
70  * the register files between SoCs are not identical.
71  *
72  * This means generic registers can, sometimes, have
73  * different offsets from start of register files
74  * needed to communicate with GDB.
75  *
76  * Therefore, it is better to defer to the SoC layer
77  * for proper support for GDB.
78  */
79 #include <gdbstub/soc.h>
80 
81 struct gdb_ctx {
82 	/* Exception reason */
83 	unsigned int		exception;
84 
85 	/* Register descriptions */
86 	struct xtensa_register	*regs;
87 
88 	/* Number of registers */
89 	uint8_t			num_regs;
90 
91 	/* Sequence number */
92 	uint8_t			seqno;
93 
94 	/* Index in register descriptions of A0 register */
95 	uint8_t			a0_idx;
96 
97 	/* Index in register descriptions of AR0 register */
98 	uint8_t			ar_idx;
99 
100 	/* Index in register descriptions of WINDOWBASE register */
101 	uint8_t			wb_idx;
102 };
103 
104 /**
105  * Test if the register is a logical address register (A0 - A15).
106  *
107  * @retval true  if register is A0 - A15
108  * @retval false if register is not A0 - A15
109  */
gdb_xtensa_is_logical_addr_reg(struct xtensa_register * reg)110 static inline bool gdb_xtensa_is_logical_addr_reg(struct xtensa_register *reg)
111 {
112 	if (reg->regno < 16) {
113 		return true;
114 	} else {
115 		return false;
116 	}
117 }
118 
119 /**
120  * Test if the register is a address register (AR0 - AR31/AR63).
121  *
122  * @retval true  if register is AR0 - AR31/AR63
123  * @retval false if not
124  */
gdb_xtensa_is_address_reg(struct xtensa_register * reg)125 static inline bool gdb_xtensa_is_address_reg(struct xtensa_register *reg)
126 {
127 	if ((reg->regno & XTREG_GRP_MASK) == XTREG_GRP_ADDR) {
128 		return true;
129 	} else {
130 		return false;
131 	}
132 }
133 
134 /**
135  * Test if the register is a special register that needs to be
136  * accessed via RSR/WSR.
137  *
138  * @retval true  if special register
139  * @retval false if not
140  */
gdb_xtensa_is_special_reg(struct xtensa_register * reg)141 static inline bool gdb_xtensa_is_special_reg(struct xtensa_register *reg)
142 {
143 	if ((reg->regno & XTREG_GRP_MASK) == XTREG_GRP_SPECIAL) {
144 		return true;
145 	} else {
146 		return false;
147 	}
148 }
149 
150 /**
151  * Test if the register is a user register that needs to be
152  * accessed via RUR/WUR.
153  *
154  * @retval true  if user register
155  * @retval false if not
156  */
gdb_xtensa_is_user_reg(struct xtensa_register * reg)157 static inline bool gdb_xtensa_is_user_reg(struct xtensa_register *reg)
158 {
159 	if ((reg->regno & XTREG_GRP_MASK) == XTREG_GRP_USER) {
160 		return true;
161 	} else {
162 		return false;
163 	}
164 }
165 
166 #endif /* CONFIG_GDBSTUB */
167 
168 #endif /* ZEPHYR_INCLUDE_ARCH_XTENSA_GDBSTUB_SYS_H_ */
169