target/xtensa: virtualize XDM registers
[openocd.git] / src / target / xtensa / xtensa.c
bloba90cd146841d5f5f25fe86919e8bf1a62984c43d
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 /***************************************************************************
4 * Generic Xtensa target API for OpenOCD *
5 * Copyright (C) 2020-2022 Cadence Design Systems, Inc. *
6 * Copyright (C) 2016-2019 Espressif Systems Ltd. *
7 * Derived from esp108.c *
8 * Author: Angus Gratton gus@projectgus.com *
9 ***************************************************************************/
11 #ifdef HAVE_CONFIG_H
12 #include "config.h"
13 #endif
15 #include <stdlib.h>
16 #include <helper/time_support.h>
17 #include <helper/align.h>
18 #include <target/register.h>
20 #include "xtensa_chip.h"
21 #include "xtensa.h"
23 /* Swap 4-bit Xtensa opcodes and fields */
24 #define XT_NIBSWAP8(V) \
25 ((((V) & 0x0F) << 4) \
26 | (((V) & 0xF0) >> 4))
28 #define XT_NIBSWAP16(V) \
29 ((((V) & 0x000F) << 12) \
30 | (((V) & 0x00F0) << 4) \
31 | (((V) & 0x0F00) >> 4) \
32 | (((V) & 0xF000) >> 12))
34 #define XT_NIBSWAP24(V) \
35 ((((V) & 0x00000F) << 20) \
36 | (((V) & 0x0000F0) << 12) \
37 | (((V) & 0x000F00) << 4) \
38 | (((V) & 0x00F000) >> 4) \
39 | (((V) & 0x0F0000) >> 12) \
40 | (((V) & 0xF00000) >> 20))
42 /* _XT_INS_FORMAT_*()
43 * Instruction formatting converted from little-endian inputs
44 * and shifted to the MSB-side of DIR for BE systems.
46 #define _XT_INS_FORMAT_RSR(X, OPCODE, SR, T) \
47 (XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE) \
48 | (((T) & 0x0F) << 16) \
49 | (((SR) & 0xFF) << 8)) << 8 \
50 : (OPCODE) \
51 | (((SR) & 0xFF) << 8) \
52 | (((T) & 0x0F) << 4))
54 #define _XT_INS_FORMAT_RRR(X, OPCODE, ST, R) \
55 (XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE) \
56 | ((XT_NIBSWAP8((ST) & 0xFF)) << 12) \
57 | (((R) & 0x0F) << 8)) << 8 \
58 : (OPCODE) \
59 | (((ST) & 0xFF) << 4) \
60 | (((R) & 0x0F) << 12))
62 #define _XT_INS_FORMAT_RRRN(X, OPCODE, S, T, IMM4) \
63 (XT_ISBE(X) ? (XT_NIBSWAP16(OPCODE) \
64 | (((T) & 0x0F) << 8) \
65 | (((S) & 0x0F) << 4) \
66 | ((IMM4) & 0x0F)) << 16 \
67 : (OPCODE) \
68 | (((T) & 0x0F) << 4) \
69 | (((S) & 0x0F) << 8) \
70 | (((IMM4) & 0x0F) << 12))
72 #define _XT_INS_FORMAT_RRI8(X, OPCODE, R, S, T, IMM8) \
73 (XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE) \
74 | (((T) & 0x0F) << 16) \
75 | (((S) & 0x0F) << 12) \
76 | (((R) & 0x0F) << 8) \
77 | ((IMM8) & 0xFF)) << 8 \
78 : (OPCODE) \
79 | (((IMM8) & 0xFF) << 16) \
80 | (((R) & 0x0F) << 12) \
81 | (((S) & 0x0F) << 8) \
82 | (((T) & 0x0F) << 4))
84 #define _XT_INS_FORMAT_RRI4(X, OPCODE, IMM4, R, S, T) \
85 (XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE) \
86 | (((T) & 0x0F) << 16) \
87 | (((S) & 0x0F) << 12) \
88 | (((R) & 0x0F) << 8)) << 8 \
89 | ((IMM4) & 0x0F) \
90 : (OPCODE) \
91 | (((IMM4) & 0x0F) << 20) \
92 | (((R) & 0x0F) << 12) \
93 | (((S) & 0x0F) << 8) \
94 | (((T) & 0x0F) << 4))
96 /* Xtensa processor instruction opcodes
98 /* "Return From Debug Operation" to Normal */
99 #define XT_INS_RFDO(X) (XT_ISBE(X) ? 0x000e1f << 8 : 0xf1e000)
100 /* "Return From Debug and Dispatch" - allow sw debugging stuff to take over */
101 #define XT_INS_RFDD(X) (XT_ISBE(X) ? 0x010e1f << 8 : 0xf1e010)
103 /* Load to DDR register, increase addr register */
104 #define XT_INS_LDDR32P(X, S) (XT_ISBE(X) ? (0x0E0700 | ((S) << 12)) << 8 : (0x0070E0 | ((S) << 8)))
105 /* Store from DDR register, increase addr register */
106 #define XT_INS_SDDR32P(X, S) (XT_ISBE(X) ? (0x0F0700 | ((S) << 12)) << 8 : (0x0070F0 | ((S) << 8)))
108 /* Load 32-bit Indirect from A(S)+4*IMM8 to A(T) */
109 #define XT_INS_L32I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x002002, 0, S, T, IMM8)
110 /* Load 16-bit Unsigned from A(S)+2*IMM8 to A(T) */
111 #define XT_INS_L16UI(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x001002, 0, S, T, IMM8)
112 /* Load 8-bit Unsigned from A(S)+IMM8 to A(T) */
113 #define XT_INS_L8UI(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x000002, 0, S, T, IMM8)
115 /* Store 32-bit Indirect to A(S)+4*IMM8 from A(T) */
116 #define XT_INS_S32I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x006002, 0, S, T, IMM8)
117 /* Store 16-bit to A(S)+2*IMM8 from A(T) */
118 #define XT_INS_S16I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x005002, 0, S, T, IMM8)
119 /* Store 8-bit to A(S)+IMM8 from A(T) */
120 #define XT_INS_S8I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x004002, 0, S, T, IMM8)
122 /* Cache Instructions */
123 #define XT_INS_IHI(X, S, IMM8) _XT_INS_FORMAT_RRI8(X, 0x0070E2, 0, S, 0, IMM8)
124 #define XT_INS_DHWBI(X, S, IMM8) _XT_INS_FORMAT_RRI8(X, 0x007052, 0, S, 0, IMM8)
125 #define XT_INS_DHWB(X, S, IMM8) _XT_INS_FORMAT_RRI8(X, 0x007042, 0, S, 0, IMM8)
126 #define XT_INS_ISYNC(X) (XT_ISBE(X) ? 0x000200 << 8 : 0x002000)
128 /* Control Instructions */
129 #define XT_INS_JX(X, S) (XT_ISBE(X) ? (0x050000 | ((S) << 12)) : (0x0000a0 | ((S) << 8)))
130 #define XT_INS_CALL0(X, IMM18) (XT_ISBE(X) ? (0x500000 | ((IMM18) & 0x3ffff)) : (0x000005 | (((IMM18) & 0x3ffff) << 6)))
132 /* Read Special Register */
133 #define XT_INS_RSR(X, SR, T) _XT_INS_FORMAT_RSR(X, 0x030000, SR, T)
134 /* Write Special Register */
135 #define XT_INS_WSR(X, SR, T) _XT_INS_FORMAT_RSR(X, 0x130000, SR, T)
136 /* Swap Special Register */
137 #define XT_INS_XSR(X, SR, T) _XT_INS_FORMAT_RSR(X, 0x610000, SR, T)
139 /* Rotate Window by (-8..7) */
140 #define XT_INS_ROTW(X, N) (XT_ISBE(X) ? ((0x000804) | (((N) & 15) << 16)) << 8 : ((0x408000) | (((N) & 15) << 4)))
142 /* Read User Register */
143 #define XT_INS_RUR(X, UR, T) _XT_INS_FORMAT_RRR(X, 0xE30000, UR, T)
144 /* Write User Register */
145 #define XT_INS_WUR(X, UR, T) _XT_INS_FORMAT_RSR(X, 0xF30000, UR, T)
147 /* Read Floating-Point Register */
148 #define XT_INS_RFR(X, FR, T) _XT_INS_FORMAT_RRR(X, 0xFA0000, ((FR << 4) | 0x4), T)
149 /* Write Floating-Point Register */
150 #define XT_INS_WFR(X, FR, T) _XT_INS_FORMAT_RRR(X, 0xFA0000, ((T << 4) | 0x5), FR)
152 #define XT_INS_L32E(X, R, S, T) _XT_INS_FORMAT_RRI4(X, 0x090000, 0, R, S, T)
153 #define XT_INS_S32E(X, R, S, T) _XT_INS_FORMAT_RRI4(X, 0x490000, 0, R, S, T)
154 #define XT_INS_L32E_S32E_MASK(X) (XT_ISBE(X) ? 0xF000FF << 8 : 0xFF000F)
156 #define XT_INS_RFWO(X) (XT_ISBE(X) ? 0x004300 << 8 : 0x003400)
157 #define XT_INS_RFWU(X) (XT_ISBE(X) ? 0x005300 << 8 : 0x003500)
158 #define XT_INS_RFWO_RFWU_MASK(X) (XT_ISBE(X) ? 0xFFFFFF << 8 : 0xFFFFFF)
160 #define XT_WATCHPOINTS_NUM_MAX 2
162 /* Special register number macro for DDR, PS, WB, A3, A4 registers.
163 * These get used a lot so making a shortcut is useful.
165 #define XT_SR_DDR (xtensa_regs[XT_REG_IDX_DDR].reg_num)
166 #define XT_SR_PS (xtensa_regs[XT_REG_IDX_PS].reg_num)
167 #define XT_SR_WB (xtensa_regs[XT_REG_IDX_WINDOWBASE].reg_num)
168 #define XT_REG_A3 (xtensa_regs[XT_REG_IDX_AR3].reg_num)
169 #define XT_REG_A4 (xtensa_regs[XT_REG_IDX_AR4].reg_num)
171 #define XT_PS_REG_NUM_BASE (0xc0U) /* (EPS2 - 2), for adding DBGLEVEL */
172 #define XT_PC_REG_NUM_BASE (0xb0U) /* (EPC1 - 1), for adding DBGLEVEL */
173 #define XT_PC_REG_NUM_VIRTUAL (0xffU) /* Marker for computing PC (EPC[DBGLEVEL) */
174 #define XT_PC_DBREG_NUM_BASE (0x20U) /* External (i.e., GDB) access */
176 #define XT_SW_BREAKPOINTS_MAX_NUM 32
177 #define XT_HW_IBREAK_MAX_NUM 2
178 #define XT_HW_DBREAK_MAX_NUM 2
180 struct xtensa_reg_desc xtensa_regs[XT_NUM_REGS] = {
181 XT_MK_REG_DESC("pc", XT_PC_REG_NUM_VIRTUAL, XT_REG_SPECIAL, 0),
182 XT_MK_REG_DESC("ar0", 0x00, XT_REG_GENERAL, 0),
183 XT_MK_REG_DESC("ar1", 0x01, XT_REG_GENERAL, 0),
184 XT_MK_REG_DESC("ar2", 0x02, XT_REG_GENERAL, 0),
185 XT_MK_REG_DESC("ar3", 0x03, XT_REG_GENERAL, 0),
186 XT_MK_REG_DESC("ar4", 0x04, XT_REG_GENERAL, 0),
187 XT_MK_REG_DESC("ar5", 0x05, XT_REG_GENERAL, 0),
188 XT_MK_REG_DESC("ar6", 0x06, XT_REG_GENERAL, 0),
189 XT_MK_REG_DESC("ar7", 0x07, XT_REG_GENERAL, 0),
190 XT_MK_REG_DESC("ar8", 0x08, XT_REG_GENERAL, 0),
191 XT_MK_REG_DESC("ar9", 0x09, XT_REG_GENERAL, 0),
192 XT_MK_REG_DESC("ar10", 0x0A, XT_REG_GENERAL, 0),
193 XT_MK_REG_DESC("ar11", 0x0B, XT_REG_GENERAL, 0),
194 XT_MK_REG_DESC("ar12", 0x0C, XT_REG_GENERAL, 0),
195 XT_MK_REG_DESC("ar13", 0x0D, XT_REG_GENERAL, 0),
196 XT_MK_REG_DESC("ar14", 0x0E, XT_REG_GENERAL, 0),
197 XT_MK_REG_DESC("ar15", 0x0F, XT_REG_GENERAL, 0),
198 XT_MK_REG_DESC("ar16", 0x10, XT_REG_GENERAL, 0),
199 XT_MK_REG_DESC("ar17", 0x11, XT_REG_GENERAL, 0),
200 XT_MK_REG_DESC("ar18", 0x12, XT_REG_GENERAL, 0),
201 XT_MK_REG_DESC("ar19", 0x13, XT_REG_GENERAL, 0),
202 XT_MK_REG_DESC("ar20", 0x14, XT_REG_GENERAL, 0),
203 XT_MK_REG_DESC("ar21", 0x15, XT_REG_GENERAL, 0),
204 XT_MK_REG_DESC("ar22", 0x16, XT_REG_GENERAL, 0),
205 XT_MK_REG_DESC("ar23", 0x17, XT_REG_GENERAL, 0),
206 XT_MK_REG_DESC("ar24", 0x18, XT_REG_GENERAL, 0),
207 XT_MK_REG_DESC("ar25", 0x19, XT_REG_GENERAL, 0),
208 XT_MK_REG_DESC("ar26", 0x1A, XT_REG_GENERAL, 0),
209 XT_MK_REG_DESC("ar27", 0x1B, XT_REG_GENERAL, 0),
210 XT_MK_REG_DESC("ar28", 0x1C, XT_REG_GENERAL, 0),
211 XT_MK_REG_DESC("ar29", 0x1D, XT_REG_GENERAL, 0),
212 XT_MK_REG_DESC("ar30", 0x1E, XT_REG_GENERAL, 0),
213 XT_MK_REG_DESC("ar31", 0x1F, XT_REG_GENERAL, 0),
214 XT_MK_REG_DESC("ar32", 0x20, XT_REG_GENERAL, 0),
215 XT_MK_REG_DESC("ar33", 0x21, XT_REG_GENERAL, 0),
216 XT_MK_REG_DESC("ar34", 0x22, XT_REG_GENERAL, 0),
217 XT_MK_REG_DESC("ar35", 0x23, XT_REG_GENERAL, 0),
218 XT_MK_REG_DESC("ar36", 0x24, XT_REG_GENERAL, 0),
219 XT_MK_REG_DESC("ar37", 0x25, XT_REG_GENERAL, 0),
220 XT_MK_REG_DESC("ar38", 0x26, XT_REG_GENERAL, 0),
221 XT_MK_REG_DESC("ar39", 0x27, XT_REG_GENERAL, 0),
222 XT_MK_REG_DESC("ar40", 0x28, XT_REG_GENERAL, 0),
223 XT_MK_REG_DESC("ar41", 0x29, XT_REG_GENERAL, 0),
224 XT_MK_REG_DESC("ar42", 0x2A, XT_REG_GENERAL, 0),
225 XT_MK_REG_DESC("ar43", 0x2B, XT_REG_GENERAL, 0),
226 XT_MK_REG_DESC("ar44", 0x2C, XT_REG_GENERAL, 0),
227 XT_MK_REG_DESC("ar45", 0x2D, XT_REG_GENERAL, 0),
228 XT_MK_REG_DESC("ar46", 0x2E, XT_REG_GENERAL, 0),
229 XT_MK_REG_DESC("ar47", 0x2F, XT_REG_GENERAL, 0),
230 XT_MK_REG_DESC("ar48", 0x30, XT_REG_GENERAL, 0),
231 XT_MK_REG_DESC("ar49", 0x31, XT_REG_GENERAL, 0),
232 XT_MK_REG_DESC("ar50", 0x32, XT_REG_GENERAL, 0),
233 XT_MK_REG_DESC("ar51", 0x33, XT_REG_GENERAL, 0),
234 XT_MK_REG_DESC("ar52", 0x34, XT_REG_GENERAL, 0),
235 XT_MK_REG_DESC("ar53", 0x35, XT_REG_GENERAL, 0),
236 XT_MK_REG_DESC("ar54", 0x36, XT_REG_GENERAL, 0),
237 XT_MK_REG_DESC("ar55", 0x37, XT_REG_GENERAL, 0),
238 XT_MK_REG_DESC("ar56", 0x38, XT_REG_GENERAL, 0),
239 XT_MK_REG_DESC("ar57", 0x39, XT_REG_GENERAL, 0),
240 XT_MK_REG_DESC("ar58", 0x3A, XT_REG_GENERAL, 0),
241 XT_MK_REG_DESC("ar59", 0x3B, XT_REG_GENERAL, 0),
242 XT_MK_REG_DESC("ar60", 0x3C, XT_REG_GENERAL, 0),
243 XT_MK_REG_DESC("ar61", 0x3D, XT_REG_GENERAL, 0),
244 XT_MK_REG_DESC("ar62", 0x3E, XT_REG_GENERAL, 0),
245 XT_MK_REG_DESC("ar63", 0x3F, XT_REG_GENERAL, 0),
246 XT_MK_REG_DESC("windowbase", 0x48, XT_REG_SPECIAL, 0),
247 XT_MK_REG_DESC("windowstart", 0x49, XT_REG_SPECIAL, 0),
248 XT_MK_REG_DESC("ps", 0xE6, XT_REG_SPECIAL, 0), /* PS (not mapped through EPS[]) */
249 XT_MK_REG_DESC("ibreakenable", 0x60, XT_REG_SPECIAL, 0),
250 XT_MK_REG_DESC("ddr", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD),
251 XT_MK_REG_DESC("ibreaka0", 0x80, XT_REG_SPECIAL, 0),
252 XT_MK_REG_DESC("ibreaka1", 0x81, XT_REG_SPECIAL, 0),
253 XT_MK_REG_DESC("dbreaka0", 0x90, XT_REG_SPECIAL, 0),
254 XT_MK_REG_DESC("dbreaka1", 0x91, XT_REG_SPECIAL, 0),
255 XT_MK_REG_DESC("dbreakc0", 0xA0, XT_REG_SPECIAL, 0),
256 XT_MK_REG_DESC("dbreakc1", 0xA1, XT_REG_SPECIAL, 0),
257 XT_MK_REG_DESC("cpenable", 0xE0, XT_REG_SPECIAL, 0),
258 XT_MK_REG_DESC("exccause", 0xE8, XT_REG_SPECIAL, 0),
259 XT_MK_REG_DESC("debugcause", 0xE9, XT_REG_SPECIAL, 0),
260 XT_MK_REG_DESC("icount", 0xEC, XT_REG_SPECIAL, 0),
261 XT_MK_REG_DESC("icountlevel", 0xED, XT_REG_SPECIAL, 0),
263 /* WARNING: For these registers, regnum points to the
264 * index of the corresponding ARx registers, NOT to
265 * the processor register number! */
266 XT_MK_REG_DESC("a0", XT_REG_IDX_AR0, XT_REG_RELGEN, 0),
267 XT_MK_REG_DESC("a1", XT_REG_IDX_AR1, XT_REG_RELGEN, 0),
268 XT_MK_REG_DESC("a2", XT_REG_IDX_AR2, XT_REG_RELGEN, 0),
269 XT_MK_REG_DESC("a3", XT_REG_IDX_AR3, XT_REG_RELGEN, 0),
270 XT_MK_REG_DESC("a4", XT_REG_IDX_AR4, XT_REG_RELGEN, 0),
271 XT_MK_REG_DESC("a5", XT_REG_IDX_AR5, XT_REG_RELGEN, 0),
272 XT_MK_REG_DESC("a6", XT_REG_IDX_AR6, XT_REG_RELGEN, 0),
273 XT_MK_REG_DESC("a7", XT_REG_IDX_AR7, XT_REG_RELGEN, 0),
274 XT_MK_REG_DESC("a8", XT_REG_IDX_AR8, XT_REG_RELGEN, 0),
275 XT_MK_REG_DESC("a9", XT_REG_IDX_AR9, XT_REG_RELGEN, 0),
276 XT_MK_REG_DESC("a10", XT_REG_IDX_AR10, XT_REG_RELGEN, 0),
277 XT_MK_REG_DESC("a11", XT_REG_IDX_AR11, XT_REG_RELGEN, 0),
278 XT_MK_REG_DESC("a12", XT_REG_IDX_AR12, XT_REG_RELGEN, 0),
279 XT_MK_REG_DESC("a13", XT_REG_IDX_AR13, XT_REG_RELGEN, 0),
280 XT_MK_REG_DESC("a14", XT_REG_IDX_AR14, XT_REG_RELGEN, 0),
281 XT_MK_REG_DESC("a15", XT_REG_IDX_AR15, XT_REG_RELGEN, 0),
285 * Types of memory used at xtensa target
287 enum xtensa_mem_region_type {
288 XTENSA_MEM_REG_IROM = 0x0,
289 XTENSA_MEM_REG_IRAM,
290 XTENSA_MEM_REG_DROM,
291 XTENSA_MEM_REG_DRAM,
292 XTENSA_MEM_REG_SRAM,
293 XTENSA_MEM_REG_SROM,
294 XTENSA_MEM_REGS_NUM
297 /* Register definition as union for list allocation */
298 union xtensa_reg_val_u {
299 xtensa_reg_val_t val;
300 uint8_t buf[4];
303 const struct xtensa_keyval_info_s xt_qerr[XT_QERR_NUM] = {
304 { .chrval = "E00", .intval = ERROR_FAIL },
305 { .chrval = "E01", .intval = ERROR_FAIL },
306 { .chrval = "E02", .intval = ERROR_COMMAND_ARGUMENT_INVALID },
307 { .chrval = "E03", .intval = ERROR_FAIL },
310 /* Set to true for extra debug logging */
311 static const bool xtensa_extra_debug_log;
314 * Gets a config for the specific mem type
316 static inline const struct xtensa_local_mem_config *xtensa_get_mem_config(
317 struct xtensa *xtensa,
318 enum xtensa_mem_region_type type)
320 switch (type) {
321 case XTENSA_MEM_REG_IROM:
322 return &xtensa->core_config->irom;
323 case XTENSA_MEM_REG_IRAM:
324 return &xtensa->core_config->iram;
325 case XTENSA_MEM_REG_DROM:
326 return &xtensa->core_config->drom;
327 case XTENSA_MEM_REG_DRAM:
328 return &xtensa->core_config->dram;
329 case XTENSA_MEM_REG_SRAM:
330 return &xtensa->core_config->sram;
331 case XTENSA_MEM_REG_SROM:
332 return &xtensa->core_config->srom;
333 default:
334 return NULL;
339 * Extracts an exact xtensa_local_mem_region_config from xtensa_local_mem_config
340 * for a given address
341 * Returns NULL if nothing found
343 static inline const struct xtensa_local_mem_region_config *xtensa_memory_region_find(
344 const struct xtensa_local_mem_config *mem,
345 target_addr_t address)
347 for (unsigned int i = 0; i < mem->count; i++) {
348 const struct xtensa_local_mem_region_config *region = &mem->regions[i];
349 if (address >= region->base && address < (region->base + region->size))
350 return region;
352 return NULL;
356 * Returns a corresponding xtensa_local_mem_region_config from the xtensa target
357 * for a given address
358 * Returns NULL if nothing found
360 static inline const struct xtensa_local_mem_region_config *xtensa_target_memory_region_find(
361 struct xtensa *xtensa,
362 target_addr_t address)
364 const struct xtensa_local_mem_region_config *result;
365 const struct xtensa_local_mem_config *mcgf;
366 for (unsigned int mtype = 0; mtype < XTENSA_MEM_REGS_NUM; mtype++) {
367 mcgf = xtensa_get_mem_config(xtensa, mtype);
368 result = xtensa_memory_region_find(mcgf, address);
369 if (result)
370 return result;
372 return NULL;
375 static inline bool xtensa_is_cacheable(const struct xtensa_cache_config *cache,
376 const struct xtensa_local_mem_config *mem,
377 target_addr_t address)
379 if (!cache->size)
380 return false;
381 return xtensa_memory_region_find(mem, address);
384 static inline bool xtensa_is_icacheable(struct xtensa *xtensa, target_addr_t address)
386 return xtensa_is_cacheable(&xtensa->core_config->icache, &xtensa->core_config->iram, address) ||
387 xtensa_is_cacheable(&xtensa->core_config->icache, &xtensa->core_config->irom, address) ||
388 xtensa_is_cacheable(&xtensa->core_config->icache, &xtensa->core_config->sram, address) ||
389 xtensa_is_cacheable(&xtensa->core_config->icache, &xtensa->core_config->srom, address);
392 static inline bool xtensa_is_dcacheable(struct xtensa *xtensa, target_addr_t address)
394 return xtensa_is_cacheable(&xtensa->core_config->dcache, &xtensa->core_config->dram, address) ||
395 xtensa_is_cacheable(&xtensa->core_config->dcache, &xtensa->core_config->drom, address) ||
396 xtensa_is_cacheable(&xtensa->core_config->dcache, &xtensa->core_config->sram, address) ||
397 xtensa_is_cacheable(&xtensa->core_config->dcache, &xtensa->core_config->srom, address);
400 static int xtensa_core_reg_get(struct reg *reg)
402 /* We don't need this because we read all registers on halt anyway. */
403 struct xtensa *xtensa = (struct xtensa *)reg->arch_info;
404 struct target *target = xtensa->target;
406 if (target->state != TARGET_HALTED)
407 return ERROR_TARGET_NOT_HALTED;
408 if (!reg->exist) {
409 if (strncmp(reg->name, "?0x", 3) == 0) {
410 unsigned int regnum = strtoul(reg->name + 1, 0, 0);
411 LOG_WARNING("Read unknown register 0x%04x ignored", regnum);
412 return ERROR_OK;
414 return ERROR_COMMAND_ARGUMENT_INVALID;
416 return ERROR_OK;
419 static int xtensa_core_reg_set(struct reg *reg, uint8_t *buf)
421 struct xtensa *xtensa = (struct xtensa *)reg->arch_info;
422 struct target *target = xtensa->target;
424 assert(reg->size <= 64 && "up to 64-bit regs are supported only!");
425 if (target->state != TARGET_HALTED)
426 return ERROR_TARGET_NOT_HALTED;
428 if (!reg->exist) {
429 if (strncmp(reg->name, "?0x", 3) == 0) {
430 unsigned int regnum = strtoul(reg->name + 1, 0, 0);
431 LOG_WARNING("Write unknown register 0x%04x ignored", regnum);
432 return ERROR_OK;
434 return ERROR_COMMAND_ARGUMENT_INVALID;
437 buf_cpy(buf, reg->value, reg->size);
439 if (xtensa->core_config->windowed) {
440 /* If the user updates a potential scratch register, track for conflicts */
441 for (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++) {
442 if (strcmp(reg->name, xtensa->scratch_ars[s].chrval) == 0) {
443 LOG_DEBUG("Scratch reg %s [0x%08" PRIx32 "] set from gdb", reg->name,
444 buf_get_u32(reg->value, 0, 32));
445 LOG_DEBUG("scratch_ars mapping: a3/%s, a4/%s",
446 xtensa->scratch_ars[XT_AR_SCRATCH_AR3].chrval,
447 xtensa->scratch_ars[XT_AR_SCRATCH_AR4].chrval);
448 xtensa->scratch_ars[s].intval = true;
449 break;
453 reg->dirty = true;
454 reg->valid = true;
456 return ERROR_OK;
459 static const struct reg_arch_type xtensa_reg_type = {
460 .get = xtensa_core_reg_get,
461 .set = xtensa_core_reg_set,
464 /* Convert a register index that's indexed relative to windowbase, to the real address. */
465 static enum xtensa_reg_id xtensa_windowbase_offset_to_canonical(struct xtensa *xtensa,
466 enum xtensa_reg_id reg_idx,
467 int windowbase)
469 unsigned int idx;
470 if (reg_idx >= XT_REG_IDX_AR0 && reg_idx <= XT_REG_IDX_ARLAST) {
471 idx = reg_idx - XT_REG_IDX_AR0;
472 } else if (reg_idx >= XT_REG_IDX_A0 && reg_idx <= XT_REG_IDX_A15) {
473 idx = reg_idx - XT_REG_IDX_A0;
474 } else {
475 LOG_ERROR("Error: can't convert register %d to non-windowbased register!", reg_idx);
476 return -1;
478 return ((idx + windowbase * 4) & (xtensa->core_config->aregs_num - 1)) + XT_REG_IDX_AR0;
481 static enum xtensa_reg_id xtensa_canonical_to_windowbase_offset(struct xtensa *xtensa,
482 enum xtensa_reg_id reg_idx,
483 int windowbase)
485 return xtensa_windowbase_offset_to_canonical(xtensa, reg_idx, -windowbase);
488 static void xtensa_mark_register_dirty(struct xtensa *xtensa, enum xtensa_reg_id reg_idx)
490 struct reg *reg_list = xtensa->core_cache->reg_list;
491 reg_list[reg_idx].dirty = true;
494 static void xtensa_queue_exec_ins(struct xtensa *xtensa, uint32_t ins)
496 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DIR0EXEC, ins);
499 static void xtensa_queue_exec_ins_wide(struct xtensa *xtensa, uint8_t *ops, uint8_t oplen)
501 if ((oplen > 0) && (oplen <= 64)) {
502 uint32_t opsw[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; /* 8 DIRx regs: max width 64B */
503 uint8_t oplenw = (oplen + 3) / 4;
504 if (xtensa->target->endianness == TARGET_BIG_ENDIAN)
505 buf_bswap32((uint8_t *)opsw, ops, oplenw * 4);
506 else
507 memcpy(opsw, ops, oplen);
508 for (int32_t i = oplenw - 1; i > 0; i--)
509 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DIR0 + i, opsw[i]);
510 /* Write DIR0EXEC last */
511 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DIR0EXEC, opsw[0]);
515 static int xtensa_queue_pwr_reg_write(struct xtensa *xtensa, unsigned int reg, uint32_t data)
517 struct xtensa_debug_module *dm = &xtensa->dbg_mod;
518 return dm->pwr_ops->queue_reg_write(dm, reg, data);
521 /* NOTE: Assumes A3 has already been saved */
522 int xtensa_window_state_save(struct target *target, uint32_t *woe)
524 struct xtensa *xtensa = target_to_xtensa(target);
525 int woe_dis;
526 uint8_t woe_buf[4];
528 if (xtensa->core_config->windowed) {
529 /* Save PS (LX) and disable window overflow exceptions prior to AR save */
530 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_PS, XT_REG_A3));
531 xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
532 xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, woe_buf);
533 int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
534 if (res != ERROR_OK) {
535 LOG_ERROR("Failed to read PS (%d)!", res);
536 return res;
538 xtensa_core_status_check(target);
539 *woe = buf_get_u32(woe_buf, 0, 32);
540 woe_dis = *woe & ~XT_PS_WOE_MSK;
541 LOG_DEBUG("Clearing PS.WOE (0x%08" PRIx32 " -> 0x%08" PRIx32 ")", *woe, woe_dis);
542 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, woe_dis);
543 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
544 xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_PS, XT_REG_A3));
546 return ERROR_OK;
549 /* NOTE: Assumes A3 has already been saved */
550 void xtensa_window_state_restore(struct target *target, uint32_t woe)
552 struct xtensa *xtensa = target_to_xtensa(target);
553 if (xtensa->core_config->windowed) {
554 /* Restore window overflow exception state */
555 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, woe);
556 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
557 xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_PS, XT_REG_A3));
558 LOG_DEBUG("Restored PS.WOE (0x%08" PRIx32 ")", woe);
562 static bool xtensa_reg_is_readable(int flags, int cpenable)
564 if (flags & XT_REGF_NOREAD)
565 return false;
566 if ((flags & XT_REGF_COPROC0) && (cpenable & BIT(0)) == 0)
567 return false;
568 return true;
571 static bool xtensa_scratch_regs_fixup(struct xtensa *xtensa, struct reg *reg_list, int i, int j, int a_idx, int ar_idx)
573 int a_name = (a_idx == XT_AR_SCRATCH_A3) ? 3 : 4;
574 if (xtensa->scratch_ars[a_idx].intval && !xtensa->scratch_ars[ar_idx].intval) {
575 LOG_DEBUG("AR conflict: a%d -> ar%d", a_name, j - XT_REG_IDX_AR0);
576 memcpy(reg_list[j].value, reg_list[i].value, sizeof(xtensa_reg_val_t));
577 } else {
578 LOG_DEBUG("AR conflict: ar%d -> a%d", j - XT_REG_IDX_AR0, a_name);
579 memcpy(reg_list[i].value, reg_list[j].value, sizeof(xtensa_reg_val_t));
581 return xtensa->scratch_ars[a_idx].intval && xtensa->scratch_ars[ar_idx].intval;
584 static int xtensa_write_dirty_registers(struct target *target)
586 struct xtensa *xtensa = target_to_xtensa(target);
587 int res;
588 xtensa_reg_val_t regval, windowbase = 0;
589 bool scratch_reg_dirty = false, delay_cpenable = false;
590 struct reg *reg_list = xtensa->core_cache->reg_list;
591 unsigned int reg_list_size = xtensa->core_cache->num_regs;
592 bool preserve_a3 = false;
593 uint8_t a3_buf[4];
594 xtensa_reg_val_t a3 = 0, woe;
596 LOG_TARGET_DEBUG(target, "start");
598 /* We need to write the dirty registers in the cache list back to the processor.
599 * Start by writing the SFR/user registers. */
600 for (unsigned int i = 0; i < reg_list_size; i++) {
601 struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs;
602 unsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS;
603 if (reg_list[i].dirty) {
604 if (rlist[ridx].type == XT_REG_SPECIAL ||
605 rlist[ridx].type == XT_REG_USER ||
606 rlist[ridx].type == XT_REG_FR) {
607 scratch_reg_dirty = true;
608 if (i == XT_REG_IDX_CPENABLE) {
609 delay_cpenable = true;
610 continue;
612 regval = xtensa_reg_get(target, i);
613 LOG_TARGET_DEBUG(target, "Writing back reg %s (%d) val %08" PRIX32,
614 reg_list[i].name,
615 rlist[ridx].reg_num,
616 regval);
617 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, regval);
618 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
619 if (reg_list[i].exist) {
620 unsigned int reg_num = rlist[ridx].reg_num;
621 if (rlist[ridx].type == XT_REG_USER) {
622 xtensa_queue_exec_ins(xtensa, XT_INS_WUR(xtensa, reg_num, XT_REG_A3));
623 } else if (rlist[ridx].type == XT_REG_FR) {
624 xtensa_queue_exec_ins(xtensa, XT_INS_WFR(xtensa, reg_num, XT_REG_A3));
625 } else {/*SFR */
626 if (reg_num == XT_PC_REG_NUM_VIRTUAL)
627 /* reg number of PC for debug interrupt depends on NDEBUGLEVEL
629 reg_num =
630 (XT_PC_REG_NUM_BASE +
631 xtensa->core_config->debug.irq_level);
632 xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, reg_num, XT_REG_A3));
635 reg_list[i].dirty = false;
639 if (scratch_reg_dirty)
640 xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3);
641 if (delay_cpenable) {
642 regval = xtensa_reg_get(target, XT_REG_IDX_CPENABLE);
643 LOG_TARGET_DEBUG(target, "Writing back reg cpenable (224) val %08" PRIX32, regval);
644 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, regval);
645 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
646 xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa,
647 xtensa_regs[XT_REG_IDX_CPENABLE].reg_num,
648 XT_REG_A3));
649 reg_list[XT_REG_IDX_CPENABLE].dirty = false;
652 preserve_a3 = (xtensa->core_config->windowed);
653 if (preserve_a3) {
654 /* Save (windowed) A3 for scratch use */
655 xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
656 xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, a3_buf);
657 res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
658 if (res != ERROR_OK)
659 return res;
660 xtensa_core_status_check(target);
661 a3 = buf_get_u32(a3_buf, 0, 32);
664 if (xtensa->core_config->windowed) {
665 res = xtensa_window_state_save(target, &woe);
666 if (res != ERROR_OK)
667 return res;
668 /* Grab the windowbase, we need it. */
669 windowbase = xtensa_reg_get(target, XT_REG_IDX_WINDOWBASE);
670 /* Check if there are mismatches between the ARx and corresponding Ax registers.
671 * When the user sets a register on a windowed config, xt-gdb may set the ARx
672 * register directly. Thus we take ARx as priority over Ax if both are dirty
673 * and it's unclear if the user set one over the other explicitly.
675 for (unsigned int i = XT_REG_IDX_A0; i <= XT_REG_IDX_A15; i++) {
676 unsigned int j = xtensa_windowbase_offset_to_canonical(xtensa, i, windowbase);
677 if (reg_list[i].dirty && reg_list[j].dirty) {
678 if (memcmp(reg_list[i].value, reg_list[j].value, sizeof(xtensa_reg_val_t)) != 0) {
679 bool show_warning = true;
680 if (i == XT_REG_IDX_A3)
681 show_warning = xtensa_scratch_regs_fixup(xtensa,
682 reg_list, i, j, XT_AR_SCRATCH_A3, XT_AR_SCRATCH_AR3);
683 else if (i == XT_REG_IDX_A4)
684 show_warning = xtensa_scratch_regs_fixup(xtensa,
685 reg_list, i, j, XT_AR_SCRATCH_A4, XT_AR_SCRATCH_AR4);
686 if (show_warning)
687 LOG_WARNING(
688 "Warning: Both A%d [0x%08" PRIx32
689 "] as well as its underlying physical register "
690 "(AR%d) [0x%08" PRIx32 "] are dirty and differ in value",
691 i - XT_REG_IDX_A0,
692 buf_get_u32(reg_list[i].value, 0, 32),
693 j - XT_REG_IDX_AR0,
694 buf_get_u32(reg_list[j].value, 0, 32));
700 /* Write A0-A16. */
701 for (unsigned int i = 0; i < 16; i++) {
702 if (reg_list[XT_REG_IDX_A0 + i].dirty) {
703 regval = xtensa_reg_get(target, XT_REG_IDX_A0 + i);
704 LOG_TARGET_DEBUG(target, "Writing back reg %s value %08" PRIX32 ", num =%i",
705 xtensa_regs[XT_REG_IDX_A0 + i].name,
706 regval,
707 xtensa_regs[XT_REG_IDX_A0 + i].reg_num);
708 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, regval);
709 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, i));
710 reg_list[XT_REG_IDX_A0 + i].dirty = false;
711 if (i == 3) {
712 /* Avoid stomping A3 during restore at end of function */
713 a3 = regval;
718 if (xtensa->core_config->windowed) {
719 /* Now write AR registers */
720 for (unsigned int j = 0; j < XT_REG_IDX_ARLAST; j += 16) {
721 /* Write the 16 registers we can see */
722 for (unsigned int i = 0; i < 16; i++) {
723 if (i + j < xtensa->core_config->aregs_num) {
724 enum xtensa_reg_id realadr =
725 xtensa_windowbase_offset_to_canonical(xtensa, XT_REG_IDX_AR0 + i + j,
726 windowbase);
727 /* Write back any dirty un-windowed registers */
728 if (reg_list[realadr].dirty) {
729 regval = xtensa_reg_get(target, realadr);
730 LOG_TARGET_DEBUG(
731 target,
732 "Writing back reg %s value %08" PRIX32 ", num =%i",
733 xtensa_regs[realadr].name,
734 regval,
735 xtensa_regs[realadr].reg_num);
736 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, regval);
737 xtensa_queue_exec_ins(xtensa,
738 XT_INS_RSR(xtensa, XT_SR_DDR,
739 xtensa_regs[XT_REG_IDX_AR0 + i].reg_num));
740 reg_list[realadr].dirty = false;
741 if ((i + j) == 3)
742 /* Avoid stomping AR during A3 restore at end of function */
743 a3 = regval;
747 /*Now rotate the window so we'll see the next 16 registers. The final rotate
748 * will wraparound, */
749 /*leaving us in the state we were. */
750 xtensa_queue_exec_ins(xtensa, XT_INS_ROTW(xtensa, 4));
753 xtensa_window_state_restore(target, woe);
755 for (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++)
756 xtensa->scratch_ars[s].intval = false;
759 if (preserve_a3) {
760 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, a3);
761 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
764 res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
765 xtensa_core_status_check(target);
767 return res;
770 static inline bool xtensa_is_stopped(struct target *target)
772 struct xtensa *xtensa = target_to_xtensa(target);
773 return xtensa->dbg_mod.core_status.dsr & OCDDSR_STOPPED;
776 int xtensa_examine(struct target *target)
778 struct xtensa *xtensa = target_to_xtensa(target);
779 unsigned int cmd = PWRCTL_DEBUGWAKEUP | PWRCTL_MEMWAKEUP | PWRCTL_COREWAKEUP;
781 LOG_DEBUG("coreid = %d", target->coreid);
783 if (xtensa->core_config->core_type == XT_UNDEF) {
784 LOG_ERROR("XTensa core not configured; is xtensa-core-openocd.cfg missing?");
785 return ERROR_FAIL;
788 xtensa_queue_pwr_reg_write(xtensa, XDMREG_PWRCTL, cmd);
789 xtensa_queue_pwr_reg_write(xtensa, XDMREG_PWRCTL, cmd | PWRCTL_JTAGDEBUGUSE);
790 xtensa_dm_queue_enable(&xtensa->dbg_mod);
791 xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
792 int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
793 if (res != ERROR_OK)
794 return res;
795 if (!xtensa_dm_is_online(&xtensa->dbg_mod)) {
796 LOG_ERROR("Unexpected OCD_ID = %08" PRIx32, xtensa->dbg_mod.device_id);
797 return ERROR_TARGET_FAILURE;
799 LOG_DEBUG("OCD_ID = %08" PRIx32, xtensa->dbg_mod.device_id);
800 if (!target_was_examined(target))
801 target_set_examined(target);
802 xtensa_smpbreak_write(xtensa, xtensa->smp_break);
803 return ERROR_OK;
806 int xtensa_wakeup(struct target *target)
808 struct xtensa *xtensa = target_to_xtensa(target);
809 unsigned int cmd = PWRCTL_DEBUGWAKEUP | PWRCTL_MEMWAKEUP | PWRCTL_COREWAKEUP;
811 if (xtensa->reset_asserted)
812 cmd |= PWRCTL_CORERESET;
813 xtensa_queue_pwr_reg_write(xtensa, XDMREG_PWRCTL, cmd);
814 /* TODO: can we join this with the write above? */
815 xtensa_queue_pwr_reg_write(xtensa, XDMREG_PWRCTL, cmd | PWRCTL_JTAGDEBUGUSE);
816 xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
817 return xtensa_dm_queue_execute(&xtensa->dbg_mod);
820 int xtensa_smpbreak_write(struct xtensa *xtensa, uint32_t set)
822 uint32_t dsr_data = 0x00110000;
823 uint32_t clear = (set | OCDDCR_ENABLEOCD) ^
824 (OCDDCR_BREAKINEN | OCDDCR_BREAKOUTEN | OCDDCR_RUNSTALLINEN |
825 OCDDCR_DEBUGMODEOUTEN | OCDDCR_ENABLEOCD);
827 LOG_TARGET_DEBUG(xtensa->target, "write smpbreak set=0x%" PRIx32 " clear=0x%" PRIx32, set, clear);
828 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRSET, set | OCDDCR_ENABLEOCD);
829 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRCLR, clear);
830 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DSR, dsr_data);
831 xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
832 return xtensa_dm_queue_execute(&xtensa->dbg_mod);
835 int xtensa_smpbreak_set(struct target *target, uint32_t set)
837 struct xtensa *xtensa = target_to_xtensa(target);
838 int res = ERROR_OK;
840 xtensa->smp_break = set;
841 if (target_was_examined(target))
842 res = xtensa_smpbreak_write(xtensa, xtensa->smp_break);
843 LOG_TARGET_DEBUG(target, "set smpbreak=%" PRIx32 ", state=%i", set, target->state);
844 return res;
847 int xtensa_smpbreak_read(struct xtensa *xtensa, uint32_t *val)
849 uint8_t dcr_buf[sizeof(uint32_t)];
851 xtensa_queue_dbg_reg_read(xtensa, XDMREG_DCRSET, dcr_buf);
852 xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
853 int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
854 *val = buf_get_u32(dcr_buf, 0, 32);
856 return res;
859 int xtensa_smpbreak_get(struct target *target, uint32_t *val)
861 struct xtensa *xtensa = target_to_xtensa(target);
862 *val = xtensa->smp_break;
863 return ERROR_OK;
866 static inline xtensa_reg_val_t xtensa_reg_get_value(struct reg *reg)
868 return buf_get_u32(reg->value, 0, 32);
871 static inline void xtensa_reg_set_value(struct reg *reg, xtensa_reg_val_t value)
873 buf_set_u32(reg->value, 0, 32, value);
874 reg->dirty = true;
877 int xtensa_core_status_check(struct target *target)
879 struct xtensa *xtensa = target_to_xtensa(target);
880 int res, needclear = 0;
882 xtensa_dm_core_status_read(&xtensa->dbg_mod);
883 xtensa_dsr_t dsr = xtensa_dm_core_status_get(&xtensa->dbg_mod);
884 LOG_TARGET_DEBUG(target, "DSR (%08" PRIX32 ")", dsr);
885 if (dsr & OCDDSR_EXECBUSY) {
886 if (!xtensa->suppress_dsr_errors)
887 LOG_TARGET_ERROR(target, "DSR (%08" PRIX32 ") indicates target still busy!", dsr);
888 needclear = 1;
890 if (dsr & OCDDSR_EXECEXCEPTION) {
891 if (!xtensa->suppress_dsr_errors)
892 LOG_TARGET_ERROR(target,
893 "DSR (%08" PRIX32 ") indicates DIR instruction generated an exception!",
894 dsr);
895 needclear = 1;
897 if (dsr & OCDDSR_EXECOVERRUN) {
898 if (!xtensa->suppress_dsr_errors)
899 LOG_TARGET_ERROR(target,
900 "DSR (%08" PRIX32 ") indicates DIR instruction generated an overrun!",
901 dsr);
902 needclear = 1;
904 if (needclear) {
905 res = xtensa_dm_core_status_clear(&xtensa->dbg_mod,
906 OCDDSR_EXECEXCEPTION | OCDDSR_EXECOVERRUN);
907 if (res != ERROR_OK && !xtensa->suppress_dsr_errors)
908 LOG_TARGET_ERROR(target, "clearing DSR failed!");
909 return ERROR_FAIL;
911 return ERROR_OK;
914 xtensa_reg_val_t xtensa_reg_get(struct target *target, enum xtensa_reg_id reg_id)
916 struct xtensa *xtensa = target_to_xtensa(target);
917 struct reg *reg = &xtensa->core_cache->reg_list[reg_id];
918 return xtensa_reg_get_value(reg);
921 void xtensa_reg_set(struct target *target, enum xtensa_reg_id reg_id, xtensa_reg_val_t value)
923 struct xtensa *xtensa = target_to_xtensa(target);
924 struct reg *reg = &xtensa->core_cache->reg_list[reg_id];
925 if (xtensa_reg_get_value(reg) == value)
926 return;
927 xtensa_reg_set_value(reg, value);
930 /* Set Ax (XT_REG_RELGEN) register along with its underlying ARx (XT_REG_GENERAL) */
931 void xtensa_reg_set_deep_relgen(struct target *target, enum xtensa_reg_id a_idx, xtensa_reg_val_t value)
933 struct xtensa *xtensa = target_to_xtensa(target);
934 uint32_t windowbase = (xtensa->core_config->windowed ?
935 xtensa_reg_get(target, XT_REG_IDX_WINDOWBASE) : 0);
936 int ar_idx = xtensa_windowbase_offset_to_canonical(xtensa, a_idx, windowbase);
937 xtensa_reg_set(target, a_idx, value);
938 xtensa_reg_set(target, ar_idx, value);
941 /* Read cause for entering halted state; return bitmask in DEBUGCAUSE_* format */
942 uint32_t xtensa_cause_get(struct target *target)
944 return xtensa_reg_get(target, XT_REG_IDX_DEBUGCAUSE);
947 void xtensa_cause_clear(struct target *target)
949 struct xtensa *xtensa = target_to_xtensa(target);
950 xtensa_reg_set(target, XT_REG_IDX_DEBUGCAUSE, 0);
951 xtensa->core_cache->reg_list[XT_REG_IDX_DEBUGCAUSE].dirty = false;
954 int xtensa_assert_reset(struct target *target)
956 struct xtensa *xtensa = target_to_xtensa(target);
958 LOG_TARGET_DEBUG(target, "target_number=%i, begin", target->target_number);
959 target->state = TARGET_RESET;
960 xtensa_queue_pwr_reg_write(xtensa,
961 XDMREG_PWRCTL,
962 PWRCTL_JTAGDEBUGUSE | PWRCTL_DEBUGWAKEUP | PWRCTL_MEMWAKEUP |
963 PWRCTL_COREWAKEUP | PWRCTL_CORERESET);
964 xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
965 int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
966 if (res != ERROR_OK)
967 return res;
968 xtensa->reset_asserted = true;
969 return res;
972 int xtensa_deassert_reset(struct target *target)
974 struct xtensa *xtensa = target_to_xtensa(target);
976 LOG_TARGET_DEBUG(target, "halt=%d", target->reset_halt);
977 if (target->reset_halt)
978 xtensa_queue_dbg_reg_write(xtensa,
979 XDMREG_DCRSET,
980 OCDDCR_ENABLEOCD | OCDDCR_DEBUGINTERRUPT);
981 xtensa_queue_pwr_reg_write(xtensa,
982 XDMREG_PWRCTL,
983 PWRCTL_JTAGDEBUGUSE | PWRCTL_DEBUGWAKEUP | PWRCTL_MEMWAKEUP |
984 PWRCTL_COREWAKEUP);
985 xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
986 int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
987 if (res != ERROR_OK)
988 return res;
989 target->state = TARGET_RUNNING;
990 xtensa->reset_asserted = false;
991 return res;
994 int xtensa_soft_reset_halt(struct target *target)
996 LOG_TARGET_DEBUG(target, "begin");
997 return xtensa_assert_reset(target);
1000 int xtensa_fetch_all_regs(struct target *target)
1002 struct xtensa *xtensa = target_to_xtensa(target);
1003 struct reg *reg_list = xtensa->core_cache->reg_list;
1004 unsigned int reg_list_size = xtensa->core_cache->num_regs;
1005 xtensa_reg_val_t cpenable = 0, windowbase = 0, a3;
1006 uint32_t woe;
1007 uint8_t a3_buf[4];
1008 bool debug_dsrs = !xtensa->regs_fetched || LOG_LEVEL_IS(LOG_LVL_DEBUG);
1010 union xtensa_reg_val_u *regvals = calloc(reg_list_size, sizeof(*regvals));
1011 if (!regvals) {
1012 LOG_TARGET_ERROR(target, "unable to allocate memory for regvals!");
1013 return ERROR_FAIL;
1015 union xtensa_reg_val_u *dsrs = calloc(reg_list_size, sizeof(*dsrs));
1016 if (!dsrs) {
1017 LOG_TARGET_ERROR(target, "unable to allocate memory for dsrs!");
1018 free(regvals);
1019 return ERROR_FAIL;
1022 LOG_TARGET_DEBUG(target, "start");
1024 /* Save (windowed) A3 so cache matches physical AR3; A3 usable as scratch */
1025 xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
1026 xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, a3_buf);
1027 int res = xtensa_window_state_save(target, &woe);
1028 if (res != ERROR_OK)
1029 goto xtensa_fetch_all_regs_done;
1031 /* Assume the CPU has just halted. We now want to fill the register cache with all the
1032 * register contents GDB needs. For speed, we pipeline all the read operations, execute them
1033 * in one go, then sort everything out from the regvals variable. */
1035 /* Start out with AREGS; we can reach those immediately. Grab them per 16 registers. */
1036 for (unsigned int j = 0; j < XT_AREGS_NUM_MAX; j += 16) {
1037 /*Grab the 16 registers we can see */
1038 for (unsigned int i = 0; i < 16; i++) {
1039 if (i + j < xtensa->core_config->aregs_num) {
1040 xtensa_queue_exec_ins(xtensa,
1041 XT_INS_WSR(xtensa, XT_SR_DDR, xtensa_regs[XT_REG_IDX_AR0 + i].reg_num));
1042 xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR,
1043 regvals[XT_REG_IDX_AR0 + i + j].buf);
1044 if (debug_dsrs)
1045 xtensa_queue_dbg_reg_read(xtensa, XDMREG_DSR,
1046 dsrs[XT_REG_IDX_AR0 + i + j].buf);
1049 if (xtensa->core_config->windowed)
1050 /* Now rotate the window so we'll see the next 16 registers. The final rotate
1051 * will wraparound, */
1052 /* leaving us in the state we were. */
1053 xtensa_queue_exec_ins(xtensa, XT_INS_ROTW(xtensa, 4));
1055 xtensa_window_state_restore(target, woe);
1057 if (xtensa->core_config->coproc) {
1058 /* As the very first thing after AREGS, go grab CPENABLE */
1059 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, xtensa_regs[XT_REG_IDX_CPENABLE].reg_num, XT_REG_A3));
1060 xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
1061 xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, regvals[XT_REG_IDX_CPENABLE].buf);
1063 res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
1064 if (res != ERROR_OK) {
1065 LOG_ERROR("Failed to read ARs (%d)!", res);
1066 goto xtensa_fetch_all_regs_done;
1068 xtensa_core_status_check(target);
1070 a3 = buf_get_u32(a3_buf, 0, 32);
1072 if (xtensa->core_config->coproc) {
1073 cpenable = buf_get_u32(regvals[XT_REG_IDX_CPENABLE].buf, 0, 32);
1075 /* Enable all coprocessors (by setting all bits in CPENABLE) so we can read FP and user registers. */
1076 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, 0xffffffff);
1077 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
1078 xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, xtensa_regs[XT_REG_IDX_CPENABLE].reg_num, XT_REG_A3));
1080 /* Save CPENABLE; flag dirty later (when regcache updated) so original value is always restored */
1081 LOG_TARGET_DEBUG(target, "CPENABLE: was 0x%" PRIx32 ", all enabled", cpenable);
1082 xtensa_reg_set(target, XT_REG_IDX_CPENABLE, cpenable);
1084 /* We're now free to use any of A0-A15 as scratch registers
1085 * Grab the SFRs and user registers first. We use A3 as a scratch register. */
1086 for (unsigned int i = 0; i < reg_list_size; i++) {
1087 struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs;
1088 unsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS;
1089 if (xtensa_reg_is_readable(rlist[ridx].flags, cpenable) && rlist[ridx].exist) {
1090 bool reg_fetched = true;
1091 unsigned int reg_num = rlist[ridx].reg_num;
1092 switch (rlist[ridx].type) {
1093 case XT_REG_USER:
1094 xtensa_queue_exec_ins(xtensa, XT_INS_RUR(xtensa, reg_num, XT_REG_A3));
1095 break;
1096 case XT_REG_FR:
1097 xtensa_queue_exec_ins(xtensa, XT_INS_RFR(xtensa, reg_num, XT_REG_A3));
1098 break;
1099 case XT_REG_SPECIAL:
1100 if (reg_num == XT_PC_REG_NUM_VIRTUAL) {
1101 /* reg number of PC for debug interrupt depends on NDEBUGLEVEL */
1102 reg_num = (XT_PC_REG_NUM_BASE + xtensa->core_config->debug.irq_level);
1103 } else if (reg_num == xtensa_regs[XT_REG_IDX_CPENABLE].reg_num) {
1104 /* CPENABLE already read/updated; don't re-read */
1105 reg_fetched = false;
1106 break;
1108 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, reg_num, XT_REG_A3));
1109 break;
1110 default:
1111 reg_fetched = false;
1113 if (reg_fetched) {
1114 xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
1115 xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, regvals[i].buf);
1116 if (debug_dsrs)
1117 xtensa_queue_dbg_reg_read(xtensa, XDMREG_DSR, dsrs[i].buf);
1121 /* Ok, send the whole mess to the CPU. */
1122 res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
1123 if (res != ERROR_OK) {
1124 LOG_ERROR("Failed to fetch AR regs!");
1125 goto xtensa_fetch_all_regs_done;
1127 xtensa_core_status_check(target);
1129 if (debug_dsrs) {
1130 /* DSR checking: follows order in which registers are requested. */
1131 for (unsigned int i = 0; i < reg_list_size; i++) {
1132 struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs;
1133 unsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS;
1134 if (xtensa_reg_is_readable(rlist[ridx].flags, cpenable) && rlist[ridx].exist &&
1135 (rlist[ridx].type != XT_REG_DEBUG) &&
1136 (rlist[ridx].type != XT_REG_RELGEN) &&
1137 (rlist[ridx].type != XT_REG_TIE) &&
1138 (rlist[ridx].type != XT_REG_OTHER)) {
1139 if (buf_get_u32(dsrs[i].buf, 0, 32) & OCDDSR_EXECEXCEPTION) {
1140 LOG_ERROR("Exception reading %s!", reg_list[i].name);
1141 res = ERROR_FAIL;
1142 goto xtensa_fetch_all_regs_done;
1148 if (xtensa->core_config->windowed)
1149 /* We need the windowbase to decode the general addresses. */
1150 windowbase = buf_get_u32(regvals[XT_REG_IDX_WINDOWBASE].buf, 0, 32);
1151 /* Decode the result and update the cache. */
1152 for (unsigned int i = 0; i < reg_list_size; i++) {
1153 struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs;
1154 unsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS;
1155 if (xtensa_reg_is_readable(rlist[ridx].flags, cpenable) && rlist[ridx].exist) {
1156 if ((xtensa->core_config->windowed) && (rlist[ridx].type == XT_REG_GENERAL)) {
1157 /* The 64-value general register set is read from (windowbase) on down.
1158 * We need to get the real register address by subtracting windowbase and
1159 * wrapping around. */
1160 enum xtensa_reg_id realadr = xtensa_canonical_to_windowbase_offset(xtensa, i,
1161 windowbase);
1162 buf_cpy(regvals[realadr].buf, reg_list[i].value, reg_list[i].size);
1163 } else if (rlist[ridx].type == XT_REG_RELGEN) {
1164 buf_cpy(regvals[rlist[ridx].reg_num].buf, reg_list[i].value, reg_list[i].size);
1165 if (xtensa_extra_debug_log) {
1166 xtensa_reg_val_t regval = buf_get_u32(regvals[rlist[ridx].reg_num].buf, 0, 32);
1167 LOG_DEBUG("%s = 0x%x", rlist[ridx].name, regval);
1169 } else {
1170 xtensa_reg_val_t regval = buf_get_u32(regvals[i].buf, 0, 32);
1171 bool is_dirty = (i == XT_REG_IDX_CPENABLE);
1172 if (xtensa_extra_debug_log)
1173 LOG_INFO("Register %s: 0x%X", reg_list[i].name, regval);
1174 xtensa_reg_set(target, i, regval);
1175 reg_list[i].dirty = is_dirty; /*always do this _after_ xtensa_reg_set! */
1177 reg_list[i].valid = true;
1178 } else {
1179 if ((rlist[ridx].flags & XT_REGF_MASK) == XT_REGF_NOREAD) {
1180 /* Report read-only registers all-zero but valid */
1181 reg_list[i].valid = true;
1182 xtensa_reg_set(target, i, 0);
1183 } else {
1184 reg_list[i].valid = false;
1189 if (xtensa->core_config->windowed) {
1190 /* We have used A3 as a scratch register.
1191 * Windowed configs: restore A3's AR (XT_REG_GENERAL) and and flag for write-back.
1193 enum xtensa_reg_id ar3_idx = xtensa_windowbase_offset_to_canonical(xtensa, XT_REG_IDX_A3, windowbase);
1194 xtensa_reg_set(target, ar3_idx, a3);
1195 xtensa_mark_register_dirty(xtensa, ar3_idx);
1197 /* Reset scratch_ars[] on fetch. .chrval tracks AR mapping and changes w/ window */
1198 sprintf(xtensa->scratch_ars[XT_AR_SCRATCH_AR3].chrval, "ar%d", ar3_idx - XT_REG_IDX_AR0);
1199 enum xtensa_reg_id ar4_idx = xtensa_windowbase_offset_to_canonical(xtensa, XT_REG_IDX_A4, windowbase);
1200 sprintf(xtensa->scratch_ars[XT_AR_SCRATCH_AR4].chrval, "ar%d", ar4_idx - XT_REG_IDX_AR0);
1201 for (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++)
1202 xtensa->scratch_ars[s].intval = false;
1205 /* We have used A3 (XT_REG_RELGEN) as a scratch register. Restore and flag for write-back. */
1206 xtensa_reg_set(target, XT_REG_IDX_A3, a3);
1207 xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3);
1208 xtensa->regs_fetched = true;
1209 xtensa_fetch_all_regs_done:
1210 free(regvals);
1211 free(dsrs);
1212 return res;
1215 int xtensa_get_gdb_reg_list(struct target *target,
1216 struct reg **reg_list[],
1217 int *reg_list_size,
1218 enum target_register_class reg_class)
1220 struct xtensa *xtensa = target_to_xtensa(target);
1221 unsigned int num_regs;
1223 if (reg_class == REG_CLASS_GENERAL) {
1224 if ((xtensa->genpkt_regs_num == 0) || !xtensa->contiguous_regs_list) {
1225 LOG_ERROR("reg_class %d unhandled; 'xtgregs' not found", reg_class);
1226 return ERROR_FAIL;
1228 num_regs = xtensa->genpkt_regs_num;
1229 } else {
1230 /* Determine whether to return a contiguous or sparse register map */
1231 num_regs = xtensa->regmap_contiguous ? xtensa->total_regs_num : xtensa->dbregs_num;
1234 LOG_DEBUG("reg_class=%i, num_regs=%d", (int)reg_class, num_regs);
1236 *reg_list = calloc(num_regs, sizeof(struct reg *));
1237 if (!*reg_list)
1238 return ERROR_FAIL;
1240 *reg_list_size = num_regs;
1241 if (xtensa->regmap_contiguous) {
1242 assert((num_regs <= xtensa->total_regs_num) && "contiguous regmap size internal error!");
1243 for (unsigned int i = 0; i < num_regs; i++)
1244 (*reg_list)[i] = xtensa->contiguous_regs_list[i];
1245 return ERROR_OK;
1248 for (unsigned int i = 0; i < num_regs; i++)
1249 (*reg_list)[i] = (struct reg *)&xtensa->empty_regs[i];
1250 unsigned int k = 0;
1251 for (unsigned int i = 0; i < xtensa->core_cache->num_regs && k < num_regs; i++) {
1252 if (xtensa->core_cache->reg_list[i].exist) {
1253 struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs;
1254 unsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS;
1255 int sparse_idx = rlist[ridx].dbreg_num;
1256 if (i == XT_REG_IDX_PS) {
1257 if (xtensa->eps_dbglevel_idx == 0) {
1258 LOG_ERROR("eps_dbglevel_idx not set\n");
1259 return ERROR_FAIL;
1261 (*reg_list)[sparse_idx] = &xtensa->core_cache->reg_list[xtensa->eps_dbglevel_idx];
1262 if (xtensa_extra_debug_log)
1263 LOG_DEBUG("SPARSE GDB reg 0x%x getting EPS%d 0x%x",
1264 sparse_idx, xtensa->core_config->debug.irq_level,
1265 xtensa_reg_get_value((*reg_list)[sparse_idx]));
1266 } else if (rlist[ridx].type == XT_REG_RELGEN) {
1267 (*reg_list)[sparse_idx - XT_REG_IDX_ARFIRST] = &xtensa->core_cache->reg_list[i];
1268 } else {
1269 (*reg_list)[sparse_idx] = &xtensa->core_cache->reg_list[i];
1271 if (i == XT_REG_IDX_PC)
1272 /* Make a duplicate copy of PC for external access */
1273 (*reg_list)[XT_PC_DBREG_NUM_BASE] = &xtensa->core_cache->reg_list[i];
1274 k++;
1278 if (k == num_regs)
1279 LOG_ERROR("SPARSE GDB reg list full (size %d)", k);
1281 return ERROR_OK;
1284 int xtensa_mmu_is_enabled(struct target *target, int *enabled)
1286 struct xtensa *xtensa = target_to_xtensa(target);
1287 *enabled = xtensa->core_config->mmu.itlb_entries_count > 0 ||
1288 xtensa->core_config->mmu.dtlb_entries_count > 0;
1289 return ERROR_OK;
1292 int xtensa_halt(struct target *target)
1294 struct xtensa *xtensa = target_to_xtensa(target);
1296 LOG_TARGET_DEBUG(target, "start");
1297 if (target->state == TARGET_HALTED) {
1298 LOG_TARGET_DEBUG(target, "target was already halted");
1299 return ERROR_OK;
1301 /* First we have to read dsr and check if the target stopped */
1302 int res = xtensa_dm_core_status_read(&xtensa->dbg_mod);
1303 if (res != ERROR_OK) {
1304 LOG_TARGET_ERROR(target, "Failed to read core status!");
1305 return res;
1307 LOG_TARGET_DEBUG(target, "Core status 0x%" PRIx32, xtensa_dm_core_status_get(&xtensa->dbg_mod));
1308 if (!xtensa_is_stopped(target)) {
1309 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRSET, OCDDCR_ENABLEOCD | OCDDCR_DEBUGINTERRUPT);
1310 xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
1311 res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
1312 if (res != ERROR_OK)
1313 LOG_TARGET_ERROR(target, "Failed to set OCDDCR_DEBUGINTERRUPT. Can't halt.");
1316 return res;
1319 int xtensa_prepare_resume(struct target *target,
1320 int current,
1321 target_addr_t address,
1322 int handle_breakpoints,
1323 int debug_execution)
1325 struct xtensa *xtensa = target_to_xtensa(target);
1326 uint32_t bpena = 0;
1328 LOG_TARGET_DEBUG(target,
1329 "current=%d address=" TARGET_ADDR_FMT ", handle_breakpoints=%i, debug_execution=%i)",
1330 current,
1331 address,
1332 handle_breakpoints,
1333 debug_execution);
1335 if (target->state != TARGET_HALTED) {
1336 LOG_TARGET_WARNING(target, "target not halted");
1337 return ERROR_TARGET_NOT_HALTED;
1340 if (address && !current) {
1341 xtensa_reg_set(target, XT_REG_IDX_PC, address);
1342 } else {
1343 uint32_t cause = xtensa_cause_get(target);
1344 LOG_TARGET_DEBUG(target, "DEBUGCAUSE 0x%x (watchpoint %lu) (break %lu)",
1345 cause, (cause & DEBUGCAUSE_DB), (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN)));
1346 if (cause & DEBUGCAUSE_DB)
1347 /* We stopped due to a watchpoint. We can't just resume executing the
1348 * instruction again because */
1349 /* that would trigger the watchpoint again. To fix this, we single-step,
1350 * which ignores watchpoints. */
1351 xtensa_do_step(target, current, address, handle_breakpoints);
1352 if (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN))
1353 /* We stopped due to a break instruction. We can't just resume executing the
1354 * instruction again because */
1355 /* that would trigger the break again. To fix this, we single-step, which
1356 * ignores break. */
1357 xtensa_do_step(target, current, address, handle_breakpoints);
1360 /* Write back hw breakpoints. Current FreeRTOS SMP code can set a hw breakpoint on an
1361 * exception; we need to clear that and return to the breakpoints gdb has set on resume. */
1362 for (unsigned int slot = 0; slot < xtensa->core_config->debug.ibreaks_num; slot++) {
1363 if (xtensa->hw_brps[slot]) {
1364 /* Write IBREAKA[slot] and set bit #slot in IBREAKENABLE */
1365 xtensa_reg_set(target, XT_REG_IDX_IBREAKA0 + slot, xtensa->hw_brps[slot]->address);
1366 bpena |= BIT(slot);
1369 xtensa_reg_set(target, XT_REG_IDX_IBREAKENABLE, bpena);
1371 /* Here we write all registers to the targets */
1372 int res = xtensa_write_dirty_registers(target);
1373 if (res != ERROR_OK)
1374 LOG_TARGET_ERROR(target, "Failed to write back register cache.");
1375 return res;
1378 int xtensa_do_resume(struct target *target)
1380 struct xtensa *xtensa = target_to_xtensa(target);
1382 LOG_TARGET_DEBUG(target, "start");
1384 xtensa_queue_exec_ins(xtensa, XT_INS_RFDO(xtensa));
1385 int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
1386 if (res != ERROR_OK) {
1387 LOG_TARGET_ERROR(target, "Failed to exec RFDO %d!", res);
1388 return res;
1390 xtensa_core_status_check(target);
1391 return ERROR_OK;
1394 int xtensa_resume(struct target *target,
1395 int current,
1396 target_addr_t address,
1397 int handle_breakpoints,
1398 int debug_execution)
1400 LOG_TARGET_DEBUG(target, "start");
1401 int res = xtensa_prepare_resume(target, current, address, handle_breakpoints, debug_execution);
1402 if (res != ERROR_OK) {
1403 LOG_TARGET_ERROR(target, "Failed to prepare for resume!");
1404 return res;
1406 res = xtensa_do_resume(target);
1407 if (res != ERROR_OK) {
1408 LOG_TARGET_ERROR(target, "Failed to resume!");
1409 return res;
1412 target->debug_reason = DBG_REASON_NOTHALTED;
1413 if (!debug_execution)
1414 target->state = TARGET_RUNNING;
1415 else
1416 target->state = TARGET_DEBUG_RUNNING;
1418 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1420 return ERROR_OK;
1423 static bool xtensa_pc_in_winexc(struct target *target, target_addr_t pc)
1425 struct xtensa *xtensa = target_to_xtensa(target);
1426 uint8_t insn_buf[XT_ISNS_SZ_MAX];
1427 int err = xtensa_read_buffer(target, pc, sizeof(insn_buf), insn_buf);
1428 if (err != ERROR_OK)
1429 return false;
1431 xtensa_insn_t insn = buf_get_u32(insn_buf, 0, 24);
1432 xtensa_insn_t masked = insn & XT_INS_L32E_S32E_MASK(xtensa);
1433 if (masked == XT_INS_L32E(xtensa, 0, 0, 0) || masked == XT_INS_S32E(xtensa, 0, 0, 0))
1434 return true;
1436 masked = insn & XT_INS_RFWO_RFWU_MASK(xtensa);
1437 if (masked == XT_INS_RFWO(xtensa) || masked == XT_INS_RFWU(xtensa))
1438 return true;
1440 return false;
1443 int xtensa_do_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)
1445 struct xtensa *xtensa = target_to_xtensa(target);
1446 int res;
1447 const uint32_t icount_val = -2; /* ICOUNT value to load for 1 step */
1448 xtensa_reg_val_t dbreakc[XT_WATCHPOINTS_NUM_MAX];
1449 xtensa_reg_val_t icountlvl, cause;
1450 xtensa_reg_val_t oldps, oldpc, cur_pc;
1451 bool ps_lowered = false;
1453 LOG_TARGET_DEBUG(target, "current=%d, address=" TARGET_ADDR_FMT ", handle_breakpoints=%i",
1454 current, address, handle_breakpoints);
1456 if (target->state != TARGET_HALTED) {
1457 LOG_TARGET_WARNING(target, "target not halted");
1458 return ERROR_TARGET_NOT_HALTED;
1461 if (xtensa->eps_dbglevel_idx == 0) {
1462 LOG_ERROR("eps_dbglevel_idx not set\n");
1463 return ERROR_FAIL;
1466 /* Save old ps (EPS[dbglvl] on LX), pc */
1467 oldps = xtensa_reg_get(target, xtensa->eps_dbglevel_idx);
1468 oldpc = xtensa_reg_get(target, XT_REG_IDX_PC);
1470 cause = xtensa_cause_get(target);
1471 LOG_TARGET_DEBUG(target, "oldps=%" PRIx32 ", oldpc=%" PRIx32 " dbg_cause=%" PRIx32 " exc_cause=%" PRIx32,
1472 oldps,
1473 oldpc,
1474 cause,
1475 xtensa_reg_get(target, XT_REG_IDX_EXCCAUSE));
1476 if (handle_breakpoints && (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN))) {
1477 /* handle hard-coded SW breakpoints (e.g. syscalls) */
1478 LOG_TARGET_DEBUG(target, "Increment PC to pass break instruction...");
1479 xtensa_cause_clear(target); /* so we don't recurse into the same routine */
1480 /* pretend that we have stepped */
1481 if (cause & DEBUGCAUSE_BI)
1482 xtensa_reg_set(target, XT_REG_IDX_PC, oldpc + 3); /* PC = PC+3 */
1483 else
1484 xtensa_reg_set(target, XT_REG_IDX_PC, oldpc + 2); /* PC = PC+2 */
1485 return ERROR_OK;
1488 /* Xtensa LX has an ICOUNTLEVEL register which sets the maximum interrupt level
1489 * at which the instructions are to be counted while stepping.
1491 * For example, if we need to step by 2 instructions, and an interrupt occurs
1492 * in between, the processor will trigger the interrupt and halt after the 2nd
1493 * instruction within the interrupt vector and/or handler.
1495 * However, sometimes we don't want the interrupt handlers to be executed at all
1496 * while stepping through the code. In this case (XT_STEPPING_ISR_OFF),
1497 * ICOUNTLEVEL can be lowered to the executing code's (level + 1) to prevent ISR
1498 * code from being counted during stepping. Note that C exception handlers must
1499 * run at level 0 and hence will be counted and stepped into, should one occur.
1501 * TODO: Certain instructions should never be single-stepped and should instead
1502 * be emulated (per DUG): RSIL >= DBGLEVEL, RSR/WSR [ICOUNT|ICOUNTLEVEL], and
1503 * RFI >= DBGLEVEL.
1505 if (xtensa->stepping_isr_mode == XT_STEPPING_ISR_OFF) {
1506 if (!xtensa->core_config->high_irq.enabled) {
1507 LOG_TARGET_WARNING(
1508 target,
1509 "disabling IRQs while stepping is not implemented w/o high prio IRQs option!");
1510 return ERROR_FAIL;
1512 /* Update ICOUNTLEVEL accordingly */
1513 icountlvl = MIN((oldps & 0xF) + 1, xtensa->core_config->debug.irq_level);
1514 } else {
1515 icountlvl = xtensa->core_config->debug.irq_level;
1518 if (cause & DEBUGCAUSE_DB) {
1519 /* We stopped due to a watchpoint. We can't just resume executing the instruction again because
1520 * that would trigger the watchpoint again. To fix this, we remove watchpoints,single-step and
1521 * re-enable the watchpoint. */
1522 LOG_TARGET_DEBUG(
1523 target,
1524 "Single-stepping to get past instruction that triggered the watchpoint...");
1525 xtensa_cause_clear(target); /* so we don't recurse into the same routine */
1526 /* Save all DBREAKCx registers and set to 0 to disable watchpoints */
1527 for (unsigned int slot = 0; slot < xtensa->core_config->debug.dbreaks_num; slot++) {
1528 dbreakc[slot] = xtensa_reg_get(target, XT_REG_IDX_DBREAKC0 + slot);
1529 xtensa_reg_set(target, XT_REG_IDX_DBREAKC0 + slot, 0);
1533 if (!handle_breakpoints && (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN)))
1534 /* handle normal SW breakpoint */
1535 xtensa_cause_clear(target); /* so we don't recurse into the same routine */
1536 if ((oldps & 0xf) >= icountlvl) {
1537 /* Lower interrupt level to allow stepping, but flag eps[dbglvl] to be restored */
1538 ps_lowered = true;
1539 uint32_t newps = (oldps & ~0xf) | (icountlvl - 1);
1540 xtensa_reg_set(target, xtensa->eps_dbglevel_idx, newps);
1541 LOG_TARGET_DEBUG(target,
1542 "Lowering PS.INTLEVEL to allow stepping: %s <- 0x%08" PRIx32 " (was 0x%08" PRIx32 ")",
1543 xtensa->core_cache->reg_list[xtensa->eps_dbglevel_idx].name,
1544 newps,
1545 oldps);
1547 do {
1548 xtensa_reg_set(target, XT_REG_IDX_ICOUNTLEVEL, icountlvl);
1549 xtensa_reg_set(target, XT_REG_IDX_ICOUNT, icount_val);
1551 /* Now ICOUNT is set, we can resume as if we were going to run */
1552 res = xtensa_prepare_resume(target, current, address, 0, 0);
1553 if (res != ERROR_OK) {
1554 LOG_TARGET_ERROR(target, "Failed to prepare resume for single step");
1555 return res;
1557 res = xtensa_do_resume(target);
1558 if (res != ERROR_OK) {
1559 LOG_TARGET_ERROR(target, "Failed to resume after setting up single step");
1560 return res;
1563 /* Wait for stepping to complete */
1564 long long start = timeval_ms();
1565 while (timeval_ms() < start + 500) {
1566 /* Do not use target_poll here, it also triggers other things... just manually read the DSR
1567 *until stepping is complete. */
1568 usleep(1000);
1569 res = xtensa_dm_core_status_read(&xtensa->dbg_mod);
1570 if (res != ERROR_OK) {
1571 LOG_TARGET_ERROR(target, "Failed to read core status!");
1572 return res;
1574 if (xtensa_is_stopped(target))
1575 break;
1576 usleep(1000);
1578 LOG_TARGET_DEBUG(target, "Finish stepping. dsr=0x%08" PRIx32,
1579 xtensa_dm_core_status_get(&xtensa->dbg_mod));
1580 if (!xtensa_is_stopped(target)) {
1581 LOG_TARGET_WARNING(
1582 target,
1583 "Timed out waiting for target to finish stepping. dsr=0x%08" PRIx32,
1584 xtensa_dm_core_status_get(&xtensa->dbg_mod));
1585 target->debug_reason = DBG_REASON_NOTHALTED;
1586 target->state = TARGET_RUNNING;
1587 return ERROR_FAIL;
1589 target->debug_reason = DBG_REASON_SINGLESTEP;
1590 target->state = TARGET_HALTED;
1592 xtensa_fetch_all_regs(target);
1594 cur_pc = xtensa_reg_get(target, XT_REG_IDX_PC);
1596 LOG_TARGET_DEBUG(target,
1597 "cur_ps=%" PRIx32 ", cur_pc=%" PRIx32 " dbg_cause=%" PRIx32 " exc_cause=%" PRIx32,
1598 xtensa_reg_get(target, XT_REG_IDX_PS),
1599 cur_pc,
1600 xtensa_cause_get(target),
1601 xtensa_reg_get(target, XT_REG_IDX_EXCCAUSE));
1603 /* Do not step into WindowOverflow if ISRs are masked.
1604 If we stop in WindowOverflow at breakpoint with masked ISRs and
1605 try to do a step it will get us out of that handler */
1606 if (xtensa->core_config->windowed &&
1607 xtensa->stepping_isr_mode == XT_STEPPING_ISR_OFF &&
1608 xtensa_pc_in_winexc(target, cur_pc)) {
1609 /* isrmask = on, need to step out of the window exception handler */
1610 LOG_DEBUG("Stepping out of window exception, PC=%" PRIX32, cur_pc);
1611 oldpc = cur_pc;
1612 address = oldpc + 3;
1613 continue;
1616 if (oldpc == cur_pc)
1617 LOG_TARGET_WARNING(target, "Stepping doesn't seem to change PC! dsr=0x%08" PRIx32,
1618 xtensa_dm_core_status_get(&xtensa->dbg_mod));
1619 else
1620 LOG_DEBUG("Stepped from %" PRIX32 " to %" PRIX32, oldpc, cur_pc);
1621 break;
1622 } while (true);
1623 LOG_DEBUG("Done stepping, PC=%" PRIX32, cur_pc);
1625 if (cause & DEBUGCAUSE_DB) {
1626 LOG_TARGET_DEBUG(target, "...Done, re-installing watchpoints.");
1627 /* Restore the DBREAKCx registers */
1628 for (unsigned int slot = 0; slot < xtensa->core_config->debug.dbreaks_num; slot++)
1629 xtensa_reg_set(target, XT_REG_IDX_DBREAKC0 + slot, dbreakc[slot]);
1632 /* Restore int level */
1633 if (ps_lowered) {
1634 LOG_DEBUG("Restoring %s after stepping: 0x%08" PRIx32,
1635 xtensa->core_cache->reg_list[xtensa->eps_dbglevel_idx].name,
1636 oldps);
1637 xtensa_reg_set(target, xtensa->eps_dbglevel_idx, oldps);
1640 /* write ICOUNTLEVEL back to zero */
1641 xtensa_reg_set(target, XT_REG_IDX_ICOUNTLEVEL, 0);
1642 /* TODO: can we skip writing dirty registers and re-fetching them? */
1643 res = xtensa_write_dirty_registers(target);
1644 xtensa_fetch_all_regs(target);
1645 return res;
1648 int xtensa_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)
1650 return xtensa_do_step(target, current, address, handle_breakpoints);
1654 * Returns true if two ranges are overlapping
1656 static inline bool xtensa_memory_regions_overlap(target_addr_t r1_start,
1657 target_addr_t r1_end,
1658 target_addr_t r2_start,
1659 target_addr_t r2_end)
1661 if ((r2_start >= r1_start) && (r2_start < r1_end))
1662 return true; /* r2_start is in r1 region */
1663 if ((r2_end > r1_start) && (r2_end <= r1_end))
1664 return true; /* r2_end is in r1 region */
1665 return false;
1669 * Returns a size of overlapped region of two ranges.
1671 static inline target_addr_t xtensa_get_overlap_size(target_addr_t r1_start,
1672 target_addr_t r1_end,
1673 target_addr_t r2_start,
1674 target_addr_t r2_end)
1676 if (xtensa_memory_regions_overlap(r1_start, r1_end, r2_start, r2_end)) {
1677 target_addr_t ov_start = r1_start < r2_start ? r2_start : r1_start;
1678 target_addr_t ov_end = r1_end > r2_end ? r2_end : r1_end;
1679 return ov_end - ov_start;
1681 return 0;
1685 * Check if the address gets to memory regions, and its access mode
1687 static bool xtensa_memory_op_validate_range(struct xtensa *xtensa, target_addr_t address, size_t size, int access)
1689 target_addr_t adr_pos = address; /* address cursor set to the beginning start */
1690 target_addr_t adr_end = address + size; /* region end */
1691 target_addr_t overlap_size;
1692 const struct xtensa_local_mem_region_config *cm; /* current mem region */
1694 while (adr_pos < adr_end) {
1695 cm = xtensa_target_memory_region_find(xtensa, adr_pos);
1696 if (!cm) /* address is not belong to anything */
1697 return false;
1698 if ((cm->access & access) != access) /* access check */
1699 return false;
1700 overlap_size = xtensa_get_overlap_size(cm->base, (cm->base + cm->size), adr_pos, adr_end);
1701 assert(overlap_size != 0);
1702 adr_pos += overlap_size;
1704 return true;
1707 int xtensa_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
1709 struct xtensa *xtensa = target_to_xtensa(target);
1710 /* We are going to read memory in 32-bit increments. This may not be what the calling
1711 * function expects, so we may need to allocate a temp buffer and read into that first. */
1712 target_addr_t addrstart_al = ALIGN_DOWN(address, 4);
1713 target_addr_t addrend_al = ALIGN_UP(address + size * count, 4);
1714 target_addr_t adr = addrstart_al;
1715 uint8_t *albuff;
1716 bool bswap = xtensa->target->endianness == TARGET_BIG_ENDIAN;
1718 if (target->state != TARGET_HALTED) {
1719 LOG_TARGET_WARNING(target, "target not halted");
1720 return ERROR_TARGET_NOT_HALTED;
1723 if (!xtensa->permissive_mode) {
1724 if (!xtensa_memory_op_validate_range(xtensa, address, (size * count),
1725 XT_MEM_ACCESS_READ)) {
1726 LOG_DEBUG("address " TARGET_ADDR_FMT " not readable", address);
1727 return ERROR_FAIL;
1731 if (addrstart_al == address && addrend_al == address + (size * count)) {
1732 albuff = buffer;
1733 } else {
1734 albuff = malloc(addrend_al - addrstart_al);
1735 if (!albuff) {
1736 LOG_TARGET_ERROR(target, "Out of memory allocating %" TARGET_PRIdADDR " bytes!",
1737 addrend_al - addrstart_al);
1738 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1742 /* We're going to use A3 here */
1743 xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3);
1744 /* Write start address to A3 */
1745 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addrstart_al);
1746 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
1747 /* Now we can safely read data from addrstart_al up to addrend_al into albuff */
1748 if (xtensa->probe_lsddr32p != 0) {
1749 xtensa_queue_exec_ins(xtensa, XT_INS_LDDR32P(xtensa, XT_REG_A3));
1750 for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t))
1751 xtensa_queue_dbg_reg_read(xtensa,
1752 (adr + sizeof(uint32_t) == addrend_al) ? XDMREG_DDR : XDMREG_DDREXEC,
1753 &albuff[i]);
1754 } else {
1755 xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A4);
1756 for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) {
1757 xtensa_queue_exec_ins(xtensa, XT_INS_L32I(xtensa, XT_REG_A3, XT_REG_A4, 0));
1758 xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A4));
1759 xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, &albuff[i]);
1760 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, adr + sizeof(uint32_t));
1761 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
1764 int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
1765 if (res == ERROR_OK) {
1766 bool prev_suppress = xtensa->suppress_dsr_errors;
1767 xtensa->suppress_dsr_errors = true;
1768 res = xtensa_core_status_check(target);
1769 if (xtensa->probe_lsddr32p == -1)
1770 xtensa->probe_lsddr32p = 1;
1771 xtensa->suppress_dsr_errors = prev_suppress;
1773 if (res != ERROR_OK) {
1774 if (xtensa->probe_lsddr32p != 0) {
1775 /* Disable fast memory access instructions and retry before reporting an error */
1776 LOG_TARGET_INFO(target, "Disabling LDDR32.P/SDDR32.P");
1777 xtensa->probe_lsddr32p = 0;
1778 res = xtensa_read_memory(target, address, size, count, buffer);
1779 bswap = false;
1780 } else {
1781 LOG_TARGET_WARNING(target, "Failed reading %d bytes at address "TARGET_ADDR_FMT,
1782 count * size, address);
1786 if (bswap)
1787 buf_bswap32(albuff, albuff, addrend_al - addrstart_al);
1788 if (albuff != buffer) {
1789 memcpy(buffer, albuff + (address & 3), (size * count));
1790 free(albuff);
1793 return res;
1796 int xtensa_read_buffer(struct target *target, target_addr_t address, uint32_t count, uint8_t *buffer)
1798 /* xtensa_read_memory can also read unaligned stuff. Just pass through to that routine. */
1799 return xtensa_read_memory(target, address, 1, count, buffer);
1802 int xtensa_write_memory(struct target *target,
1803 target_addr_t address,
1804 uint32_t size,
1805 uint32_t count,
1806 const uint8_t *buffer)
1808 /* This memory write function can get thrown nigh everything into it, from
1809 * aligned uint32 writes to unaligned uint8ths. The Xtensa memory doesn't always
1810 * accept anything but aligned uint32 writes, though. That is why we convert
1811 * everything into that. */
1812 struct xtensa *xtensa = target_to_xtensa(target);
1813 target_addr_t addrstart_al = ALIGN_DOWN(address, 4);
1814 target_addr_t addrend_al = ALIGN_UP(address + size * count, 4);
1815 target_addr_t adr = addrstart_al;
1816 int res;
1817 uint8_t *albuff;
1818 bool fill_head_tail = false;
1820 if (target->state != TARGET_HALTED) {
1821 LOG_TARGET_WARNING(target, "target not halted");
1822 return ERROR_TARGET_NOT_HALTED;
1825 if (!xtensa->permissive_mode) {
1826 if (!xtensa_memory_op_validate_range(xtensa, address, (size * count), XT_MEM_ACCESS_WRITE)) {
1827 LOG_WARNING("address " TARGET_ADDR_FMT " not writable", address);
1828 return ERROR_FAIL;
1832 if (size == 0 || count == 0 || !buffer)
1833 return ERROR_COMMAND_SYNTAX_ERROR;
1835 /* Allocate a temporary buffer to put the aligned bytes in, if needed. */
1836 if (addrstart_al == address && addrend_al == address + (size * count)) {
1837 if (xtensa->target->endianness == TARGET_BIG_ENDIAN)
1838 /* Need a buffer for byte-swapping */
1839 albuff = malloc(addrend_al - addrstart_al);
1840 else
1841 /* We discard the const here because albuff can also be non-const */
1842 albuff = (uint8_t *)buffer;
1843 } else {
1844 fill_head_tail = true;
1845 albuff = malloc(addrend_al - addrstart_al);
1847 if (!albuff) {
1848 LOG_TARGET_ERROR(target, "Out of memory allocating %" TARGET_PRIdADDR " bytes!",
1849 addrend_al - addrstart_al);
1850 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1853 /* We're going to use A3 here */
1854 xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3);
1856 /* If we're using a temp aligned buffer, we need to fill the head and/or tail bit of it. */
1857 if (fill_head_tail) {
1858 /* See if we need to read the first and/or last word. */
1859 if (address & 3) {
1860 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addrstart_al);
1861 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
1862 if (xtensa->probe_lsddr32p == 1) {
1863 xtensa_queue_exec_ins(xtensa, XT_INS_LDDR32P(xtensa, XT_REG_A3));
1864 } else {
1865 xtensa_queue_exec_ins(xtensa, XT_INS_L32I(xtensa, XT_REG_A3, XT_REG_A3, 0));
1866 xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
1868 xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, &albuff[0]);
1870 if ((address + (size * count)) & 3) {
1871 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addrend_al - 4);
1872 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
1873 if (xtensa->probe_lsddr32p == 1) {
1874 xtensa_queue_exec_ins(xtensa, XT_INS_LDDR32P(xtensa, XT_REG_A3));
1875 } else {
1876 xtensa_queue_exec_ins(xtensa, XT_INS_L32I(xtensa, XT_REG_A3, XT_REG_A3, 0));
1877 xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
1879 xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR,
1880 &albuff[addrend_al - addrstart_al - 4]);
1882 /* Grab bytes */
1883 res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
1884 if (res != ERROR_OK) {
1885 LOG_ERROR("Error issuing unaligned memory write context instruction(s): %d", res);
1886 if (albuff != buffer)
1887 free(albuff);
1888 return res;
1890 xtensa_core_status_check(target);
1891 if (xtensa->target->endianness == TARGET_BIG_ENDIAN) {
1892 bool swapped_w0 = false;
1893 if (address & 3) {
1894 buf_bswap32(&albuff[0], &albuff[0], 4);
1895 swapped_w0 = true;
1897 if ((address + (size * count)) & 3) {
1898 if ((addrend_al - addrstart_al - 4 == 0) && swapped_w0) {
1899 /* Don't double-swap if buffer start/end are within the same word */
1900 } else {
1901 buf_bswap32(&albuff[addrend_al - addrstart_al - 4],
1902 &albuff[addrend_al - addrstart_al - 4], 4);
1906 /* Copy data to be written into the aligned buffer (in host-endianness) */
1907 memcpy(&albuff[address & 3], buffer, size * count);
1908 /* Now we can write albuff in aligned uint32s. */
1911 if (xtensa->target->endianness == TARGET_BIG_ENDIAN)
1912 buf_bswap32(albuff, fill_head_tail ? albuff : buffer, addrend_al - addrstart_al);
1914 /* Write start address to A3 */
1915 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addrstart_al);
1916 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
1917 /* Write the aligned buffer */
1918 if (xtensa->probe_lsddr32p != 0) {
1919 for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) {
1920 if (i == 0) {
1921 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, buf_get_u32(&albuff[i], 0, 32));
1922 xtensa_queue_exec_ins(xtensa, XT_INS_SDDR32P(xtensa, XT_REG_A3));
1923 } else {
1924 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDREXEC, buf_get_u32(&albuff[i], 0, 32));
1927 } else {
1928 xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A4);
1929 for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) {
1930 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, buf_get_u32(&albuff[i], 0, 32));
1931 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A4));
1932 xtensa_queue_exec_ins(xtensa, XT_INS_S32I(xtensa, XT_REG_A3, XT_REG_A4, 0));
1933 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, adr + sizeof(uint32_t));
1934 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
1938 res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
1939 if (res == ERROR_OK) {
1940 bool prev_suppress = xtensa->suppress_dsr_errors;
1941 xtensa->suppress_dsr_errors = true;
1942 res = xtensa_core_status_check(target);
1943 if (xtensa->probe_lsddr32p == -1)
1944 xtensa->probe_lsddr32p = 1;
1945 xtensa->suppress_dsr_errors = prev_suppress;
1947 if (res != ERROR_OK) {
1948 if (xtensa->probe_lsddr32p != 0) {
1949 /* Disable fast memory access instructions and retry before reporting an error */
1950 LOG_TARGET_INFO(target, "Disabling LDDR32.P/SDDR32.P");
1951 xtensa->probe_lsddr32p = 0;
1952 res = xtensa_write_memory(target, address, size, count, buffer);
1953 } else {
1954 LOG_TARGET_WARNING(target, "Failed writing %d bytes at address "TARGET_ADDR_FMT,
1955 count * size, address);
1957 } else {
1958 /* Invalidate ICACHE, writeback DCACHE if present */
1959 uint32_t issue_ihi = xtensa_is_icacheable(xtensa, address);
1960 uint32_t issue_dhwb = xtensa_is_dcacheable(xtensa, address);
1961 if (issue_ihi || issue_dhwb) {
1962 uint32_t ilinesize = issue_ihi ? xtensa->core_config->icache.line_size : UINT32_MAX;
1963 uint32_t dlinesize = issue_dhwb ? xtensa->core_config->dcache.line_size : UINT32_MAX;
1964 uint32_t linesize = MIN(ilinesize, dlinesize);
1965 uint32_t off = 0;
1966 adr = addrstart_al;
1968 while ((adr + off) < addrend_al) {
1969 if (off == 0) {
1970 /* Write start address to A3 */
1971 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, adr);
1972 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
1974 if (issue_ihi)
1975 xtensa_queue_exec_ins(xtensa, XT_INS_IHI(xtensa, XT_REG_A3, off));
1976 if (issue_dhwb)
1977 xtensa_queue_exec_ins(xtensa, XT_INS_DHWBI(xtensa, XT_REG_A3, off));
1978 off += linesize;
1979 if (off > 1020) {
1980 /* IHI, DHWB have 8-bit immediate operands (0..1020) */
1981 adr += off;
1982 off = 0;
1986 /* Execute cache WB/INV instructions */
1987 res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
1988 xtensa_core_status_check(target);
1989 if (res != ERROR_OK)
1990 LOG_TARGET_ERROR(target,
1991 "Error issuing cache writeback/invaldate instruction(s): %d",
1992 res);
1995 if (albuff != buffer)
1996 free(albuff);
1998 return res;
2001 int xtensa_write_buffer(struct target *target, target_addr_t address, uint32_t count, const uint8_t *buffer)
2003 /* xtensa_write_memory can handle everything. Just pass on to that. */
2004 return xtensa_write_memory(target, address, 1, count, buffer);
2007 int xtensa_checksum_memory(struct target *target, target_addr_t address, uint32_t count, uint32_t *checksum)
2009 LOG_WARNING("not implemented yet");
2010 return ERROR_FAIL;
2013 int xtensa_poll(struct target *target)
2015 struct xtensa *xtensa = target_to_xtensa(target);
2017 int res = xtensa_dm_power_status_read(&xtensa->dbg_mod, PWRSTAT_DEBUGWASRESET |
2018 PWRSTAT_COREWASRESET);
2019 if (xtensa->dbg_mod.power_status.stat != xtensa->dbg_mod.power_status.stath)
2020 LOG_TARGET_DEBUG(target, "PWRSTAT: read 0x%08" PRIx32 ", clear 0x%08lx, reread 0x%08" PRIx32,
2021 xtensa->dbg_mod.power_status.stat,
2022 PWRSTAT_DEBUGWASRESET | PWRSTAT_COREWASRESET,
2023 xtensa->dbg_mod.power_status.stath);
2024 if (res != ERROR_OK)
2025 return res;
2027 if (xtensa_dm_tap_was_reset(&xtensa->dbg_mod)) {
2028 LOG_TARGET_INFO(target, "Debug controller was reset.");
2029 res = xtensa_smpbreak_write(xtensa, xtensa->smp_break);
2030 if (res != ERROR_OK)
2031 return res;
2033 if (xtensa_dm_core_was_reset(&xtensa->dbg_mod))
2034 LOG_TARGET_INFO(target, "Core was reset.");
2035 xtensa_dm_power_status_cache(&xtensa->dbg_mod);
2036 /* Enable JTAG, set reset if needed */
2037 res = xtensa_wakeup(target);
2038 if (res != ERROR_OK)
2039 return res;
2041 uint32_t prev_dsr = xtensa->dbg_mod.core_status.dsr;
2042 res = xtensa_dm_core_status_read(&xtensa->dbg_mod);
2043 if (res != ERROR_OK)
2044 return res;
2045 if (prev_dsr != xtensa->dbg_mod.core_status.dsr)
2046 LOG_TARGET_DEBUG(target,
2047 "DSR has changed: was 0x%08" PRIx32 " now 0x%08" PRIx32,
2048 prev_dsr,
2049 xtensa->dbg_mod.core_status.dsr);
2050 if (xtensa->dbg_mod.power_status.stath & PWRSTAT_COREWASRESET) {
2051 /* if RESET state is persitent */
2052 target->state = TARGET_RESET;
2053 } else if (!xtensa_dm_is_powered(&xtensa->dbg_mod)) {
2054 LOG_TARGET_DEBUG(target, "not powered 0x%" PRIX32 "%ld",
2055 xtensa->dbg_mod.core_status.dsr,
2056 xtensa->dbg_mod.core_status.dsr & OCDDSR_STOPPED);
2057 target->state = TARGET_UNKNOWN;
2058 if (xtensa->come_online_probes_num == 0)
2059 target->examined = false;
2060 else
2061 xtensa->come_online_probes_num--;
2062 } else if (xtensa_is_stopped(target)) {
2063 if (target->state != TARGET_HALTED) {
2064 enum target_state oldstate = target->state;
2065 target->state = TARGET_HALTED;
2066 /* Examine why the target has been halted */
2067 target->debug_reason = DBG_REASON_DBGRQ;
2068 xtensa_fetch_all_regs(target);
2069 /* When setting debug reason DEBUGCAUSE events have the following
2070 * priorities: watchpoint == breakpoint > single step > debug interrupt. */
2071 /* Watchpoint and breakpoint events at the same time results in special
2072 * debug reason: DBG_REASON_WPTANDBKPT. */
2073 uint32_t halt_cause = xtensa_cause_get(target);
2074 /* TODO: Add handling of DBG_REASON_EXC_CATCH */
2075 if (halt_cause & DEBUGCAUSE_IC)
2076 target->debug_reason = DBG_REASON_SINGLESTEP;
2077 if (halt_cause & (DEBUGCAUSE_IB | DEBUGCAUSE_BN | DEBUGCAUSE_BI)) {
2078 if (halt_cause & DEBUGCAUSE_DB)
2079 target->debug_reason = DBG_REASON_WPTANDBKPT;
2080 else
2081 target->debug_reason = DBG_REASON_BREAKPOINT;
2082 } else if (halt_cause & DEBUGCAUSE_DB) {
2083 target->debug_reason = DBG_REASON_WATCHPOINT;
2085 LOG_TARGET_DEBUG(target, "Target halted, pc=0x%08" PRIx32
2086 ", debug_reason=%08" PRIx32 ", oldstate=%08" PRIx32,
2087 xtensa_reg_get(target, XT_REG_IDX_PC),
2088 target->debug_reason,
2089 oldstate);
2090 LOG_TARGET_DEBUG(target, "Halt reason=0x%08" PRIX32 ", exc_cause=%" PRId32 ", dsr=0x%08" PRIx32,
2091 halt_cause,
2092 xtensa_reg_get(target, XT_REG_IDX_EXCCAUSE),
2093 xtensa->dbg_mod.core_status.dsr);
2094 xtensa_dm_core_status_clear(
2095 &xtensa->dbg_mod,
2096 OCDDSR_DEBUGPENDBREAK | OCDDSR_DEBUGINTBREAK | OCDDSR_DEBUGPENDTRAX |
2097 OCDDSR_DEBUGINTTRAX |
2098 OCDDSR_DEBUGPENDHOST | OCDDSR_DEBUGINTHOST);
2100 } else {
2101 target->debug_reason = DBG_REASON_NOTHALTED;
2102 if (target->state != TARGET_RUNNING && target->state != TARGET_DEBUG_RUNNING) {
2103 target->state = TARGET_RUNNING;
2104 target->debug_reason = DBG_REASON_NOTHALTED;
2107 if (xtensa->trace_active) {
2108 /* Detect if tracing was active but has stopped. */
2109 struct xtensa_trace_status trace_status;
2110 res = xtensa_dm_trace_status_read(&xtensa->dbg_mod, &trace_status);
2111 if (res == ERROR_OK) {
2112 if (!(trace_status.stat & TRAXSTAT_TRACT)) {
2113 LOG_INFO("Detected end of trace.");
2114 if (trace_status.stat & TRAXSTAT_PCMTG)
2115 LOG_TARGET_INFO(target, "Trace stop triggered by PC match");
2116 if (trace_status.stat & TRAXSTAT_PTITG)
2117 LOG_TARGET_INFO(target, "Trace stop triggered by Processor Trigger Input");
2118 if (trace_status.stat & TRAXSTAT_CTITG)
2119 LOG_TARGET_INFO(target, "Trace stop triggered by Cross-trigger Input");
2120 xtensa->trace_active = false;
2124 return ERROR_OK;
2127 static int xtensa_update_instruction(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
2129 struct xtensa *xtensa = target_to_xtensa(target);
2130 unsigned int issue_ihi = xtensa_is_icacheable(xtensa, address);
2131 unsigned int issue_dhwbi = xtensa_is_dcacheable(xtensa, address);
2132 uint32_t icache_line_size = issue_ihi ? xtensa->core_config->icache.line_size : UINT32_MAX;
2133 uint32_t dcache_line_size = issue_dhwbi ? xtensa->core_config->dcache.line_size : UINT32_MAX;
2134 unsigned int same_ic_line = ((address & (icache_line_size - 1)) + size) <= icache_line_size;
2135 unsigned int same_dc_line = ((address & (dcache_line_size - 1)) + size) <= dcache_line_size;
2136 int ret;
2138 if (size > icache_line_size)
2139 return ERROR_FAIL;
2141 if (issue_ihi || issue_dhwbi) {
2142 /* We're going to use A3 here */
2143 xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3);
2145 /* Write start address to A3 and invalidate */
2146 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, address);
2147 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
2148 LOG_TARGET_DEBUG(target, "DHWBI, IHI for address "TARGET_ADDR_FMT, address);
2149 if (issue_dhwbi) {
2150 xtensa_queue_exec_ins(xtensa, XT_INS_DHWBI(xtensa, XT_REG_A3, 0));
2151 if (!same_dc_line) {
2152 LOG_TARGET_DEBUG(target,
2153 "DHWBI second dcache line for address "TARGET_ADDR_FMT,
2154 address + 4);
2155 xtensa_queue_exec_ins(xtensa, XT_INS_DHWBI(xtensa, XT_REG_A3, 4));
2158 if (issue_ihi) {
2159 xtensa_queue_exec_ins(xtensa, XT_INS_IHI(xtensa, XT_REG_A3, 0));
2160 if (!same_ic_line) {
2161 LOG_TARGET_DEBUG(target,
2162 "IHI second icache line for address "TARGET_ADDR_FMT,
2163 address + 4);
2164 xtensa_queue_exec_ins(xtensa, XT_INS_IHI(xtensa, XT_REG_A3, 4));
2168 /* Execute invalidate instructions */
2169 ret = xtensa_dm_queue_execute(&xtensa->dbg_mod);
2170 xtensa_core_status_check(target);
2171 if (ret != ERROR_OK) {
2172 LOG_ERROR("Error issuing cache invaldate instruction(s): %d", ret);
2173 return ret;
2177 /* Write new instructions to memory */
2178 ret = target_write_buffer(target, address, size, buffer);
2179 if (ret != ERROR_OK) {
2180 LOG_TARGET_ERROR(target, "Error writing instruction to memory: %d", ret);
2181 return ret;
2184 if (issue_dhwbi) {
2185 /* Flush dcache so instruction propagates. A3 may be corrupted during memory write */
2186 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, address);
2187 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
2188 xtensa_queue_exec_ins(xtensa, XT_INS_DHWB(xtensa, XT_REG_A3, 0));
2189 LOG_DEBUG("DHWB dcache line for address "TARGET_ADDR_FMT, address);
2190 if (!same_dc_line) {
2191 LOG_TARGET_DEBUG(target, "DHWB second dcache line for address "TARGET_ADDR_FMT, address + 4);
2192 xtensa_queue_exec_ins(xtensa, XT_INS_DHWB(xtensa, XT_REG_A3, 4));
2195 /* Execute invalidate instructions */
2196 ret = xtensa_dm_queue_execute(&xtensa->dbg_mod);
2197 xtensa_core_status_check(target);
2200 /* TODO: Handle L2 cache if present */
2201 return ret;
2204 static int xtensa_sw_breakpoint_add(struct target *target,
2205 struct breakpoint *breakpoint,
2206 struct xtensa_sw_breakpoint *sw_bp)
2208 struct xtensa *xtensa = target_to_xtensa(target);
2209 int ret = target_read_buffer(target, breakpoint->address, XT_ISNS_SZ_MAX, sw_bp->insn);
2210 if (ret != ERROR_OK) {
2211 LOG_TARGET_ERROR(target, "Failed to read original instruction (%d)!", ret);
2212 return ret;
2215 sw_bp->insn_sz = MIN(XT_ISNS_SZ_MAX, breakpoint->length);
2216 sw_bp->oocd_bp = breakpoint;
2218 uint32_t break_insn = sw_bp->insn_sz == XT_ISNS_SZ_MAX ? XT_INS_BREAK(xtensa, 0, 0) : XT_INS_BREAKN(xtensa, 0);
2220 /* Underlying memory write will convert instruction endianness, don't do that here */
2221 ret = xtensa_update_instruction(target, breakpoint->address, sw_bp->insn_sz, (uint8_t *)&break_insn);
2222 if (ret != ERROR_OK) {
2223 LOG_TARGET_ERROR(target, "Failed to write breakpoint instruction (%d)!", ret);
2224 return ret;
2227 return ERROR_OK;
2230 static int xtensa_sw_breakpoint_remove(struct target *target, struct xtensa_sw_breakpoint *sw_bp)
2232 int ret = xtensa_update_instruction(target, sw_bp->oocd_bp->address, sw_bp->insn_sz, sw_bp->insn);
2233 if (ret != ERROR_OK) {
2234 LOG_TARGET_ERROR(target, "Failed to write insn (%d)!", ret);
2235 return ret;
2237 sw_bp->oocd_bp = NULL;
2238 return ERROR_OK;
2241 int xtensa_breakpoint_add(struct target *target, struct breakpoint *breakpoint)
2243 struct xtensa *xtensa = target_to_xtensa(target);
2244 unsigned int slot;
2246 if (breakpoint->type == BKPT_SOFT) {
2247 for (slot = 0; slot < XT_SW_BREAKPOINTS_MAX_NUM; slot++) {
2248 if (!xtensa->sw_brps[slot].oocd_bp ||
2249 xtensa->sw_brps[slot].oocd_bp == breakpoint)
2250 break;
2252 if (slot == XT_SW_BREAKPOINTS_MAX_NUM) {
2253 LOG_TARGET_WARNING(target, "No free slots to add SW breakpoint!");
2254 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2256 int ret = xtensa_sw_breakpoint_add(target, breakpoint, &xtensa->sw_brps[slot]);
2257 if (ret != ERROR_OK) {
2258 LOG_TARGET_ERROR(target, "Failed to add SW breakpoint!");
2259 return ret;
2261 LOG_TARGET_DEBUG(target, "placed SW breakpoint %u @ " TARGET_ADDR_FMT,
2262 slot,
2263 breakpoint->address);
2264 return ERROR_OK;
2267 for (slot = 0; slot < xtensa->core_config->debug.ibreaks_num; slot++) {
2268 if (!xtensa->hw_brps[slot] || xtensa->hw_brps[slot] == breakpoint)
2269 break;
2271 if (slot == xtensa->core_config->debug.ibreaks_num) {
2272 LOG_TARGET_ERROR(target, "No free slots to add HW breakpoint!");
2273 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2276 xtensa->hw_brps[slot] = breakpoint;
2277 /* We will actually write the breakpoints when we resume the target. */
2278 LOG_TARGET_DEBUG(target, "placed HW breakpoint %u @ " TARGET_ADDR_FMT,
2279 slot,
2280 breakpoint->address);
2282 return ERROR_OK;
2285 int xtensa_breakpoint_remove(struct target *target, struct breakpoint *breakpoint)
2287 struct xtensa *xtensa = target_to_xtensa(target);
2288 unsigned int slot;
2290 if (breakpoint->type == BKPT_SOFT) {
2291 for (slot = 0; slot < XT_SW_BREAKPOINTS_MAX_NUM; slot++) {
2292 if (xtensa->sw_brps[slot].oocd_bp && xtensa->sw_brps[slot].oocd_bp == breakpoint)
2293 break;
2295 if (slot == XT_SW_BREAKPOINTS_MAX_NUM) {
2296 LOG_TARGET_WARNING(target, "Max SW breakpoints slot reached, slot=%u!", slot);
2297 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2299 int ret = xtensa_sw_breakpoint_remove(target, &xtensa->sw_brps[slot]);
2300 if (ret != ERROR_OK) {
2301 LOG_TARGET_ERROR(target, "Failed to remove SW breakpoint (%d)!", ret);
2302 return ret;
2304 LOG_TARGET_DEBUG(target, "cleared SW breakpoint %u @ " TARGET_ADDR_FMT, slot, breakpoint->address);
2305 return ERROR_OK;
2308 for (slot = 0; slot < xtensa->core_config->debug.ibreaks_num; slot++) {
2309 if (xtensa->hw_brps[slot] == breakpoint)
2310 break;
2312 if (slot == xtensa->core_config->debug.ibreaks_num) {
2313 LOG_TARGET_ERROR(target, "HW breakpoint not found!");
2314 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2316 xtensa->hw_brps[slot] = NULL;
2317 LOG_TARGET_DEBUG(target, "cleared HW breakpoint %u @ " TARGET_ADDR_FMT, slot, breakpoint->address);
2318 return ERROR_OK;
2321 int xtensa_watchpoint_add(struct target *target, struct watchpoint *watchpoint)
2323 struct xtensa *xtensa = target_to_xtensa(target);
2324 unsigned int slot;
2325 xtensa_reg_val_t dbreakcval;
2327 if (target->state != TARGET_HALTED) {
2328 LOG_TARGET_WARNING(target, "target not halted");
2329 return ERROR_TARGET_NOT_HALTED;
2332 if (watchpoint->mask != ~(uint32_t)0) {
2333 LOG_TARGET_ERROR(target, "watchpoint value masks not supported");
2334 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2337 for (slot = 0; slot < xtensa->core_config->debug.dbreaks_num; slot++) {
2338 if (!xtensa->hw_wps[slot] || xtensa->hw_wps[slot] == watchpoint)
2339 break;
2341 if (slot == xtensa->core_config->debug.dbreaks_num) {
2342 LOG_TARGET_WARNING(target, "No free slots to add HW watchpoint!");
2343 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2346 /* Figure out value for dbreakc5..0
2347 * It's basically 0x3F with an incremental bit removed from the LSB for each extra length power of 2. */
2348 if (watchpoint->length < 1 || watchpoint->length > 64 ||
2349 !IS_PWR_OF_2(watchpoint->length) ||
2350 !IS_ALIGNED(watchpoint->address, watchpoint->length)) {
2351 LOG_TARGET_WARNING(
2352 target,
2353 "Watchpoint with length %d on address " TARGET_ADDR_FMT
2354 " not supported by hardware.",
2355 watchpoint->length,
2356 watchpoint->address);
2357 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2359 dbreakcval = ALIGN_DOWN(0x3F, watchpoint->length);
2361 if (watchpoint->rw == WPT_READ)
2362 dbreakcval |= BIT(30);
2363 if (watchpoint->rw == WPT_WRITE)
2364 dbreakcval |= BIT(31);
2365 if (watchpoint->rw == WPT_ACCESS)
2366 dbreakcval |= BIT(30) | BIT(31);
2368 /* Write DBREAKA[slot] and DBCREAKC[slot] */
2369 xtensa_reg_set(target, XT_REG_IDX_DBREAKA0 + slot, watchpoint->address);
2370 xtensa_reg_set(target, XT_REG_IDX_DBREAKC0 + slot, dbreakcval);
2371 xtensa->hw_wps[slot] = watchpoint;
2372 LOG_TARGET_DEBUG(target, "placed HW watchpoint @ " TARGET_ADDR_FMT,
2373 watchpoint->address);
2374 return ERROR_OK;
2377 int xtensa_watchpoint_remove(struct target *target, struct watchpoint *watchpoint)
2379 struct xtensa *xtensa = target_to_xtensa(target);
2380 unsigned int slot;
2382 for (slot = 0; slot < xtensa->core_config->debug.dbreaks_num; slot++) {
2383 if (xtensa->hw_wps[slot] == watchpoint)
2384 break;
2386 if (slot == xtensa->core_config->debug.dbreaks_num) {
2387 LOG_TARGET_WARNING(target, "HW watchpoint " TARGET_ADDR_FMT " not found!", watchpoint->address);
2388 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2390 xtensa_reg_set(target, XT_REG_IDX_DBREAKC0 + slot, 0);
2391 xtensa->hw_wps[slot] = NULL;
2392 LOG_TARGET_DEBUG(target, "cleared HW watchpoint @ " TARGET_ADDR_FMT,
2393 watchpoint->address);
2394 return ERROR_OK;
2397 static int xtensa_build_reg_cache(struct target *target)
2399 struct xtensa *xtensa = target_to_xtensa(target);
2400 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
2401 unsigned int last_dbreg_num = 0;
2403 if (xtensa->core_regs_num + xtensa->num_optregs != xtensa->total_regs_num)
2404 LOG_TARGET_WARNING(target, "Register count MISMATCH: %d core regs, %d extended regs; %d expected",
2405 xtensa->core_regs_num, xtensa->num_optregs, xtensa->total_regs_num);
2407 struct reg_cache *reg_cache = calloc(1, sizeof(struct reg_cache));
2409 if (!reg_cache) {
2410 LOG_ERROR("Failed to alloc reg cache!");
2411 return ERROR_FAIL;
2413 reg_cache->name = "Xtensa registers";
2414 reg_cache->next = NULL;
2415 /* Init reglist */
2416 unsigned int reg_list_size = XT_NUM_REGS + xtensa->num_optregs;
2417 struct reg *reg_list = calloc(reg_list_size, sizeof(struct reg));
2418 if (!reg_list) {
2419 LOG_ERROR("Failed to alloc reg list!");
2420 goto fail;
2422 xtensa->dbregs_num = 0;
2423 unsigned int didx = 0;
2424 for (unsigned int whichlist = 0; whichlist < 2; whichlist++) {
2425 struct xtensa_reg_desc *rlist = (whichlist == 0) ? xtensa_regs : xtensa->optregs;
2426 unsigned int listsize = (whichlist == 0) ? XT_NUM_REGS : xtensa->num_optregs;
2427 for (unsigned int i = 0; i < listsize; i++, didx++) {
2428 reg_list[didx].exist = rlist[i].exist;
2429 reg_list[didx].name = rlist[i].name;
2430 reg_list[didx].size = 32;
2431 reg_list[didx].value = calloc(1, 4 /*XT_REG_LEN*/); /* make Clang Static Analyzer happy */
2432 if (!reg_list[didx].value) {
2433 LOG_ERROR("Failed to alloc reg list value!");
2434 goto fail;
2436 reg_list[didx].dirty = false;
2437 reg_list[didx].valid = false;
2438 reg_list[didx].type = &xtensa_reg_type;
2439 reg_list[didx].arch_info = xtensa;
2440 if (rlist[i].exist && (rlist[i].dbreg_num > last_dbreg_num))
2441 last_dbreg_num = rlist[i].dbreg_num;
2443 if (xtensa_extra_debug_log) {
2444 LOG_TARGET_DEBUG(target,
2445 "POPULATE %-16s list %d exist %d, idx %d, type %d, dbreg_num 0x%04x",
2446 reg_list[didx].name,
2447 whichlist,
2448 reg_list[didx].exist,
2449 didx,
2450 rlist[i].type,
2451 rlist[i].dbreg_num);
2456 xtensa->dbregs_num = last_dbreg_num + 1;
2457 reg_cache->reg_list = reg_list;
2458 reg_cache->num_regs = reg_list_size;
2460 LOG_TARGET_DEBUG(target, "xtensa->total_regs_num %d reg_list_size %d xtensa->dbregs_num %d",
2461 xtensa->total_regs_num, reg_list_size, xtensa->dbregs_num);
2463 /* Construct empty-register list for handling unknown register requests */
2464 xtensa->empty_regs = calloc(xtensa->dbregs_num, sizeof(struct reg));
2465 if (!xtensa->empty_regs) {
2466 LOG_TARGET_ERROR(target, "ERROR: Out of memory");
2467 goto fail;
2469 for (unsigned int i = 0; i < xtensa->dbregs_num; i++) {
2470 xtensa->empty_regs[i].name = calloc(8, sizeof(char));
2471 if (!xtensa->empty_regs[i].name) {
2472 LOG_TARGET_ERROR(target, "ERROR: Out of memory");
2473 goto fail;
2475 sprintf((char *)xtensa->empty_regs[i].name, "?0x%04x", i & 0x0000FFFF);
2476 xtensa->empty_regs[i].size = 32;
2477 xtensa->empty_regs[i].type = &xtensa_reg_type;
2478 xtensa->empty_regs[i].value = calloc(1, 4 /*XT_REG_LEN*/); /* make Clang Static Analyzer happy */
2479 if (!xtensa->empty_regs[i].value) {
2480 LOG_ERROR("Failed to alloc empty reg list value!");
2481 goto fail;
2483 xtensa->empty_regs[i].arch_info = xtensa;
2486 /* Construct contiguous register list from contiguous descriptor list */
2487 if (xtensa->regmap_contiguous && xtensa->contiguous_regs_desc) {
2488 xtensa->contiguous_regs_list = calloc(xtensa->total_regs_num, sizeof(struct reg *));
2489 if (!xtensa->contiguous_regs_list) {
2490 LOG_TARGET_ERROR(target, "ERROR: Out of memory");
2491 goto fail;
2493 for (unsigned int i = 0; i < xtensa->total_regs_num; i++) {
2494 unsigned int j;
2495 for (j = 0; j < reg_cache->num_regs; j++) {
2496 if (!strcmp(reg_cache->reg_list[j].name, xtensa->contiguous_regs_desc[i]->name)) {
2497 xtensa->contiguous_regs_list[i] = &(reg_cache->reg_list[j]);
2498 LOG_TARGET_DEBUG(target,
2499 "POPULATE contiguous regs list: %-16s, dbreg_num 0x%04x",
2500 xtensa->contiguous_regs_list[i]->name,
2501 xtensa->contiguous_regs_desc[i]->dbreg_num);
2502 break;
2505 if (j == reg_cache->num_regs)
2506 LOG_TARGET_WARNING(target, "contiguous register %s not found",
2507 xtensa->contiguous_regs_desc[i]->name);
2511 xtensa->algo_context_backup = calloc(reg_cache->num_regs, sizeof(void *));
2512 if (!xtensa->algo_context_backup) {
2513 LOG_ERROR("Failed to alloc mem for algorithm context backup!");
2514 goto fail;
2516 for (unsigned int i = 0; i < reg_cache->num_regs; i++) {
2517 struct reg *reg = &reg_cache->reg_list[i];
2518 xtensa->algo_context_backup[i] = calloc(1, reg->size / 8);
2519 if (!xtensa->algo_context_backup[i]) {
2520 LOG_ERROR("Failed to alloc mem for algorithm context!");
2521 goto fail;
2524 xtensa->core_cache = reg_cache;
2525 if (cache_p)
2526 *cache_p = reg_cache;
2527 return ERROR_OK;
2529 fail:
2530 if (reg_list) {
2531 for (unsigned int i = 0; i < reg_list_size; i++)
2532 free(reg_list[i].value);
2533 free(reg_list);
2535 if (xtensa->empty_regs) {
2536 for (unsigned int i = 0; i < xtensa->dbregs_num; i++) {
2537 free((void *)xtensa->empty_regs[i].name);
2538 free(xtensa->empty_regs[i].value);
2540 free(xtensa->empty_regs);
2542 if (xtensa->algo_context_backup) {
2543 for (unsigned int i = 0; i < reg_cache->num_regs; i++)
2544 free(xtensa->algo_context_backup[i]);
2545 free(xtensa->algo_context_backup);
2547 free(reg_cache);
2549 return ERROR_FAIL;
2552 static int32_t xtensa_gdbqc_parse_exec_tie_ops(struct target *target, char *opstr)
2554 struct xtensa *xtensa = target_to_xtensa(target);
2555 int32_t status = ERROR_COMMAND_ARGUMENT_INVALID;
2556 /* Process op[] list */
2557 while (opstr && (*opstr == ':')) {
2558 uint8_t ops[32];
2559 unsigned int oplen = strtoul(opstr + 1, &opstr, 16);
2560 if (oplen > 32) {
2561 LOG_TARGET_ERROR(target, "TIE access instruction too long (%d)\n", oplen);
2562 break;
2564 unsigned int i = 0;
2565 while ((i < oplen) && opstr && (*opstr == ':'))
2566 ops[i++] = strtoul(opstr + 1, &opstr, 16);
2567 if (i != oplen) {
2568 LOG_TARGET_ERROR(target, "TIE access instruction malformed (%d)\n", i);
2569 break;
2572 char insn_buf[128];
2573 sprintf(insn_buf, "Exec %d-byte TIE sequence: ", oplen);
2574 for (i = 0; i < oplen; i++)
2575 sprintf(insn_buf + strlen(insn_buf), "%02x:", ops[i]);
2576 LOG_TARGET_DEBUG(target, "%s", insn_buf);
2577 xtensa_queue_exec_ins_wide(xtensa, ops, oplen); /* Handles endian-swap */
2578 status = ERROR_OK;
2580 return status;
2583 static int xtensa_gdbqc_qxtreg(struct target *target, const char *packet, char **response_p)
2585 struct xtensa *xtensa = target_to_xtensa(target);
2586 bool iswrite = (packet[0] == 'Q');
2587 enum xtensa_qerr_e error;
2589 /* Read/write TIE register. Requires spill location.
2590 * qxtreg<num>:<len>:<oplen>:<op[0]>:<...>[:<oplen>:<op[0]>:<...>]
2591 * Qxtreg<num>:<len>:<oplen>:<op[0]>:<...>[:<oplen>:<op[0]>:<...>]=<value>
2593 if (!(xtensa->spill_buf)) {
2594 LOG_ERROR("Spill location not specified. Try 'target remote <host>:3333 &spill_location0'");
2595 error = XT_QERR_FAIL;
2596 goto xtensa_gdbqc_qxtreg_fail;
2599 char *delim;
2600 uint32_t regnum = strtoul(packet + 6, &delim, 16);
2601 if (*delim != ':') {
2602 LOG_ERROR("Malformed qxtreg packet");
2603 error = XT_QERR_INVAL;
2604 goto xtensa_gdbqc_qxtreg_fail;
2606 uint32_t reglen = strtoul(delim + 1, &delim, 16);
2607 if (*delim != ':') {
2608 LOG_ERROR("Malformed qxtreg packet");
2609 error = XT_QERR_INVAL;
2610 goto xtensa_gdbqc_qxtreg_fail;
2612 uint8_t regbuf[XT_QUERYPKT_RESP_MAX];
2613 memset(regbuf, 0, XT_QUERYPKT_RESP_MAX);
2614 LOG_DEBUG("TIE reg 0x%08" PRIx32 " %s (%d bytes)", regnum, iswrite ? "write" : "read", reglen);
2615 if (reglen * 2 + 1 > XT_QUERYPKT_RESP_MAX) {
2616 LOG_ERROR("TIE register too large");
2617 error = XT_QERR_MEM;
2618 goto xtensa_gdbqc_qxtreg_fail;
2621 /* (1) Save spill memory, (1.5) [if write then store value to spill location],
2622 * (2) read old a4, (3) write spill address to a4.
2623 * NOTE: ensure a4 is restored properly by all error handling logic
2625 unsigned int memop_size = (xtensa->spill_loc & 3) ? 1 : 4;
2626 int status = xtensa_read_memory(target, xtensa->spill_loc, memop_size,
2627 xtensa->spill_bytes / memop_size, xtensa->spill_buf);
2628 if (status != ERROR_OK) {
2629 LOG_ERROR("Spill memory save");
2630 error = XT_QERR_MEM;
2631 goto xtensa_gdbqc_qxtreg_fail;
2633 if (iswrite) {
2634 /* Extract value and store in spill memory */
2635 unsigned int b = 0;
2636 char *valbuf = strchr(delim, '=');
2637 if (!(valbuf && (*valbuf == '='))) {
2638 LOG_ERROR("Malformed Qxtreg packet");
2639 error = XT_QERR_INVAL;
2640 goto xtensa_gdbqc_qxtreg_fail;
2642 valbuf++;
2643 while (*valbuf && *(valbuf + 1)) {
2644 char bytestr[3] = { 0, 0, 0 };
2645 strncpy(bytestr, valbuf, 2);
2646 regbuf[b++] = strtoul(bytestr, NULL, 16);
2647 valbuf += 2;
2649 if (b != reglen) {
2650 LOG_ERROR("Malformed Qxtreg packet");
2651 error = XT_QERR_INVAL;
2652 goto xtensa_gdbqc_qxtreg_fail;
2654 status = xtensa_write_memory(target, xtensa->spill_loc, memop_size,
2655 reglen / memop_size, regbuf);
2656 if (status != ERROR_OK) {
2657 LOG_ERROR("TIE value store");
2658 error = XT_QERR_MEM;
2659 goto xtensa_gdbqc_qxtreg_fail;
2662 xtensa_reg_val_t orig_a4 = xtensa_reg_get(target, XT_REG_IDX_A4);
2663 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, xtensa->spill_loc);
2664 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A4));
2666 int32_t tieop_status = xtensa_gdbqc_parse_exec_tie_ops(target, delim);
2668 /* Restore a4 but not yet spill memory. Execute it all... */
2669 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, orig_a4);
2670 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A4));
2671 status = xtensa_dm_queue_execute(&xtensa->dbg_mod);
2672 if (status != ERROR_OK) {
2673 LOG_TARGET_ERROR(target, "TIE queue execute: %d\n", status);
2674 tieop_status = status;
2676 status = xtensa_core_status_check(target);
2677 if (status != ERROR_OK) {
2678 LOG_TARGET_ERROR(target, "TIE instr execute: %d\n", status);
2679 tieop_status = status;
2682 if (tieop_status == ERROR_OK) {
2683 if (iswrite) {
2684 /* TIE write succeeded; send OK */
2685 strcpy(*response_p, "OK");
2686 } else {
2687 /* TIE read succeeded; copy result from spill memory */
2688 status = xtensa_read_memory(target, xtensa->spill_loc, memop_size, reglen, regbuf);
2689 if (status != ERROR_OK) {
2690 LOG_TARGET_ERROR(target, "TIE result read");
2691 tieop_status = status;
2693 unsigned int i;
2694 for (i = 0; i < reglen; i++)
2695 sprintf(*response_p + 2 * i, "%02x", regbuf[i]);
2696 *(*response_p + 2 * i) = '\0';
2697 LOG_TARGET_DEBUG(target, "TIE response: %s", *response_p);
2701 /* Restore spill memory first, then report any previous errors */
2702 status = xtensa_write_memory(target, xtensa->spill_loc, memop_size,
2703 xtensa->spill_bytes / memop_size, xtensa->spill_buf);
2704 if (status != ERROR_OK) {
2705 LOG_ERROR("Spill memory restore");
2706 error = XT_QERR_MEM;
2707 goto xtensa_gdbqc_qxtreg_fail;
2709 if (tieop_status != ERROR_OK) {
2710 LOG_ERROR("TIE execution");
2711 error = XT_QERR_FAIL;
2712 goto xtensa_gdbqc_qxtreg_fail;
2714 return ERROR_OK;
2716 xtensa_gdbqc_qxtreg_fail:
2717 strcpy(*response_p, xt_qerr[error].chrval);
2718 return xt_qerr[error].intval;
2721 int xtensa_gdb_query_custom(struct target *target, const char *packet, char **response_p)
2723 struct xtensa *xtensa = target_to_xtensa(target);
2724 enum xtensa_qerr_e error;
2725 if (!packet || !response_p) {
2726 LOG_TARGET_ERROR(target, "invalid parameter: packet %p response_p %p", packet, response_p);
2727 return ERROR_FAIL;
2730 *response_p = xtensa->qpkt_resp;
2731 if (strncmp(packet, "qxtn", 4) == 0) {
2732 strcpy(*response_p, "OpenOCD");
2733 return ERROR_OK;
2734 } else if (strncasecmp(packet, "qxtgdbversion=", 14) == 0) {
2735 return ERROR_OK;
2736 } else if ((strncmp(packet, "Qxtsis=", 7) == 0) || (strncmp(packet, "Qxtsds=", 7) == 0)) {
2737 /* Confirm host cache params match core .cfg file */
2738 struct xtensa_cache_config *cachep = (packet[4] == 'i') ?
2739 &xtensa->core_config->icache : &xtensa->core_config->dcache;
2740 unsigned int line_size = 0, size = 0, way_count = 0;
2741 sscanf(&packet[7], "%x,%x,%x", &line_size, &size, &way_count);
2742 if ((cachep->line_size != line_size) ||
2743 (cachep->size != size) ||
2744 (cachep->way_count != way_count)) {
2745 LOG_TARGET_WARNING(target, "%cCache mismatch; check xtensa-core-XXX.cfg file",
2746 cachep == &xtensa->core_config->icache ? 'I' : 'D');
2748 strcpy(*response_p, "OK");
2749 return ERROR_OK;
2750 } else if ((strncmp(packet, "Qxtiram=", 8) == 0) || (strncmp(packet, "Qxtirom=", 8) == 0)) {
2751 /* Confirm host IRAM/IROM params match core .cfg file */
2752 struct xtensa_local_mem_config *memp = (packet[5] == 'a') ?
2753 &xtensa->core_config->iram : &xtensa->core_config->irom;
2754 unsigned int base = 0, size = 0, i;
2755 char *pkt = (char *)&packet[7];
2756 do {
2757 pkt++;
2758 size = strtoul(pkt, &pkt, 16);
2759 pkt++;
2760 base = strtoul(pkt, &pkt, 16);
2761 LOG_TARGET_DEBUG(target, "memcheck: %dB @ 0x%08x", size, base);
2762 for (i = 0; i < memp->count; i++) {
2763 if ((memp->regions[i].base == base) && (memp->regions[i].size == size))
2764 break;
2766 if (i == memp->count) {
2767 LOG_TARGET_WARNING(target, "%s mismatch; check xtensa-core-XXX.cfg file",
2768 memp == &xtensa->core_config->iram ? "IRAM" : "IROM");
2769 break;
2771 for (i = 0; i < 11; i++) {
2772 pkt++;
2773 strtoul(pkt, &pkt, 16);
2775 } while (pkt && (pkt[0] == ','));
2776 strcpy(*response_p, "OK");
2777 return ERROR_OK;
2778 } else if (strncmp(packet, "Qxtexcmlvl=", 11) == 0) {
2779 /* Confirm host EXCM_LEVEL matches core .cfg file */
2780 unsigned int excm_level = strtoul(&packet[11], NULL, 0);
2781 if (!xtensa->core_config->high_irq.enabled ||
2782 (excm_level != xtensa->core_config->high_irq.excm_level))
2783 LOG_TARGET_WARNING(target, "EXCM_LEVEL mismatch; check xtensa-core-XXX.cfg file");
2784 strcpy(*response_p, "OK");
2785 return ERROR_OK;
2786 } else if ((strncmp(packet, "Qxtl2cs=", 8) == 0) ||
2787 (strncmp(packet, "Qxtl2ca=", 8) == 0) ||
2788 (strncmp(packet, "Qxtdensity=", 11) == 0)) {
2789 strcpy(*response_p, "OK");
2790 return ERROR_OK;
2791 } else if (strncmp(packet, "Qxtspill=", 9) == 0) {
2792 char *delim;
2793 uint32_t spill_loc = strtoul(packet + 9, &delim, 16);
2794 if (*delim != ':') {
2795 LOG_ERROR("Malformed Qxtspill packet");
2796 error = XT_QERR_INVAL;
2797 goto xtensa_gdb_query_custom_fail;
2799 xtensa->spill_loc = spill_loc;
2800 xtensa->spill_bytes = strtoul(delim + 1, NULL, 16);
2801 if (xtensa->spill_buf)
2802 free(xtensa->spill_buf);
2803 xtensa->spill_buf = calloc(1, xtensa->spill_bytes);
2804 if (!xtensa->spill_buf) {
2805 LOG_ERROR("Spill buf alloc");
2806 error = XT_QERR_MEM;
2807 goto xtensa_gdb_query_custom_fail;
2809 LOG_TARGET_DEBUG(target, "Set spill 0x%08" PRIx32 " (%d)", xtensa->spill_loc, xtensa->spill_bytes);
2810 strcpy(*response_p, "OK");
2811 return ERROR_OK;
2812 } else if (strncasecmp(packet, "qxtreg", 6) == 0) {
2813 return xtensa_gdbqc_qxtreg(target, packet, response_p);
2814 } else if ((strncmp(packet, "qTStatus", 8) == 0) ||
2815 (strncmp(packet, "qxtftie", 7) == 0) ||
2816 (strncmp(packet, "qxtstie", 7) == 0)) {
2817 /* Return empty string to indicate trace, TIE wire debug are unsupported */
2818 strcpy(*response_p, "");
2819 return ERROR_OK;
2822 /* Warn for all other queries, but do not return errors */
2823 LOG_TARGET_WARNING(target, "Unknown target-specific query packet: %s", packet);
2824 strcpy(*response_p, "");
2825 return ERROR_OK;
2827 xtensa_gdb_query_custom_fail:
2828 strcpy(*response_p, xt_qerr[error].chrval);
2829 return xt_qerr[error].intval;
2832 int xtensa_init_arch_info(struct target *target, struct xtensa *xtensa,
2833 const struct xtensa_debug_module_config *dm_cfg)
2835 target->arch_info = xtensa;
2836 xtensa->common_magic = XTENSA_COMMON_MAGIC;
2837 xtensa->target = target;
2838 xtensa->stepping_isr_mode = XT_STEPPING_ISR_ON;
2840 xtensa->core_config = calloc(1, sizeof(struct xtensa_config));
2841 if (!xtensa->core_config) {
2842 LOG_ERROR("Xtensa configuration alloc failed\n");
2843 return ERROR_FAIL;
2846 /* Default cache settings are disabled with 1 way */
2847 xtensa->core_config->icache.way_count = 1;
2848 xtensa->core_config->dcache.way_count = 1;
2850 /* chrval: AR3/AR4 register names will change with window mapping.
2851 * intval: tracks whether scratch register was set through gdb P packet.
2853 for (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++) {
2854 xtensa->scratch_ars[s].chrval = calloc(8, sizeof(char));
2855 if (!xtensa->scratch_ars[s].chrval) {
2856 for (enum xtensa_ar_scratch_set_e f = 0; f < s; f++)
2857 free(xtensa->scratch_ars[f].chrval);
2858 free(xtensa->core_config);
2859 LOG_ERROR("Xtensa scratch AR alloc failed\n");
2860 return ERROR_FAIL;
2862 xtensa->scratch_ars[s].intval = false;
2863 sprintf(xtensa->scratch_ars[s].chrval, "%s%d",
2864 ((s == XT_AR_SCRATCH_A3) || (s == XT_AR_SCRATCH_A4)) ? "a" : "ar",
2865 ((s == XT_AR_SCRATCH_A3) || (s == XT_AR_SCRATCH_AR3)) ? 3 : 4);
2868 return xtensa_dm_init(&xtensa->dbg_mod, dm_cfg);
2871 void xtensa_set_permissive_mode(struct target *target, bool state)
2873 target_to_xtensa(target)->permissive_mode = state;
2876 int xtensa_target_init(struct command_context *cmd_ctx, struct target *target)
2878 struct xtensa *xtensa = target_to_xtensa(target);
2880 xtensa->come_online_probes_num = 3;
2881 xtensa->hw_brps = calloc(XT_HW_IBREAK_MAX_NUM, sizeof(struct breakpoint *));
2882 if (!xtensa->hw_brps) {
2883 LOG_ERROR("Failed to alloc memory for HW breakpoints!");
2884 return ERROR_FAIL;
2886 xtensa->hw_wps = calloc(XT_HW_DBREAK_MAX_NUM, sizeof(struct watchpoint *));
2887 if (!xtensa->hw_wps) {
2888 free(xtensa->hw_brps);
2889 LOG_ERROR("Failed to alloc memory for HW watchpoints!");
2890 return ERROR_FAIL;
2892 xtensa->sw_brps = calloc(XT_SW_BREAKPOINTS_MAX_NUM, sizeof(struct xtensa_sw_breakpoint));
2893 if (!xtensa->sw_brps) {
2894 free(xtensa->hw_brps);
2895 free(xtensa->hw_wps);
2896 LOG_ERROR("Failed to alloc memory for SW breakpoints!");
2897 return ERROR_FAIL;
2900 xtensa->spill_loc = 0xffffffff;
2901 xtensa->spill_bytes = 0;
2902 xtensa->spill_buf = NULL;
2903 xtensa->probe_lsddr32p = -1; /* Probe for fast load/store operations */
2905 return xtensa_build_reg_cache(target);
2908 static void xtensa_free_reg_cache(struct target *target)
2910 struct xtensa *xtensa = target_to_xtensa(target);
2911 struct reg_cache *cache = xtensa->core_cache;
2913 if (cache) {
2914 register_unlink_cache(&target->reg_cache, cache);
2915 for (unsigned int i = 0; i < cache->num_regs; i++) {
2916 free(xtensa->algo_context_backup[i]);
2917 free(cache->reg_list[i].value);
2919 free(xtensa->algo_context_backup);
2920 free(cache->reg_list);
2921 free(cache);
2923 xtensa->core_cache = NULL;
2924 xtensa->algo_context_backup = NULL;
2926 if (xtensa->empty_regs) {
2927 for (unsigned int i = 0; i < xtensa->dbregs_num; i++) {
2928 free((void *)xtensa->empty_regs[i].name);
2929 free(xtensa->empty_regs[i].value);
2931 free(xtensa->empty_regs);
2933 xtensa->empty_regs = NULL;
2934 if (xtensa->optregs) {
2935 for (unsigned int i = 0; i < xtensa->num_optregs; i++)
2936 free((void *)xtensa->optregs[i].name);
2937 free(xtensa->optregs);
2939 xtensa->optregs = NULL;
2942 void xtensa_target_deinit(struct target *target)
2944 struct xtensa *xtensa = target_to_xtensa(target);
2946 LOG_DEBUG("start");
2948 if (target_was_examined(target)) {
2949 int ret = xtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRCLR, OCDDCR_ENABLEOCD);
2950 if (ret != ERROR_OK) {
2951 LOG_ERROR("Failed to queue OCDDCR_ENABLEOCD clear operation!");
2952 return;
2954 xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);
2955 ret = xtensa_dm_queue_execute(&xtensa->dbg_mod);
2956 if (ret != ERROR_OK) {
2957 LOG_ERROR("Failed to clear OCDDCR_ENABLEOCD!");
2958 return;
2961 xtensa_free_reg_cache(target);
2962 free(xtensa->hw_brps);
2963 free(xtensa->hw_wps);
2964 free(xtensa->sw_brps);
2965 if (xtensa->spill_buf) {
2966 free(xtensa->spill_buf);
2967 xtensa->spill_buf = NULL;
2969 for (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++)
2970 free(xtensa->scratch_ars[s].chrval);
2971 free(xtensa->core_config);
2974 const char *xtensa_get_gdb_arch(struct target *target)
2976 return "xtensa";
2979 /* exe <ascii-encoded hexadecimal instruction bytes> */
2980 COMMAND_HELPER(xtensa_cmd_exe_do, struct target *target)
2982 struct xtensa *xtensa = target_to_xtensa(target);
2984 if (CMD_ARGC != 1)
2985 return ERROR_COMMAND_SYNTAX_ERROR;
2987 /* Process ascii-encoded hex byte string */
2988 const char *parm = CMD_ARGV[0];
2989 unsigned int parm_len = strlen(parm);
2990 if ((parm_len >= 64) || (parm_len & 1)) {
2991 LOG_ERROR("Invalid parameter length (%d): must be even, < 64 characters", parm_len);
2992 return ERROR_FAIL;
2995 uint8_t ops[32];
2996 memset(ops, 0, 32);
2997 unsigned int oplen = parm_len / 2;
2998 char encoded_byte[3] = { 0, 0, 0 };
2999 for (unsigned int i = 0; i < oplen; i++) {
3000 encoded_byte[0] = *parm++;
3001 encoded_byte[1] = *parm++;
3002 ops[i] = strtoul(encoded_byte, NULL, 16);
3005 /* GDB must handle state save/restore.
3006 * Flush reg cache in case spill location is in an AR
3007 * Update CPENABLE only for this execution; later restore cached copy
3008 * Keep a copy of exccause in case executed code triggers an exception
3010 int status = xtensa_write_dirty_registers(target);
3011 if (status != ERROR_OK) {
3012 LOG_ERROR("%s: Failed to write back register cache.", target_name(target));
3013 return ERROR_FAIL;
3015 xtensa_reg_val_t exccause = xtensa_reg_get(target, XT_REG_IDX_EXCCAUSE);
3016 xtensa_reg_val_t cpenable = xtensa_reg_get(target, XT_REG_IDX_CPENABLE);
3017 xtensa_reg_val_t a3 = xtensa_reg_get(target, XT_REG_IDX_A3);
3018 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, 0xffffffff);
3019 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
3020 xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa,
3021 xtensa_regs[XT_REG_IDX_CPENABLE].reg_num, XT_REG_A3));
3022 xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, a3);
3023 xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
3025 /* Queue instruction list and execute everything */
3026 LOG_TARGET_DEBUG(target, "execute stub: %s", CMD_ARGV[0]);
3027 xtensa_queue_exec_ins_wide(xtensa, ops, oplen); /* Handles endian-swap */
3028 status = xtensa_dm_queue_execute(&xtensa->dbg_mod);
3029 if (status != ERROR_OK)
3030 LOG_TARGET_ERROR(target, "TIE queue execute: %d\n", status);
3031 status = xtensa_core_status_check(target);
3032 if (status != ERROR_OK)
3033 LOG_TARGET_ERROR(target, "TIE instr execute: %d\n", status);
3035 /* Reread register cache and restore saved regs after instruction execution */
3036 if (xtensa_fetch_all_regs(target) != ERROR_OK)
3037 LOG_TARGET_ERROR(target, "%s: Failed to fetch register cache (post-exec).", target_name(target));
3038 xtensa_reg_set(target, XT_REG_IDX_EXCCAUSE, exccause);
3039 xtensa_reg_set(target, XT_REG_IDX_CPENABLE, cpenable);
3040 return status;
3043 COMMAND_HANDLER(xtensa_cmd_exe)
3045 return CALL_COMMAND_HANDLER(xtensa_cmd_exe_do, get_current_target(CMD_CTX));
3048 /* xtdef <name> */
3049 COMMAND_HELPER(xtensa_cmd_xtdef_do, struct xtensa *xtensa)
3051 if (CMD_ARGC != 1)
3052 return ERROR_COMMAND_SYNTAX_ERROR;
3054 const char *core_name = CMD_ARGV[0];
3055 if (strcasecmp(core_name, "LX") == 0) {
3056 xtensa->core_config->core_type = XT_LX;
3057 } else {
3058 LOG_ERROR("xtdef [LX]\n");
3059 return ERROR_COMMAND_SYNTAX_ERROR;
3061 return ERROR_OK;
3064 COMMAND_HANDLER(xtensa_cmd_xtdef)
3066 return CALL_COMMAND_HANDLER(xtensa_cmd_xtdef_do,
3067 target_to_xtensa(get_current_target(CMD_CTX)));
3070 static inline bool xtensa_cmd_xtopt_legal_val(char *opt, int val, int min, int max)
3072 if ((val < min) || (val > max)) {
3073 LOG_ERROR("xtopt %s (%d) out of range [%d..%d]\n", opt, val, min, max);
3074 return false;
3076 return true;
3079 /* xtopt <name> <value> */
3080 COMMAND_HELPER(xtensa_cmd_xtopt_do, struct xtensa *xtensa)
3082 if (CMD_ARGC != 2)
3083 return ERROR_COMMAND_SYNTAX_ERROR;
3085 const char *opt_name = CMD_ARGV[0];
3086 int opt_val = strtol(CMD_ARGV[1], NULL, 0);
3087 if (strcasecmp(opt_name, "arnum") == 0) {
3088 if (!xtensa_cmd_xtopt_legal_val("arnum", opt_val, 0, 64))
3089 return ERROR_COMMAND_ARGUMENT_INVALID;
3090 xtensa->core_config->aregs_num = opt_val;
3091 } else if (strcasecmp(opt_name, "windowed") == 0) {
3092 if (!xtensa_cmd_xtopt_legal_val("windowed", opt_val, 0, 1))
3093 return ERROR_COMMAND_ARGUMENT_INVALID;
3094 xtensa->core_config->windowed = opt_val;
3095 } else if (strcasecmp(opt_name, "cpenable") == 0) {
3096 if (!xtensa_cmd_xtopt_legal_val("cpenable", opt_val, 0, 1))
3097 return ERROR_COMMAND_ARGUMENT_INVALID;
3098 xtensa->core_config->coproc = opt_val;
3099 } else if (strcasecmp(opt_name, "exceptions") == 0) {
3100 if (!xtensa_cmd_xtopt_legal_val("exceptions", opt_val, 0, 1))
3101 return ERROR_COMMAND_ARGUMENT_INVALID;
3102 xtensa->core_config->exceptions = opt_val;
3103 } else if (strcasecmp(opt_name, "intnum") == 0) {
3104 if (!xtensa_cmd_xtopt_legal_val("intnum", opt_val, 0, 32))
3105 return ERROR_COMMAND_ARGUMENT_INVALID;
3106 xtensa->core_config->irq.enabled = (opt_val > 0);
3107 xtensa->core_config->irq.irq_num = opt_val;
3108 } else if (strcasecmp(opt_name, "hipriints") == 0) {
3109 if (!xtensa_cmd_xtopt_legal_val("hipriints", opt_val, 0, 1))
3110 return ERROR_COMMAND_ARGUMENT_INVALID;
3111 xtensa->core_config->high_irq.enabled = opt_val;
3112 } else if (strcasecmp(opt_name, "excmlevel") == 0) {
3113 if (!xtensa_cmd_xtopt_legal_val("excmlevel", opt_val, 1, 6))
3114 return ERROR_COMMAND_ARGUMENT_INVALID;
3115 if (!xtensa->core_config->high_irq.enabled) {
3116 LOG_ERROR("xtopt excmlevel requires hipriints\n");
3117 return ERROR_COMMAND_ARGUMENT_INVALID;
3119 xtensa->core_config->high_irq.excm_level = opt_val;
3120 } else if (strcasecmp(opt_name, "intlevels") == 0) {
3121 if (xtensa->core_config->core_type == XT_LX) {
3122 if (!xtensa_cmd_xtopt_legal_val("intlevels", opt_val, 2, 6))
3123 return ERROR_COMMAND_ARGUMENT_INVALID;
3124 } else {
3125 if (!xtensa_cmd_xtopt_legal_val("intlevels", opt_val, 1, 255))
3126 return ERROR_COMMAND_ARGUMENT_INVALID;
3128 if (!xtensa->core_config->high_irq.enabled) {
3129 LOG_ERROR("xtopt intlevels requires hipriints\n");
3130 return ERROR_COMMAND_ARGUMENT_INVALID;
3132 xtensa->core_config->high_irq.level_num = opt_val;
3133 } else if (strcasecmp(opt_name, "debuglevel") == 0) {
3134 if (xtensa->core_config->core_type == XT_LX) {
3135 if (!xtensa_cmd_xtopt_legal_val("debuglevel", opt_val, 2, 6))
3136 return ERROR_COMMAND_ARGUMENT_INVALID;
3137 } else {
3138 if (!xtensa_cmd_xtopt_legal_val("debuglevel", opt_val, 0, 0))
3139 return ERROR_COMMAND_ARGUMENT_INVALID;
3141 xtensa->core_config->debug.enabled = 1;
3142 xtensa->core_config->debug.irq_level = opt_val;
3143 } else if (strcasecmp(opt_name, "ibreaknum") == 0) {
3144 if (!xtensa_cmd_xtopt_legal_val("ibreaknum", opt_val, 0, 2))
3145 return ERROR_COMMAND_ARGUMENT_INVALID;
3146 xtensa->core_config->debug.ibreaks_num = opt_val;
3147 } else if (strcasecmp(opt_name, "dbreaknum") == 0) {
3148 if (!xtensa_cmd_xtopt_legal_val("dbreaknum", opt_val, 0, 2))
3149 return ERROR_COMMAND_ARGUMENT_INVALID;
3150 xtensa->core_config->debug.dbreaks_num = opt_val;
3151 } else if (strcasecmp(opt_name, "tracemem") == 0) {
3152 if (!xtensa_cmd_xtopt_legal_val("tracemem", opt_val, 0, 256 * 1024))
3153 return ERROR_COMMAND_ARGUMENT_INVALID;
3154 xtensa->core_config->trace.mem_sz = opt_val;
3155 xtensa->core_config->trace.enabled = (opt_val > 0);
3156 } else if (strcasecmp(opt_name, "tracememrev") == 0) {
3157 if (!xtensa_cmd_xtopt_legal_val("tracememrev", opt_val, 0, 1))
3158 return ERROR_COMMAND_ARGUMENT_INVALID;
3159 xtensa->core_config->trace.reversed_mem_access = opt_val;
3160 } else if (strcasecmp(opt_name, "perfcount") == 0) {
3161 if (!xtensa_cmd_xtopt_legal_val("perfcount", opt_val, 0, 8))
3162 return ERROR_COMMAND_ARGUMENT_INVALID;
3163 xtensa->core_config->debug.perfcount_num = opt_val;
3164 } else {
3165 LOG_WARNING("Unknown xtensa command ignored: \"xtopt %s %s\"", CMD_ARGV[0], CMD_ARGV[1]);
3166 return ERROR_OK;
3169 return ERROR_OK;
3172 COMMAND_HANDLER(xtensa_cmd_xtopt)
3174 return CALL_COMMAND_HANDLER(xtensa_cmd_xtopt_do,
3175 target_to_xtensa(get_current_target(CMD_CTX)));
3178 /* xtmem <type> [parameters] */
3179 COMMAND_HELPER(xtensa_cmd_xtmem_do, struct xtensa *xtensa)
3181 struct xtensa_cache_config *cachep = NULL;
3182 struct xtensa_local_mem_config *memp = NULL;
3183 int mem_access = 0;
3184 bool is_dcache = false;
3186 if (CMD_ARGC == 0) {
3187 LOG_ERROR("xtmem <type> [parameters]\n");
3188 return ERROR_COMMAND_SYNTAX_ERROR;
3191 const char *mem_name = CMD_ARGV[0];
3192 if (strcasecmp(mem_name, "icache") == 0) {
3193 cachep = &xtensa->core_config->icache;
3194 } else if (strcasecmp(mem_name, "dcache") == 0) {
3195 cachep = &xtensa->core_config->dcache;
3196 is_dcache = true;
3197 } else if (strcasecmp(mem_name, "l2cache") == 0) {
3198 /* TODO: support L2 cache */
3199 } else if (strcasecmp(mem_name, "l2addr") == 0) {
3200 /* TODO: support L2 cache */
3201 } else if (strcasecmp(mem_name, "iram") == 0) {
3202 memp = &xtensa->core_config->iram;
3203 mem_access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE;
3204 } else if (strcasecmp(mem_name, "dram") == 0) {
3205 memp = &xtensa->core_config->dram;
3206 mem_access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE;
3207 } else if (strcasecmp(mem_name, "sram") == 0) {
3208 memp = &xtensa->core_config->sram;
3209 mem_access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE;
3210 } else if (strcasecmp(mem_name, "irom") == 0) {
3211 memp = &xtensa->core_config->irom;
3212 mem_access = XT_MEM_ACCESS_READ;
3213 } else if (strcasecmp(mem_name, "drom") == 0) {
3214 memp = &xtensa->core_config->drom;
3215 mem_access = XT_MEM_ACCESS_READ;
3216 } else if (strcasecmp(mem_name, "srom") == 0) {
3217 memp = &xtensa->core_config->srom;
3218 mem_access = XT_MEM_ACCESS_READ;
3219 } else {
3220 LOG_ERROR("xtmem types: <icache|dcache|l2cache|l2addr|iram|irom|dram|drom|sram|srom>\n");
3221 return ERROR_COMMAND_ARGUMENT_INVALID;
3224 if (cachep) {
3225 if ((CMD_ARGC != 4) && (CMD_ARGC != 5)) {
3226 LOG_ERROR("xtmem <cachetype> <linebytes> <cachebytes> <ways> [writeback]\n");
3227 return ERROR_COMMAND_SYNTAX_ERROR;
3229 cachep->line_size = strtoul(CMD_ARGV[1], NULL, 0);
3230 cachep->size = strtoul(CMD_ARGV[2], NULL, 0);
3231 cachep->way_count = strtoul(CMD_ARGV[3], NULL, 0);
3232 cachep->writeback = ((CMD_ARGC == 5) && is_dcache) ?
3233 strtoul(CMD_ARGV[4], NULL, 0) : 0;
3234 } else if (memp) {
3235 if (CMD_ARGC != 3) {
3236 LOG_ERROR("xtmem <memtype> <baseaddr> <bytes>\n");
3237 return ERROR_COMMAND_SYNTAX_ERROR;
3239 struct xtensa_local_mem_region_config *memcfgp = &memp->regions[memp->count];
3240 memcfgp->base = strtoul(CMD_ARGV[1], NULL, 0);
3241 memcfgp->size = strtoul(CMD_ARGV[2], NULL, 0);
3242 memcfgp->access = mem_access;
3243 memp->count++;
3246 return ERROR_OK;
3249 COMMAND_HANDLER(xtensa_cmd_xtmem)
3251 return CALL_COMMAND_HANDLER(xtensa_cmd_xtmem_do,
3252 target_to_xtensa(get_current_target(CMD_CTX)));
3255 /* xtmpu <num FG seg> <min seg size> <lockable> <executeonly> */
3256 COMMAND_HELPER(xtensa_cmd_xtmpu_do, struct xtensa *xtensa)
3258 if (CMD_ARGC != 4) {
3259 LOG_ERROR("xtmpu <num FG seg> <min seg size> <lockable> <executeonly>\n");
3260 return ERROR_COMMAND_SYNTAX_ERROR;
3263 unsigned int nfgseg = strtoul(CMD_ARGV[0], NULL, 0);
3264 unsigned int minsegsize = strtoul(CMD_ARGV[1], NULL, 0);
3265 unsigned int lockable = strtoul(CMD_ARGV[2], NULL, 0);
3266 unsigned int execonly = strtoul(CMD_ARGV[3], NULL, 0);
3268 if ((nfgseg > 32)) {
3269 LOG_ERROR("<nfgseg> must be within [0..32]\n");
3270 return ERROR_COMMAND_ARGUMENT_INVALID;
3271 } else if (minsegsize & (minsegsize - 1)) {
3272 LOG_ERROR("<minsegsize> must be a power of 2 >= 32\n");
3273 return ERROR_COMMAND_ARGUMENT_INVALID;
3274 } else if (lockable > 1) {
3275 LOG_ERROR("<lockable> must be 0 or 1\n");
3276 return ERROR_COMMAND_ARGUMENT_INVALID;
3277 } else if (execonly > 1) {
3278 LOG_ERROR("<execonly> must be 0 or 1\n");
3279 return ERROR_COMMAND_ARGUMENT_INVALID;
3282 xtensa->core_config->mpu.enabled = true;
3283 xtensa->core_config->mpu.nfgseg = nfgseg;
3284 xtensa->core_config->mpu.minsegsize = minsegsize;
3285 xtensa->core_config->mpu.lockable = lockable;
3286 xtensa->core_config->mpu.execonly = execonly;
3287 return ERROR_OK;
3290 COMMAND_HANDLER(xtensa_cmd_xtmpu)
3292 return CALL_COMMAND_HANDLER(xtensa_cmd_xtmpu_do,
3293 target_to_xtensa(get_current_target(CMD_CTX)));
3296 /* xtmmu <NIREFILLENTRIES> <NDREFILLENTRIES> <IVARWAY56> <DVARWAY56> */
3297 COMMAND_HELPER(xtensa_cmd_xtmmu_do, struct xtensa *xtensa)
3299 if (CMD_ARGC != 2) {
3300 LOG_ERROR("xtmmu <NIREFILLENTRIES> <NDREFILLENTRIES>\n");
3301 return ERROR_COMMAND_SYNTAX_ERROR;
3304 unsigned int nirefillentries = strtoul(CMD_ARGV[0], NULL, 0);
3305 unsigned int ndrefillentries = strtoul(CMD_ARGV[1], NULL, 0);
3306 if ((nirefillentries != 16) && (nirefillentries != 32)) {
3307 LOG_ERROR("<nirefillentries> must be 16 or 32\n");
3308 return ERROR_COMMAND_ARGUMENT_INVALID;
3309 } else if ((ndrefillentries != 16) && (ndrefillentries != 32)) {
3310 LOG_ERROR("<ndrefillentries> must be 16 or 32\n");
3311 return ERROR_COMMAND_ARGUMENT_INVALID;
3314 xtensa->core_config->mmu.enabled = true;
3315 xtensa->core_config->mmu.itlb_entries_count = nirefillentries;
3316 xtensa->core_config->mmu.dtlb_entries_count = ndrefillentries;
3317 return ERROR_OK;
3320 COMMAND_HANDLER(xtensa_cmd_xtmmu)
3322 return CALL_COMMAND_HANDLER(xtensa_cmd_xtmmu_do,
3323 target_to_xtensa(get_current_target(CMD_CTX)));
3326 /* xtregs <numregs>
3327 * xtreg <regname> <regnum> */
3328 COMMAND_HELPER(xtensa_cmd_xtreg_do, struct xtensa *xtensa)
3330 if (CMD_ARGC == 1) {
3331 int32_t numregs = strtoul(CMD_ARGV[0], NULL, 0);
3332 if ((numregs <= 0) || (numregs > UINT16_MAX)) {
3333 LOG_ERROR("xtreg <numregs>: Invalid 'numregs' (%d)", numregs);
3334 return ERROR_COMMAND_SYNTAX_ERROR;
3336 if ((xtensa->genpkt_regs_num > 0) && (numregs < (int32_t)xtensa->genpkt_regs_num)) {
3337 LOG_ERROR("xtregs (%d) must be larger than numgenregs (%d) (if xtregfmt specified)",
3338 numregs, xtensa->genpkt_regs_num);
3339 return ERROR_COMMAND_SYNTAX_ERROR;
3341 xtensa->total_regs_num = numregs;
3342 xtensa->core_regs_num = 0;
3343 xtensa->num_optregs = 0;
3344 /* A little more memory than required, but saves a second initialization pass */
3345 xtensa->optregs = calloc(xtensa->total_regs_num, sizeof(struct xtensa_reg_desc));
3346 if (!xtensa->optregs) {
3347 LOG_ERROR("Failed to allocate xtensa->optregs!");
3348 return ERROR_FAIL;
3350 return ERROR_OK;
3351 } else if (CMD_ARGC != 2) {
3352 return ERROR_COMMAND_SYNTAX_ERROR;
3355 /* "xtregfmt contiguous" must be specified prior to the first "xtreg" definition
3356 * if general register (g-packet) requests or contiguous register maps are supported */
3357 if (xtensa->regmap_contiguous && !xtensa->contiguous_regs_desc) {
3358 xtensa->contiguous_regs_desc = calloc(xtensa->total_regs_num, sizeof(struct xtensa_reg_desc *));
3359 if (!xtensa->contiguous_regs_desc) {
3360 LOG_ERROR("Failed to allocate xtensa->contiguous_regs_desc!");
3361 return ERROR_FAIL;
3365 const char *regname = CMD_ARGV[0];
3366 unsigned int regnum = strtoul(CMD_ARGV[1], NULL, 0);
3367 if (regnum > UINT16_MAX) {
3368 LOG_ERROR("<regnum> must be a 16-bit number");
3369 return ERROR_COMMAND_ARGUMENT_INVALID;
3372 if ((xtensa->num_optregs + xtensa->core_regs_num) >= xtensa->total_regs_num) {
3373 if (xtensa->total_regs_num)
3374 LOG_ERROR("'xtreg %s 0x%04x': Too many registers (%d expected, %d core %d extended)",
3375 regname, regnum,
3376 xtensa->total_regs_num, xtensa->core_regs_num, xtensa->num_optregs);
3377 else
3378 LOG_ERROR("'xtreg %s 0x%04x': Number of registers unspecified",
3379 regname, regnum);
3380 return ERROR_FAIL;
3383 /* Determine whether register belongs in xtensa_regs[] or xtensa->xtensa_spec_regs[] */
3384 struct xtensa_reg_desc *rptr = &xtensa->optregs[xtensa->num_optregs];
3385 bool is_extended_reg = true;
3386 unsigned int ridx;
3387 for (ridx = 0; ridx < XT_NUM_REGS; ridx++) {
3388 if (strcmp(CMD_ARGV[0], xtensa_regs[ridx].name) == 0) {
3389 /* Flag core register as defined */
3390 rptr = &xtensa_regs[ridx];
3391 xtensa->core_regs_num++;
3392 is_extended_reg = false;
3393 break;
3397 rptr->exist = true;
3398 if (is_extended_reg) {
3399 /* Register ID, debugger-visible register ID */
3400 rptr->name = strdup(CMD_ARGV[0]);
3401 rptr->dbreg_num = regnum;
3402 rptr->reg_num = (regnum & XT_REG_INDEX_MASK);
3403 xtensa->num_optregs++;
3405 /* Register type */
3406 if ((regnum & XT_REG_GENERAL_MASK) == XT_REG_GENERAL_VAL) {
3407 rptr->type = XT_REG_GENERAL;
3408 } else if ((regnum & XT_REG_USER_MASK) == XT_REG_USER_VAL) {
3409 rptr->type = XT_REG_USER;
3410 } else if ((regnum & XT_REG_FR_MASK) == XT_REG_FR_VAL) {
3411 rptr->type = XT_REG_FR;
3412 } else if ((regnum & XT_REG_SPECIAL_MASK) == XT_REG_SPECIAL_VAL) {
3413 rptr->type = XT_REG_SPECIAL;
3414 } else if ((regnum & XT_REG_RELGEN_MASK) == XT_REG_RELGEN_VAL) {
3415 /* WARNING: For these registers, regnum points to the
3416 * index of the corresponding ARx registers, NOT to
3417 * the processor register number! */
3418 rptr->type = XT_REG_RELGEN;
3419 rptr->reg_num += XT_REG_IDX_ARFIRST;
3420 rptr->dbreg_num += XT_REG_IDX_ARFIRST;
3421 } else if ((regnum & XT_REG_TIE_MASK) != 0) {
3422 rptr->type = XT_REG_TIE;
3423 } else {
3424 rptr->type = XT_REG_OTHER;
3427 /* Register flags */
3428 if ((strcmp(rptr->name, "mmid") == 0) || (strcmp(rptr->name, "eraccess") == 0) ||
3429 (strcmp(rptr->name, "ddr") == 0) || (strcmp(rptr->name, "intset") == 0) ||
3430 (strcmp(rptr->name, "intclear") == 0))
3431 rptr->flags = XT_REGF_NOREAD;
3432 else
3433 rptr->flags = 0;
3435 if ((rptr->reg_num == (XT_PS_REG_NUM_BASE + xtensa->core_config->debug.irq_level)) &&
3436 (xtensa->core_config->core_type == XT_LX) && (rptr->type == XT_REG_SPECIAL)) {
3437 xtensa->eps_dbglevel_idx = XT_NUM_REGS + xtensa->num_optregs - 1;
3438 LOG_DEBUG("Setting PS (%s) index to %d", rptr->name, xtensa->eps_dbglevel_idx);
3440 } else if (strcmp(rptr->name, "cpenable") == 0) {
3441 xtensa->core_config->coproc = true;
3444 /* Build out list of contiguous registers in specified order */
3445 unsigned int running_reg_count = xtensa->num_optregs + xtensa->core_regs_num;
3446 if (xtensa->contiguous_regs_desc) {
3447 assert((running_reg_count <= xtensa->total_regs_num) && "contiguous register address internal error!");
3448 xtensa->contiguous_regs_desc[running_reg_count - 1] = rptr;
3450 if (xtensa_extra_debug_log)
3451 LOG_DEBUG("Added %s register %-16s: 0x%04x/0x%02x t%d (%d of %d)",
3452 is_extended_reg ? "config-specific" : "core",
3453 rptr->name, rptr->dbreg_num, rptr->reg_num, rptr->type,
3454 is_extended_reg ? xtensa->num_optregs : ridx,
3455 is_extended_reg ? xtensa->total_regs_num : XT_NUM_REGS);
3456 return ERROR_OK;
3459 COMMAND_HANDLER(xtensa_cmd_xtreg)
3461 return CALL_COMMAND_HANDLER(xtensa_cmd_xtreg_do,
3462 target_to_xtensa(get_current_target(CMD_CTX)));
3465 /* xtregfmt <contiguous|sparse> [numgregs] */
3466 COMMAND_HELPER(xtensa_cmd_xtregfmt_do, struct xtensa *xtensa)
3468 if ((CMD_ARGC == 1) || (CMD_ARGC == 2)) {
3469 if (!strcasecmp(CMD_ARGV[0], "sparse")) {
3470 return ERROR_OK;
3471 } else if (!strcasecmp(CMD_ARGV[0], "contiguous")) {
3472 xtensa->regmap_contiguous = true;
3473 if (CMD_ARGC == 2) {
3474 unsigned int numgregs = strtoul(CMD_ARGV[1], NULL, 0);
3475 if ((numgregs <= 0) ||
3476 ((numgregs > xtensa->total_regs_num) &&
3477 (xtensa->total_regs_num > 0))) {
3478 LOG_ERROR("xtregfmt: if specified, numgregs (%d) must be <= numregs (%d)",
3479 numgregs, xtensa->total_regs_num);
3480 return ERROR_COMMAND_SYNTAX_ERROR;
3482 xtensa->genpkt_regs_num = numgregs;
3484 return ERROR_OK;
3487 return ERROR_COMMAND_SYNTAX_ERROR;
3490 COMMAND_HANDLER(xtensa_cmd_xtregfmt)
3492 return CALL_COMMAND_HANDLER(xtensa_cmd_xtregfmt_do,
3493 target_to_xtensa(get_current_target(CMD_CTX)));
3496 COMMAND_HELPER(xtensa_cmd_permissive_mode_do, struct xtensa *xtensa)
3498 return CALL_COMMAND_HANDLER(handle_command_parse_bool,
3499 &xtensa->permissive_mode, "xtensa permissive mode");
3502 COMMAND_HANDLER(xtensa_cmd_permissive_mode)
3504 return CALL_COMMAND_HANDLER(xtensa_cmd_permissive_mode_do,
3505 target_to_xtensa(get_current_target(CMD_CTX)));
3508 /* perfmon_enable <counter_id> <select> [mask] [kernelcnt] [tracelevel] */
3509 COMMAND_HELPER(xtensa_cmd_perfmon_enable_do, struct xtensa *xtensa)
3511 struct xtensa_perfmon_config config = {
3512 .mask = 0xffff,
3513 .kernelcnt = 0,
3514 .tracelevel = -1 /* use DEBUGLEVEL by default */
3517 if (CMD_ARGC < 2 || CMD_ARGC > 6)
3518 return ERROR_COMMAND_SYNTAX_ERROR;
3520 unsigned int counter_id = strtoul(CMD_ARGV[0], NULL, 0);
3521 if (counter_id >= XTENSA_MAX_PERF_COUNTERS) {
3522 command_print(CMD, "counter_id should be < %d", XTENSA_MAX_PERF_COUNTERS);
3523 return ERROR_COMMAND_ARGUMENT_INVALID;
3526 config.select = strtoul(CMD_ARGV[1], NULL, 0);
3527 if (config.select > XTENSA_MAX_PERF_SELECT) {
3528 command_print(CMD, "select should be < %d", XTENSA_MAX_PERF_SELECT);
3529 return ERROR_COMMAND_ARGUMENT_INVALID;
3532 if (CMD_ARGC >= 3) {
3533 config.mask = strtoul(CMD_ARGV[2], NULL, 0);
3534 if (config.mask > XTENSA_MAX_PERF_MASK) {
3535 command_print(CMD, "mask should be < %d", XTENSA_MAX_PERF_MASK);
3536 return ERROR_COMMAND_ARGUMENT_INVALID;
3540 if (CMD_ARGC >= 4) {
3541 config.kernelcnt = strtoul(CMD_ARGV[3], NULL, 0);
3542 if (config.kernelcnt > 1) {
3543 command_print(CMD, "kernelcnt should be 0 or 1");
3544 return ERROR_COMMAND_ARGUMENT_INVALID;
3548 if (CMD_ARGC >= 5) {
3549 config.tracelevel = strtoul(CMD_ARGV[4], NULL, 0);
3550 if (config.tracelevel > 7) {
3551 command_print(CMD, "tracelevel should be <=7");
3552 return ERROR_COMMAND_ARGUMENT_INVALID;
3556 if (config.tracelevel == -1)
3557 config.tracelevel = xtensa->core_config->debug.irq_level;
3559 return xtensa_dm_perfmon_enable(&xtensa->dbg_mod, counter_id, &config);
3562 COMMAND_HANDLER(xtensa_cmd_perfmon_enable)
3564 return CALL_COMMAND_HANDLER(xtensa_cmd_perfmon_enable_do,
3565 target_to_xtensa(get_current_target(CMD_CTX)));
3568 /* perfmon_dump [counter_id] */
3569 COMMAND_HELPER(xtensa_cmd_perfmon_dump_do, struct xtensa *xtensa)
3571 if (CMD_ARGC > 1)
3572 return ERROR_COMMAND_SYNTAX_ERROR;
3574 int counter_id = -1;
3575 if (CMD_ARGC == 1) {
3576 counter_id = strtol(CMD_ARGV[0], NULL, 0);
3577 if (counter_id > XTENSA_MAX_PERF_COUNTERS) {
3578 command_print(CMD, "counter_id should be < %d", XTENSA_MAX_PERF_COUNTERS);
3579 return ERROR_COMMAND_ARGUMENT_INVALID;
3583 unsigned int counter_start = (counter_id < 0) ? 0 : counter_id;
3584 unsigned int counter_end = (counter_id < 0) ? XTENSA_MAX_PERF_COUNTERS : counter_id + 1;
3585 for (unsigned int counter = counter_start; counter < counter_end; ++counter) {
3586 char result_buf[128] = { 0 };
3587 size_t result_pos = snprintf(result_buf, sizeof(result_buf), "Counter %d: ", counter);
3588 struct xtensa_perfmon_result result;
3589 int res = xtensa_dm_perfmon_dump(&xtensa->dbg_mod, counter, &result);
3590 if (res != ERROR_OK)
3591 return res;
3592 snprintf(result_buf + result_pos, sizeof(result_buf) - result_pos,
3593 "%-12" PRIu64 "%s",
3594 result.value,
3595 result.overflow ? " (overflow)" : "");
3596 LOG_INFO("%s", result_buf);
3599 return ERROR_OK;
3602 COMMAND_HANDLER(xtensa_cmd_perfmon_dump)
3604 return CALL_COMMAND_HANDLER(xtensa_cmd_perfmon_dump_do,
3605 target_to_xtensa(get_current_target(CMD_CTX)));
3608 COMMAND_HELPER(xtensa_cmd_mask_interrupts_do, struct xtensa *xtensa)
3610 int state = -1;
3612 if (CMD_ARGC < 1) {
3613 const char *st;
3614 state = xtensa->stepping_isr_mode;
3615 if (state == XT_STEPPING_ISR_ON)
3616 st = "OFF";
3617 else if (state == XT_STEPPING_ISR_OFF)
3618 st = "ON";
3619 else
3620 st = "UNKNOWN";
3621 command_print(CMD, "Current ISR step mode: %s", st);
3622 return ERROR_OK;
3624 /* Masking is ON -> interrupts during stepping are OFF, and vice versa */
3625 if (!strcasecmp(CMD_ARGV[0], "off"))
3626 state = XT_STEPPING_ISR_ON;
3627 else if (!strcasecmp(CMD_ARGV[0], "on"))
3628 state = XT_STEPPING_ISR_OFF;
3630 if (state == -1) {
3631 command_print(CMD, "Argument unknown. Please pick one of ON, OFF");
3632 return ERROR_FAIL;
3634 xtensa->stepping_isr_mode = state;
3635 return ERROR_OK;
3638 COMMAND_HANDLER(xtensa_cmd_mask_interrupts)
3640 return CALL_COMMAND_HANDLER(xtensa_cmd_mask_interrupts_do,
3641 target_to_xtensa(get_current_target(CMD_CTX)));
3644 COMMAND_HELPER(xtensa_cmd_smpbreak_do, struct target *target)
3646 int res;
3647 uint32_t val = 0;
3649 if (CMD_ARGC >= 1) {
3650 for (unsigned int i = 0; i < CMD_ARGC; i++) {
3651 if (!strcasecmp(CMD_ARGV[0], "none")) {
3652 val = 0;
3653 } else if (!strcasecmp(CMD_ARGV[i], "BreakIn")) {
3654 val |= OCDDCR_BREAKINEN;
3655 } else if (!strcasecmp(CMD_ARGV[i], "BreakOut")) {
3656 val |= OCDDCR_BREAKOUTEN;
3657 } else if (!strcasecmp(CMD_ARGV[i], "RunStallIn")) {
3658 val |= OCDDCR_RUNSTALLINEN;
3659 } else if (!strcasecmp(CMD_ARGV[i], "DebugModeOut")) {
3660 val |= OCDDCR_DEBUGMODEOUTEN;
3661 } else if (!strcasecmp(CMD_ARGV[i], "BreakInOut")) {
3662 val |= OCDDCR_BREAKINEN | OCDDCR_BREAKOUTEN;
3663 } else if (!strcasecmp(CMD_ARGV[i], "RunStall")) {
3664 val |= OCDDCR_RUNSTALLINEN | OCDDCR_DEBUGMODEOUTEN;
3665 } else {
3666 command_print(CMD, "Unknown arg %s", CMD_ARGV[i]);
3667 command_print(
3668 CMD,
3669 "use either BreakInOut, None or RunStall as arguments, or any combination of BreakIn, BreakOut, RunStallIn and DebugModeOut.");
3670 return ERROR_OK;
3673 res = xtensa_smpbreak_set(target, val);
3674 if (res != ERROR_OK)
3675 command_print(CMD, "Failed to set smpbreak config %d", res);
3676 } else {
3677 struct xtensa *xtensa = target_to_xtensa(target);
3678 res = xtensa_smpbreak_read(xtensa, &val);
3679 if (res == ERROR_OK)
3680 command_print(CMD, "Current bits set:%s%s%s%s",
3681 (val & OCDDCR_BREAKINEN) ? " BreakIn" : "",
3682 (val & OCDDCR_BREAKOUTEN) ? " BreakOut" : "",
3683 (val & OCDDCR_RUNSTALLINEN) ? " RunStallIn" : "",
3684 (val & OCDDCR_DEBUGMODEOUTEN) ? " DebugModeOut" : ""
3686 else
3687 command_print(CMD, "Failed to get smpbreak config %d", res);
3689 return res;
3692 COMMAND_HANDLER(xtensa_cmd_smpbreak)
3694 return CALL_COMMAND_HANDLER(xtensa_cmd_smpbreak_do,
3695 get_current_target(CMD_CTX));
3698 COMMAND_HELPER(xtensa_cmd_tracestart_do, struct xtensa *xtensa)
3700 struct xtensa_trace_status trace_status;
3701 struct xtensa_trace_start_config cfg = {
3702 .stoppc = 0,
3703 .stopmask = XTENSA_STOPMASK_DISABLED,
3704 .after = 0,
3705 .after_is_words = false
3708 /* Parse arguments */
3709 for (unsigned int i = 0; i < CMD_ARGC; i++) {
3710 if ((!strcasecmp(CMD_ARGV[i], "pc")) && CMD_ARGC > i) {
3711 char *e;
3712 i++;
3713 cfg.stoppc = strtol(CMD_ARGV[i], &e, 0);
3714 cfg.stopmask = 0;
3715 if (*e == '/')
3716 cfg.stopmask = strtol(e, NULL, 0);
3717 } else if ((!strcasecmp(CMD_ARGV[i], "after")) && CMD_ARGC > i) {
3718 i++;
3719 cfg.after = strtol(CMD_ARGV[i], NULL, 0);
3720 } else if (!strcasecmp(CMD_ARGV[i], "ins")) {
3721 cfg.after_is_words = 0;
3722 } else if (!strcasecmp(CMD_ARGV[i], "words")) {
3723 cfg.after_is_words = 1;
3724 } else {
3725 command_print(CMD, "Did not understand %s", CMD_ARGV[i]);
3726 return ERROR_FAIL;
3730 int res = xtensa_dm_trace_status_read(&xtensa->dbg_mod, &trace_status);
3731 if (res != ERROR_OK)
3732 return res;
3733 if (trace_status.stat & TRAXSTAT_TRACT) {
3734 LOG_WARNING("Silently stop active tracing!");
3735 res = xtensa_dm_trace_stop(&xtensa->dbg_mod, false);
3736 if (res != ERROR_OK)
3737 return res;
3740 res = xtensa_dm_trace_start(&xtensa->dbg_mod, &cfg);
3741 if (res != ERROR_OK)
3742 return res;
3744 xtensa->trace_active = true;
3745 command_print(CMD, "Trace started.");
3746 return ERROR_OK;
3749 COMMAND_HANDLER(xtensa_cmd_tracestart)
3751 return CALL_COMMAND_HANDLER(xtensa_cmd_tracestart_do,
3752 target_to_xtensa(get_current_target(CMD_CTX)));
3755 COMMAND_HELPER(xtensa_cmd_tracestop_do, struct xtensa *xtensa)
3757 struct xtensa_trace_status trace_status;
3759 int res = xtensa_dm_trace_status_read(&xtensa->dbg_mod, &trace_status);
3760 if (res != ERROR_OK)
3761 return res;
3763 if (!(trace_status.stat & TRAXSTAT_TRACT)) {
3764 command_print(CMD, "No trace is currently active.");
3765 return ERROR_FAIL;
3768 res = xtensa_dm_trace_stop(&xtensa->dbg_mod, true);
3769 if (res != ERROR_OK)
3770 return res;
3772 xtensa->trace_active = false;
3773 command_print(CMD, "Trace stop triggered.");
3774 return ERROR_OK;
3777 COMMAND_HANDLER(xtensa_cmd_tracestop)
3779 return CALL_COMMAND_HANDLER(xtensa_cmd_tracestop_do,
3780 target_to_xtensa(get_current_target(CMD_CTX)));
3783 COMMAND_HELPER(xtensa_cmd_tracedump_do, struct xtensa *xtensa, const char *fname)
3785 struct xtensa_trace_config trace_config;
3786 struct xtensa_trace_status trace_status;
3787 uint32_t memsz, wmem;
3789 int res = xtensa_dm_trace_status_read(&xtensa->dbg_mod, &trace_status);
3790 if (res != ERROR_OK)
3791 return res;
3793 if (trace_status.stat & TRAXSTAT_TRACT) {
3794 command_print(CMD, "Tracing is still active. Please stop it first.");
3795 return ERROR_FAIL;
3798 res = xtensa_dm_trace_config_read(&xtensa->dbg_mod, &trace_config);
3799 if (res != ERROR_OK)
3800 return res;
3802 if (!(trace_config.ctrl & TRAXCTRL_TREN)) {
3803 command_print(CMD, "No active trace found; nothing to dump.");
3804 return ERROR_FAIL;
3807 memsz = trace_config.memaddr_end - trace_config.memaddr_start + 1;
3808 LOG_INFO("Total trace memory: %d words", memsz);
3809 if ((trace_config.addr &
3810 ((TRAXADDR_TWRAP_MASK << TRAXADDR_TWRAP_SHIFT) | TRAXADDR_TWSAT)) == 0) {
3811 /*Memory hasn't overwritten itself yet. */
3812 wmem = trace_config.addr & TRAXADDR_TADDR_MASK;
3813 LOG_INFO("...but trace is only %d words", wmem);
3814 if (wmem < memsz)
3815 memsz = wmem;
3816 } else {
3817 if (trace_config.addr & TRAXADDR_TWSAT) {
3818 LOG_INFO("Real trace is many times longer than that (overflow)");
3819 } else {
3820 uint32_t trc_sz = (trace_config.addr >> TRAXADDR_TWRAP_SHIFT) & TRAXADDR_TWRAP_MASK;
3821 trc_sz = (trc_sz * memsz) + (trace_config.addr & TRAXADDR_TADDR_MASK);
3822 LOG_INFO("Real trace is %d words, but the start has been truncated.", trc_sz);
3826 uint8_t *tracemem = malloc(memsz * 4);
3827 if (!tracemem) {
3828 command_print(CMD, "Failed to alloc memory for trace data!");
3829 return ERROR_FAIL;
3831 res = xtensa_dm_trace_data_read(&xtensa->dbg_mod, tracemem, memsz * 4);
3832 if (res != ERROR_OK) {
3833 free(tracemem);
3834 return res;
3837 int f = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0666);
3838 if (f <= 0) {
3839 free(tracemem);
3840 command_print(CMD, "Unable to open file %s", fname);
3841 return ERROR_FAIL;
3843 if (write(f, tracemem, memsz * 4) != (int)memsz * 4)
3844 command_print(CMD, "Unable to write to file %s", fname);
3845 else
3846 command_print(CMD, "Written %d bytes of trace data to %s", memsz * 4, fname);
3847 close(f);
3849 bool is_all_zeroes = true;
3850 for (unsigned int i = 0; i < memsz * 4; i++) {
3851 if (tracemem[i] != 0) {
3852 is_all_zeroes = false;
3853 break;
3856 free(tracemem);
3857 if (is_all_zeroes)
3858 command_print(
3859 CMD,
3860 "WARNING: File written is all zeroes. Are you sure you enabled trace memory?");
3862 return ERROR_OK;
3865 COMMAND_HANDLER(xtensa_cmd_tracedump)
3867 if (CMD_ARGC != 1) {
3868 command_print(CMD, "Command takes exactly 1 parameter.Need filename to dump to as output!");
3869 return ERROR_FAIL;
3872 return CALL_COMMAND_HANDLER(xtensa_cmd_tracedump_do,
3873 target_to_xtensa(get_current_target(CMD_CTX)), CMD_ARGV[0]);
3876 static const struct command_registration xtensa_any_command_handlers[] = {
3878 .name = "xtdef",
3879 .handler = xtensa_cmd_xtdef,
3880 .mode = COMMAND_CONFIG,
3881 .help = "Configure Xtensa core type",
3882 .usage = "<type>",
3885 .name = "xtopt",
3886 .handler = xtensa_cmd_xtopt,
3887 .mode = COMMAND_CONFIG,
3888 .help = "Configure Xtensa core option",
3889 .usage = "<name> <value>",
3892 .name = "xtmem",
3893 .handler = xtensa_cmd_xtmem,
3894 .mode = COMMAND_CONFIG,
3895 .help = "Configure Xtensa memory/cache option",
3896 .usage = "<type> [parameters]",
3899 .name = "xtmmu",
3900 .handler = xtensa_cmd_xtmmu,
3901 .mode = COMMAND_CONFIG,
3902 .help = "Configure Xtensa MMU option",
3903 .usage = "<NIREFILLENTRIES> <NDREFILLENTRIES> <IVARWAY56> <DVARWAY56>",
3906 .name = "xtmpu",
3907 .handler = xtensa_cmd_xtmpu,
3908 .mode = COMMAND_CONFIG,
3909 .help = "Configure Xtensa MPU option",
3910 .usage = "<num FG seg> <min seg size> <lockable> <executeonly>",
3913 .name = "xtreg",
3914 .handler = xtensa_cmd_xtreg,
3915 .mode = COMMAND_CONFIG,
3916 .help = "Configure Xtensa register",
3917 .usage = "<regname> <regnum>",
3920 .name = "xtregs",
3921 .handler = xtensa_cmd_xtreg,
3922 .mode = COMMAND_CONFIG,
3923 .help = "Configure number of Xtensa registers",
3924 .usage = "<numregs>",
3927 .name = "xtregfmt",
3928 .handler = xtensa_cmd_xtregfmt,
3929 .mode = COMMAND_CONFIG,
3930 .help = "Configure format of Xtensa register map",
3931 .usage = "<contiguous|sparse> [numgregs]",
3934 .name = "set_permissive",
3935 .handler = xtensa_cmd_permissive_mode,
3936 .mode = COMMAND_ANY,
3937 .help = "When set to 1, enable Xtensa permissive mode (fewer client-side checks)",
3938 .usage = "[0|1]",
3941 .name = "maskisr",
3942 .handler = xtensa_cmd_mask_interrupts,
3943 .mode = COMMAND_ANY,
3944 .help = "mask Xtensa interrupts at step",
3945 .usage = "['on'|'off']",
3948 .name = "smpbreak",
3949 .handler = xtensa_cmd_smpbreak,
3950 .mode = COMMAND_ANY,
3951 .help = "Set the way the CPU chains OCD breaks",
3952 .usage = "[none|breakinout|runstall] | [BreakIn] [BreakOut] [RunStallIn] [DebugModeOut]",
3955 .name = "perfmon_enable",
3956 .handler = xtensa_cmd_perfmon_enable,
3957 .mode = COMMAND_EXEC,
3958 .help = "Enable and start performance counter",
3959 .usage = "<counter_id> <select> [mask] [kernelcnt] [tracelevel]",
3962 .name = "perfmon_dump",
3963 .handler = xtensa_cmd_perfmon_dump,
3964 .mode = COMMAND_EXEC,
3965 .help = "Dump performance counter value. If no argument specified, dumps all counters.",
3966 .usage = "[counter_id]",
3969 .name = "tracestart",
3970 .handler = xtensa_cmd_tracestart,
3971 .mode = COMMAND_EXEC,
3972 .help =
3973 "Tracing: Set up and start a trace. Optionally set stop trigger address and amount of data captured after.",
3974 .usage = "[pc <pcval>/[maskbitcount]] [after <n> [ins|words]]",
3977 .name = "tracestop",
3978 .handler = xtensa_cmd_tracestop,
3979 .mode = COMMAND_EXEC,
3980 .help = "Tracing: Stop current trace as started by the tracestart command",
3981 .usage = "",
3984 .name = "tracedump",
3985 .handler = xtensa_cmd_tracedump,
3986 .mode = COMMAND_EXEC,
3987 .help = "Tracing: Dump trace memory to a files. One file per core.",
3988 .usage = "<outfile>",
3991 .name = "exe",
3992 .handler = xtensa_cmd_exe,
3993 .mode = COMMAND_ANY,
3994 .help = "Xtensa stub execution",
3995 .usage = "<ascii-encoded hexadecimal instruction bytes>",
3997 COMMAND_REGISTRATION_DONE
4000 const struct command_registration xtensa_command_handlers[] = {
4002 .name = "xtensa",
4003 .mode = COMMAND_ANY,
4004 .help = "Xtensa command group",
4005 .usage = "",
4006 .chain = xtensa_any_command_handlers,
4008 COMMAND_REGISTRATION_DONE