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