OpenOCD
xtensa.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
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  ***************************************************************************/
10 
11 #ifdef HAVE_CONFIG_H
12 #include "config.h"
13 #endif
14 
15 #include <stdlib.h>
16 #include <helper/time_support.h>
17 #include <helper/align.h>
18 #include <target/register.h>
19 #include <target/algorithm.h>
20 
21 #include "xtensa_chip.h"
22 #include "xtensa.h"
23 
24 /* Swap 4-bit Xtensa opcodes and fields */
25 #define XT_NIBSWAP8(V) \
26  ((((V) & 0x0F) << 4) \
27  | (((V) & 0xF0) >> 4))
28 
29 #define XT_NIBSWAP16(V) \
30  ((((V) & 0x000F) << 12) \
31  | (((V) & 0x00F0) << 4) \
32  | (((V) & 0x0F00) >> 4) \
33  | (((V) & 0xF000) >> 12))
34 
35 #define XT_NIBSWAP24(V) \
36  ((((V) & 0x00000F) << 20) \
37  | (((V) & 0x0000F0) << 12) \
38  | (((V) & 0x000F00) << 4) \
39  | (((V) & 0x00F000) >> 4) \
40  | (((V) & 0x0F0000) >> 12) \
41  | (((V) & 0xF00000) >> 20))
42 
43 /* _XT_INS_FORMAT_*()
44  * Instruction formatting converted from little-endian inputs
45  * and shifted to the MSB-side of DIR for BE systems.
46  */
47 #define _XT_INS_FORMAT_RSR(X, OPCODE, SR, T) \
48  (XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE) \
49  | (((T) & 0x0F) << 16) \
50  | (((SR) & 0xFF) << 8)) << 8 \
51  : (OPCODE) \
52  | (((SR) & 0xFF) << 8) \
53  | (((T) & 0x0F) << 4))
54 
55 #define _XT_INS_FORMAT_RRR(X, OPCODE, ST, R) \
56  (XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE) \
57  | ((XT_NIBSWAP8((ST) & 0xFF)) << 12) \
58  | (((R) & 0x0F) << 8)) << 8 \
59  : (OPCODE) \
60  | (((ST) & 0xFF) << 4) \
61  | (((R) & 0x0F) << 12))
62 
63 #define _XT_INS_FORMAT_RRRN(X, OPCODE, S, T, IMM4) \
64  (XT_ISBE(X) ? (XT_NIBSWAP16(OPCODE) \
65  | (((T) & 0x0F) << 8) \
66  | (((S) & 0x0F) << 4) \
67  | ((IMM4) & 0x0F)) << 16 \
68  : (OPCODE) \
69  | (((T) & 0x0F) << 4) \
70  | (((S) & 0x0F) << 8) \
71  | (((IMM4) & 0x0F) << 12))
72 
73 #define _XT_INS_FORMAT_RRI8(X, OPCODE, R, S, T, IMM8) \
74  (XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE) \
75  | (((T) & 0x0F) << 16) \
76  | (((S) & 0x0F) << 12) \
77  | (((R) & 0x0F) << 8) \
78  | ((IMM8) & 0xFF)) << 8 \
79  : (OPCODE) \
80  | (((IMM8) & 0xFF) << 16) \
81  | (((R) & 0x0F) << 12) \
82  | (((S) & 0x0F) << 8) \
83  | (((T) & 0x0F) << 4))
84 
85 #define _XT_INS_FORMAT_RRI4(X, OPCODE, IMM4, R, S, T) \
86  (XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE) \
87  | (((T) & 0x0F) << 16) \
88  | (((S) & 0x0F) << 12) \
89  | (((R) & 0x0F) << 8)) << 8 \
90  | ((IMM4) & 0x0F) \
91  : (OPCODE) \
92  | (((IMM4) & 0x0F) << 20) \
93  | (((R) & 0x0F) << 12) \
94  | (((S) & 0x0F) << 8) \
95  | (((T) & 0x0F) << 4))
96 
97 /* Xtensa processor instruction opcodes
98 */
99 /* "Return From Debug Operation" to Normal */
100 #define XT_INS_RFDO(X) (XT_ISBE(X) ? 0x000e1f << 8 : 0xf1e000)
101 /* "Return From Debug and Dispatch" - allow sw debugging stuff to take over */
102 #define XT_INS_RFDD(X) (XT_ISBE(X) ? 0x010e1f << 8 : 0xf1e010)
103 
104 /* Load to DDR register, increase addr register */
105 #define XT_INS_LDDR32P(X, S) (XT_ISBE(X) ? (0x0E0700 | ((S) << 12)) << 8 : (0x0070E0 | ((S) << 8)))
106 /* Store from DDR register, increase addr register */
107 #define XT_INS_SDDR32P(X, S) (XT_ISBE(X) ? (0x0F0700 | ((S) << 12)) << 8 : (0x0070F0 | ((S) << 8)))
108 
109 /* Load 32-bit Indirect from A(S)+4*IMM8 to A(T) */
110 #define XT_INS_L32I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x002002, 0, S, T, IMM8)
111 /* Load 16-bit Unsigned from A(S)+2*IMM8 to A(T) */
112 #define XT_INS_L16UI(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x001002, 0, S, T, IMM8)
113 /* Load 8-bit Unsigned from A(S)+IMM8 to A(T) */
114 #define XT_INS_L8UI(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x000002, 0, S, T, IMM8)
115 
116 /* Store 32-bit Indirect to A(S)+4*IMM8 from A(T) */
117 #define XT_INS_S32I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x006002, 0, S, T, IMM8)
118 /* Store 16-bit to A(S)+2*IMM8 from A(T) */
119 #define XT_INS_S16I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x005002, 0, S, T, IMM8)
120 /* Store 8-bit to A(S)+IMM8 from A(T) */
121 #define XT_INS_S8I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x004002, 0, S, T, IMM8)
122 
123 /* Cache Instructions */
124 #define XT_INS_IHI(X, S, IMM8) _XT_INS_FORMAT_RRI8(X, 0x0070E2, 0, S, 0, IMM8)
125 #define XT_INS_DHWBI(X, S, IMM8) _XT_INS_FORMAT_RRI8(X, 0x007052, 0, S, 0, IMM8)
126 #define XT_INS_DHWB(X, S, IMM8) _XT_INS_FORMAT_RRI8(X, 0x007042, 0, S, 0, IMM8)
127 #define XT_INS_ISYNC(X) (XT_ISBE(X) ? 0x000200 << 8 : 0x002000)
128 
129 /* Control Instructions */
130 #define XT_INS_JX(X, S) (XT_ISBE(X) ? (0x050000 | ((S) << 12)) : (0x0000a0 | ((S) << 8)))
131 #define XT_INS_CALL0(X, IMM18) (XT_ISBE(X) ? (0x500000 | ((IMM18) & 0x3ffff)) : (0x000005 | (((IMM18) & 0x3ffff) << 6)))
132 
133 /* Read Special Register */
134 #define XT_INS_RSR(X, SR, T) _XT_INS_FORMAT_RSR(X, 0x030000, SR, T)
135 /* Write Special Register */
136 #define XT_INS_WSR(X, SR, T) _XT_INS_FORMAT_RSR(X, 0x130000, SR, T)
137 /* Swap Special Register */
138 #define XT_INS_XSR(X, SR, T) _XT_INS_FORMAT_RSR(X, 0x610000, SR, T)
139 
140 /* Rotate Window by (-8..7) */
141 #define XT_INS_ROTW(X, N) (XT_ISBE(X) ? ((0x000804) | (((N) & 15) << 16)) << 8 : ((0x408000) | (((N) & 15) << 4)))
142 
143 /* Read User Register */
144 #define XT_INS_RUR(X, UR, T) _XT_INS_FORMAT_RRR(X, 0xE30000, UR, T)
145 /* Write User Register */
146 #define XT_INS_WUR(X, UR, T) _XT_INS_FORMAT_RSR(X, 0xF30000, UR, T)
147 
148 /* Read Floating-Point Register */
149 #define XT_INS_RFR(X, FR, T) _XT_INS_FORMAT_RRR(X, 0xFA0000, ((FR << 4) | 0x4), T)
150 /* Write Floating-Point Register */
151 #define XT_INS_WFR(X, FR, T) _XT_INS_FORMAT_RRR(X, 0xFA0000, ((T << 4) | 0x5), FR)
152 
153 #define XT_INS_L32E(X, R, S, T) _XT_INS_FORMAT_RRI4(X, 0x090000, 0, R, S, T)
154 #define XT_INS_S32E(X, R, S, T) _XT_INS_FORMAT_RRI4(X, 0x490000, 0, R, S, T)
155 #define XT_INS_L32E_S32E_MASK(X) (XT_ISBE(X) ? 0xF000FF << 8 : 0xFF000F)
156 
157 #define XT_INS_RFWO(X) (XT_ISBE(X) ? 0x004300 << 8 : 0x003400)
158 #define XT_INS_RFWU(X) (XT_ISBE(X) ? 0x005300 << 8 : 0x003500)
159 #define XT_INS_RFWO_RFWU_MASK(X) (XT_ISBE(X) ? 0xFFFFFF << 8 : 0xFFFFFF)
160 
161 /* Read Protection TLB Entry Info */
162 #define XT_INS_PPTLB(X, S, T) _XT_INS_FORMAT_RRR(X, 0x500000, ((S) << 4) | (T), 0xD)
163 
164 #define XT_TLB1_ACC_SHIFT 8
165 #define XT_TLB1_ACC_MSK 0xF
166 
167 #define XT_WATCHPOINTS_NUM_MAX 2
168 
169 /* Special register number macro for DDR, PS, WB, A3, A4 registers.
170  * These get used a lot so making a shortcut is useful.
171  */
172 #define XT_SR_DDR (xtensa_regs[XT_REG_IDX_DDR].reg_num)
173 #define XT_SR_PS (xtensa_regs[XT_REG_IDX_PS].reg_num)
174 #define XT_SR_WB (xtensa_regs[XT_REG_IDX_WINDOWBASE].reg_num)
175 #define XT_REG_A0 (xtensa_regs[XT_REG_IDX_AR0].reg_num)
176 #define XT_REG_A3 (xtensa_regs[XT_REG_IDX_AR3].reg_num)
177 #define XT_REG_A4 (xtensa_regs[XT_REG_IDX_AR4].reg_num)
178 
179 #define XT_PS_REG_NUM (0xe6U)
180 #define XT_EPS_REG_NUM_BASE (0xc0U) /* (EPS2 - 2), for adding DBGLEVEL */
181 #define XT_EPC_REG_NUM_BASE (0xb0U) /* (EPC1 - 1), for adding DBGLEVEL */
182 #define XT_PC_REG_NUM_VIRTUAL (0xffU) /* Marker for computing PC (EPC[DBGLEVEL) */
183 #define XT_PC_DBREG_NUM_BASE (0x20U) /* External (i.e., GDB) access */
184 #define XT_NX_IBREAKC_BASE (0xc0U) /* (IBREAKC0..IBREAKC1) for NX */
185 
186 #define XT_SW_BREAKPOINTS_MAX_NUM 32
187 #define XT_HW_IBREAK_MAX_NUM 2
188 #define XT_HW_DBREAK_MAX_NUM 2
189 
192  XT_MK_REG_DESC("ar0", 0x00, XT_REG_GENERAL, 0),
193  XT_MK_REG_DESC("ar1", 0x01, XT_REG_GENERAL, 0),
194  XT_MK_REG_DESC("ar2", 0x02, XT_REG_GENERAL, 0),
195  XT_MK_REG_DESC("ar3", 0x03, XT_REG_GENERAL, 0),
196  XT_MK_REG_DESC("ar4", 0x04, XT_REG_GENERAL, 0),
197  XT_MK_REG_DESC("ar5", 0x05, XT_REG_GENERAL, 0),
198  XT_MK_REG_DESC("ar6", 0x06, XT_REG_GENERAL, 0),
199  XT_MK_REG_DESC("ar7", 0x07, XT_REG_GENERAL, 0),
200  XT_MK_REG_DESC("ar8", 0x08, XT_REG_GENERAL, 0),
201  XT_MK_REG_DESC("ar9", 0x09, XT_REG_GENERAL, 0),
202  XT_MK_REG_DESC("ar10", 0x0A, XT_REG_GENERAL, 0),
203  XT_MK_REG_DESC("ar11", 0x0B, XT_REG_GENERAL, 0),
204  XT_MK_REG_DESC("ar12", 0x0C, XT_REG_GENERAL, 0),
205  XT_MK_REG_DESC("ar13", 0x0D, XT_REG_GENERAL, 0),
206  XT_MK_REG_DESC("ar14", 0x0E, XT_REG_GENERAL, 0),
207  XT_MK_REG_DESC("ar15", 0x0F, XT_REG_GENERAL, 0),
208  XT_MK_REG_DESC("ar16", 0x10, XT_REG_GENERAL, 0),
209  XT_MK_REG_DESC("ar17", 0x11, XT_REG_GENERAL, 0),
210  XT_MK_REG_DESC("ar18", 0x12, XT_REG_GENERAL, 0),
211  XT_MK_REG_DESC("ar19", 0x13, XT_REG_GENERAL, 0),
212  XT_MK_REG_DESC("ar20", 0x14, XT_REG_GENERAL, 0),
213  XT_MK_REG_DESC("ar21", 0x15, XT_REG_GENERAL, 0),
214  XT_MK_REG_DESC("ar22", 0x16, XT_REG_GENERAL, 0),
215  XT_MK_REG_DESC("ar23", 0x17, XT_REG_GENERAL, 0),
216  XT_MK_REG_DESC("ar24", 0x18, XT_REG_GENERAL, 0),
217  XT_MK_REG_DESC("ar25", 0x19, XT_REG_GENERAL, 0),
218  XT_MK_REG_DESC("ar26", 0x1A, XT_REG_GENERAL, 0),
219  XT_MK_REG_DESC("ar27", 0x1B, XT_REG_GENERAL, 0),
220  XT_MK_REG_DESC("ar28", 0x1C, XT_REG_GENERAL, 0),
221  XT_MK_REG_DESC("ar29", 0x1D, XT_REG_GENERAL, 0),
222  XT_MK_REG_DESC("ar30", 0x1E, XT_REG_GENERAL, 0),
223  XT_MK_REG_DESC("ar31", 0x1F, XT_REG_GENERAL, 0),
224  XT_MK_REG_DESC("ar32", 0x20, XT_REG_GENERAL, 0),
225  XT_MK_REG_DESC("ar33", 0x21, XT_REG_GENERAL, 0),
226  XT_MK_REG_DESC("ar34", 0x22, XT_REG_GENERAL, 0),
227  XT_MK_REG_DESC("ar35", 0x23, XT_REG_GENERAL, 0),
228  XT_MK_REG_DESC("ar36", 0x24, XT_REG_GENERAL, 0),
229  XT_MK_REG_DESC("ar37", 0x25, XT_REG_GENERAL, 0),
230  XT_MK_REG_DESC("ar38", 0x26, XT_REG_GENERAL, 0),
231  XT_MK_REG_DESC("ar39", 0x27, XT_REG_GENERAL, 0),
232  XT_MK_REG_DESC("ar40", 0x28, XT_REG_GENERAL, 0),
233  XT_MK_REG_DESC("ar41", 0x29, XT_REG_GENERAL, 0),
234  XT_MK_REG_DESC("ar42", 0x2A, XT_REG_GENERAL, 0),
235  XT_MK_REG_DESC("ar43", 0x2B, XT_REG_GENERAL, 0),
236  XT_MK_REG_DESC("ar44", 0x2C, XT_REG_GENERAL, 0),
237  XT_MK_REG_DESC("ar45", 0x2D, XT_REG_GENERAL, 0),
238  XT_MK_REG_DESC("ar46", 0x2E, XT_REG_GENERAL, 0),
239  XT_MK_REG_DESC("ar47", 0x2F, XT_REG_GENERAL, 0),
240  XT_MK_REG_DESC("ar48", 0x30, XT_REG_GENERAL, 0),
241  XT_MK_REG_DESC("ar49", 0x31, XT_REG_GENERAL, 0),
242  XT_MK_REG_DESC("ar50", 0x32, XT_REG_GENERAL, 0),
243  XT_MK_REG_DESC("ar51", 0x33, XT_REG_GENERAL, 0),
244  XT_MK_REG_DESC("ar52", 0x34, XT_REG_GENERAL, 0),
245  XT_MK_REG_DESC("ar53", 0x35, XT_REG_GENERAL, 0),
246  XT_MK_REG_DESC("ar54", 0x36, XT_REG_GENERAL, 0),
247  XT_MK_REG_DESC("ar55", 0x37, XT_REG_GENERAL, 0),
248  XT_MK_REG_DESC("ar56", 0x38, XT_REG_GENERAL, 0),
249  XT_MK_REG_DESC("ar57", 0x39, XT_REG_GENERAL, 0),
250  XT_MK_REG_DESC("ar58", 0x3A, XT_REG_GENERAL, 0),
251  XT_MK_REG_DESC("ar59", 0x3B, XT_REG_GENERAL, 0),
252  XT_MK_REG_DESC("ar60", 0x3C, XT_REG_GENERAL, 0),
253  XT_MK_REG_DESC("ar61", 0x3D, XT_REG_GENERAL, 0),
254  XT_MK_REG_DESC("ar62", 0x3E, XT_REG_GENERAL, 0),
255  XT_MK_REG_DESC("ar63", 0x3F, XT_REG_GENERAL, 0),
256  XT_MK_REG_DESC("windowbase", 0x48, XT_REG_SPECIAL, 0),
257  XT_MK_REG_DESC("windowstart", 0x49, XT_REG_SPECIAL, 0),
258  XT_MK_REG_DESC("ps", XT_PS_REG_NUM, XT_REG_SPECIAL, 0), /* PS (not mapped through EPS[]) */
259  XT_MK_REG_DESC("ibreakenable", 0x60, XT_REG_SPECIAL, 0),
261  XT_MK_REG_DESC("ibreaka0", 0x80, XT_REG_SPECIAL, 0),
262  XT_MK_REG_DESC("ibreaka1", 0x81, XT_REG_SPECIAL, 0),
263  XT_MK_REG_DESC("dbreaka0", 0x90, XT_REG_SPECIAL, 0),
264  XT_MK_REG_DESC("dbreaka1", 0x91, XT_REG_SPECIAL, 0),
265  XT_MK_REG_DESC("dbreakc0", 0xA0, XT_REG_SPECIAL, 0),
266  XT_MK_REG_DESC("dbreakc1", 0xA1, XT_REG_SPECIAL, 0),
267  XT_MK_REG_DESC("cpenable", 0xE0, XT_REG_SPECIAL, 0),
268  XT_MK_REG_DESC("exccause", 0xE8, XT_REG_SPECIAL, 0),
269  XT_MK_REG_DESC("debugcause", 0xE9, XT_REG_SPECIAL, 0),
270  XT_MK_REG_DESC("icount", 0xEC, XT_REG_SPECIAL, 0),
271  XT_MK_REG_DESC("icountlevel", 0xED, XT_REG_SPECIAL, 0),
272 
273  /* WARNING: For these registers, regnum points to the
274  * index of the corresponding ARx registers, NOT to
275  * the processor register number! */
292 };
293 
305 };
306 
326 };
327 
328 /* Register definition as union for list allocation */
331  uint8_t buf[4];
332 };
333 
334 static const struct xtensa_keyval_info xt_qerr[XT_QERR_NUM] = {
335  { .chrval = "E00", .intval = ERROR_FAIL },
336  { .chrval = "E01", .intval = ERROR_FAIL },
337  { .chrval = "E02", .intval = ERROR_COMMAND_ARGUMENT_INVALID },
338  { .chrval = "E03", .intval = ERROR_FAIL },
339 };
340 
341 /* Set to true for extra debug logging */
342 static const bool xtensa_extra_debug_log;
343 
347 static inline const struct xtensa_local_mem_config *xtensa_get_mem_config(
348  struct xtensa *xtensa,
350 {
351  switch (type) {
352  case XTENSA_MEM_REG_IROM:
353  return &xtensa->core_config->irom;
354  case XTENSA_MEM_REG_IRAM:
355  return &xtensa->core_config->iram;
356  case XTENSA_MEM_REG_DROM:
357  return &xtensa->core_config->drom;
358  case XTENSA_MEM_REG_DRAM:
359  return &xtensa->core_config->dram;
360  case XTENSA_MEM_REG_SRAM:
361  return &xtensa->core_config->sram;
362  case XTENSA_MEM_REG_SROM:
363  return &xtensa->core_config->srom;
364  default:
365  return NULL;
366  }
367 }
368 
375  const struct xtensa_local_mem_config *mem,
377 {
378  for (unsigned int i = 0; i < mem->count; i++) {
379  const struct xtensa_local_mem_region_config *region = &mem->regions[i];
380  if (address >= region->base && address < (region->base + region->size))
381  return region;
382  }
383  return NULL;
384 }
385 
392  struct xtensa *xtensa,
394 {
395  const struct xtensa_local_mem_region_config *result;
396  const struct xtensa_local_mem_config *mcgf;
397  for (unsigned int mtype = 0; mtype < XTENSA_MEM_REGS_NUM; mtype++) {
398  mcgf = xtensa_get_mem_config(xtensa, mtype);
399  result = xtensa_memory_region_find(mcgf, address);
400  if (result)
401  return result;
402  }
403  return NULL;
404 }
405 
406 static inline bool xtensa_is_cacheable(const struct xtensa_cache_config *cache,
407  const struct xtensa_local_mem_config *mem,
409 {
410  if (!cache->size)
411  return false;
412  return xtensa_memory_region_find(mem, address);
413 }
414 
416 {
421 }
422 
424 {
429 }
430 
431 static int xtensa_core_reg_get(struct reg *reg)
432 {
433  /* We don't need this because we read all registers on halt anyway. */
434  struct xtensa *xtensa = (struct xtensa *)reg->arch_info;
435  struct target *target = xtensa->target;
436 
437  if (target->state != TARGET_HALTED)
439  if (!reg->exist) {
440  if (strncmp(reg->name, "?0x", 3) == 0) {
441  unsigned int regnum = strtoul(reg->name + 1, NULL, 0);
442  LOG_WARNING("Read unknown register 0x%04x ignored", regnum);
443  return ERROR_OK;
444  }
446  }
447  return ERROR_OK;
448 }
449 
450 static int xtensa_core_reg_set(struct reg *reg, uint8_t *buf)
451 {
452  struct xtensa *xtensa = (struct xtensa *)reg->arch_info;
453  struct target *target = xtensa->target;
454 
455  assert(reg->size <= 64 && "up to 64-bit regs are supported only!");
456  if (target->state != TARGET_HALTED)
458 
459  if (!reg->exist) {
460  if (strncmp(reg->name, "?0x", 3) == 0) {
461  unsigned int regnum = strtoul(reg->name + 1, NULL, 0);
462  LOG_WARNING("Write unknown register 0x%04x ignored", regnum);
463  return ERROR_OK;
464  }
466  }
467 
468  buf_cpy(buf, reg->value, reg->size);
469 
470  if (xtensa->core_config->windowed) {
471  /* If the user updates a potential scratch register, track for conflicts */
472  for (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++) {
473  if (strcmp(reg->name, xtensa->scratch_ars[s].chrval) == 0) {
474  LOG_DEBUG("Scratch reg %s [0x%08" PRIx32 "] set from gdb", reg->name,
475  buf_get_u32(reg->value, 0, 32));
476  LOG_DEBUG("scratch_ars mapping: a3/%s, a4/%s",
479  xtensa->scratch_ars[s].intval = true;
480  break;
481  }
482  }
483  }
484  reg->dirty = true;
485  reg->valid = true;
486 
487  return ERROR_OK;
488 }
489 
490 static const struct reg_arch_type xtensa_reg_type = {
492  .set = xtensa_core_reg_set,
493 };
494 
495 /* Convert a register index that's indexed relative to windowbase, to the real address. */
497  enum xtensa_reg_id reg_idx,
498  int windowbase)
499 {
500  unsigned int idx;
501  if (reg_idx >= XT_REG_IDX_AR0 && reg_idx <= XT_REG_IDX_ARLAST) {
502  idx = reg_idx - XT_REG_IDX_AR0;
503  } else if (reg_idx >= XT_REG_IDX_A0 && reg_idx <= XT_REG_IDX_A15) {
504  idx = reg_idx - XT_REG_IDX_A0;
505  } else {
506  LOG_ERROR("Can't convert register %d to non-windowbased register", reg_idx);
507  return -1;
508  }
509  /* Each windowbase value represents 4 registers on LX and 8 on NX */
510  int base_inc = (xtensa->core_config->core_type == XT_LX) ? 4 : 8;
511  return ((idx + windowbase * base_inc) & (xtensa->core_config->aregs_num - 1)) + XT_REG_IDX_AR0;
512 }
513 
515  enum xtensa_reg_id reg_idx,
516  int windowbase)
517 {
518  return xtensa_windowbase_offset_to_canonical(xtensa, reg_idx, -windowbase);
519 }
520 
521 static void xtensa_mark_register_dirty(struct xtensa *xtensa, enum xtensa_reg_id reg_idx)
522 {
523  struct reg *reg_list = xtensa->core_cache->reg_list;
524  reg_list[reg_idx].dirty = true;
525 }
526 
527 static void xtensa_queue_exec_ins(struct xtensa *xtensa, uint32_t ins)
528 {
530 }
531 
532 static void xtensa_queue_exec_ins_wide(struct xtensa *xtensa, uint8_t *ops, uint8_t oplen)
533 {
534  const int max_oplen = 64; /* 8 DIRx regs: max width 64B */
535  if ((oplen > 0) && (oplen <= max_oplen)) {
536  uint8_t ops_padded[max_oplen];
537  memcpy(ops_padded, ops, oplen);
538  memset(ops_padded + oplen, 0, max_oplen - oplen);
539  unsigned int oplenw = DIV_ROUND_UP(oplen, sizeof(uint32_t));
540  for (int32_t i = oplenw - 1; i > 0; i--)
542  XDMREG_DIR0 + i,
543  target_buffer_get_u32(xtensa->target, &ops_padded[sizeof(uint32_t) * i]));
544  /* Write DIR0EXEC last */
547  target_buffer_get_u32(xtensa->target, &ops_padded[0]));
548  }
549 }
550 
551 /* NOTE: Assumes A3 has already been saved and marked dirty; A3 will be clobbered */
553 {
555  if (xtensa->core_config->mpu.enabled) {
556  /* For cores with the MPU option, issue PPTLB on start and end addresses.
557  * Parse access rights field, and confirm both have execute permissions.
558  */
559  for (int i = 0; i <= 1; i++) {
560  uint32_t at, acc;
561  uint8_t at_buf[4];
562  bool exec_acc;
563  target_addr_t addr = i ? end : start;
570  if (res != ERROR_OK)
571  LOG_TARGET_ERROR(target, "Error queuing PPTLB: %d", res);
573  if (res != ERROR_OK)
574  LOG_TARGET_ERROR(target, "Error issuing PPTLB: %d", res);
575  at = buf_get_u32(at_buf, 0, 32);
576  acc = (at >> XT_TLB1_ACC_SHIFT) & XT_TLB1_ACC_MSK;
577  exec_acc = ((acc == XTENSA_ACC_00X_000) || (acc == XTENSA_ACC_R0X_000) ||
578  (acc == XTENSA_ACC_RWX_000) || (acc == XTENSA_ACC_RWX_R0X) ||
579  (acc == XTENSA_ACC_R0X_R0X) || (acc == XTENSA_ACC_RWX_RWX));
580  LOG_TARGET_DEBUG(target, "PPTLB(" TARGET_ADDR_FMT ") -> 0x%08" PRIx32 " exec_acc %d",
581  addr, at, exec_acc);
582  if (!exec_acc)
583  return false;
584  }
585  }
586  return true;
587 }
588 
589 static int xtensa_queue_pwr_reg_write(struct xtensa *xtensa, unsigned int reg, uint32_t data)
590 {
591  struct xtensa_debug_module *dm = &xtensa->dbg_mod;
592  return dm->pwr_ops->queue_reg_write(dm, reg, data);
593 }
594 
595 /* NOTE: Assumes A3 has already been saved */
596 static int xtensa_window_state_save(struct target *target, uint32_t *woe)
597 {
599  unsigned int woe_sr = (xtensa->core_config->core_type == XT_LX) ? XT_SR_PS : XT_SR_WB;
600  uint32_t woe_dis;
601  uint8_t woe_buf[4];
602 
603  if (xtensa->core_config->windowed) {
604  /* Save PS (LX) or WB (NX) and disable window overflow exceptions prior to AR save */
609  if (res != ERROR_OK) {
610  LOG_TARGET_ERROR(target, "Failed to read %s (%d)!",
611  (woe_sr == XT_SR_PS) ? "PS" : "WB", res);
612  return res;
613  }
615  *woe = buf_get_u32(woe_buf, 0, 32);
616  woe_dis = *woe & ~((woe_sr == XT_SR_PS) ? XT_PS_WOE_MSK : XT_WB_S_MSK);
617  LOG_TARGET_DEBUG(target, "Clearing %s (0x%08" PRIx32 " -> 0x%08" PRIx32 ")",
618  (woe_sr == XT_SR_PS) ? "PS.WOE" : "WB.S", *woe, woe_dis);
622  }
623  return ERROR_OK;
624 }
625 
626 /* NOTE: Assumes A3 has already been saved */
627 static void xtensa_window_state_restore(struct target *target, uint32_t woe)
628 {
630  unsigned int woe_sr = (xtensa->core_config->core_type == XT_LX) ? XT_SR_PS : XT_SR_WB;
631  if (xtensa->core_config->windowed) {
632  /* Restore window overflow exception state */
636  LOG_TARGET_DEBUG(target, "Restored %s (0x%08" PRIx32 ")",
637  (woe_sr == XT_SR_PS) ? "PS.WOE" : "WB", woe);
638  }
639 }
640 
641 static bool xtensa_reg_is_readable(int flags, int cpenable)
642 {
643  if (flags & XT_REGF_NOREAD)
644  return false;
645  if ((flags & XT_REGF_COPROC0) && (cpenable & BIT(0)) == 0)
646  return false;
647  return true;
648 }
649 
650 static bool xtensa_scratch_regs_fixup(struct xtensa *xtensa, struct reg *reg_list, int i, int j, int a_idx, int ar_idx)
651 {
652  int a_name = (a_idx == XT_AR_SCRATCH_A3) ? 3 : 4;
653  if (xtensa->scratch_ars[a_idx].intval && !xtensa->scratch_ars[ar_idx].intval) {
654  LOG_DEBUG("AR conflict: a%d -> ar%d", a_name, j - XT_REG_IDX_AR0);
655  memcpy(reg_list[j].value, reg_list[i].value, sizeof(xtensa_reg_val_t));
656  } else {
657  LOG_DEBUG("AR conflict: ar%d -> a%d", j - XT_REG_IDX_AR0, a_name);
658  memcpy(reg_list[i].value, reg_list[j].value, sizeof(xtensa_reg_val_t));
659  }
660  return xtensa->scratch_ars[a_idx].intval && xtensa->scratch_ars[ar_idx].intval;
661 }
662 
664 {
666  int res;
667  xtensa_reg_val_t regval, windowbase = 0;
668  bool scratch_reg_dirty = false, delay_cpenable = false;
669  struct reg *reg_list = xtensa->core_cache->reg_list;
670  unsigned int reg_list_size = xtensa->core_cache->num_regs;
671  bool preserve_a3 = false;
672  uint8_t a3_buf[4];
673  xtensa_reg_val_t a3 = 0, woe;
674  unsigned int ms_idx = (xtensa->core_config->core_type == XT_NX) ?
675  xtensa->nx_reg_idx[XT_NX_REG_IDX_MS] : reg_list_size;
676  xtensa_reg_val_t ms = 0;
677  bool restore_ms = false;
678 
679  LOG_TARGET_DEBUG(target, "start");
680 
681  /* We need to write the dirty registers in the cache list back to the processor.
682  * Start by writing the SFR/user registers. */
683  for (unsigned int i = 0; i < reg_list_size; i++) {
684  struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs;
685  unsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS;
686  if (reg_list[i].dirty) {
687  if (rlist[ridx].type == XT_REG_SPECIAL ||
688  rlist[ridx].type == XT_REG_USER ||
689  rlist[ridx].type == XT_REG_FR) {
690  scratch_reg_dirty = true;
691  if (i == XT_REG_IDX_CPENABLE) {
692  delay_cpenable = true;
693  continue;
694  }
695  regval = xtensa_reg_get(target, i);
696  LOG_TARGET_DEBUG(target, "Writing back reg %s (%d) val %08" PRIX32,
697  reg_list[i].name,
698  rlist[ridx].reg_num,
699  regval);
702  if (reg_list[i].exist) {
703  unsigned int reg_num = rlist[ridx].reg_num;
704  if (rlist[ridx].type == XT_REG_USER) {
706  } else if (rlist[ridx].type == XT_REG_FR) {
708  } else {/*SFR */
710  if (xtensa->core_config->core_type == XT_LX) {
711  /* reg number of PC for debug interrupt depends on NDEBUGLEVEL */
714  } else {
715  /* NX PC set through issuing a jump instruction */
717  }
718  } else if (i == ms_idx) {
719  /* MS must be restored after ARs. This ensures ARs remain in correct
720  * order even for reversed register groups (overflow/underflow).
721  */
722  ms = regval;
723  restore_ms = true;
724  LOG_TARGET_DEBUG(target, "Delaying MS write: 0x%x", ms);
725  } else {
727  }
728  }
729  }
730  reg_list[i].dirty = false;
731  }
732  }
733  }
734  if (scratch_reg_dirty)
736  if (delay_cpenable) {
738  LOG_TARGET_DEBUG(target, "Writing back reg cpenable (224) val %08" PRIX32, regval);
743  XT_REG_A3));
744  reg_list[XT_REG_IDX_CPENABLE].dirty = false;
745  }
746 
747  preserve_a3 = (xtensa->core_config->windowed) || (xtensa->core_config->core_type == XT_NX);
748  if (preserve_a3) {
749  /* Save (windowed) A3 for scratch use */
753  if (res != ERROR_OK)
754  return res;
756  a3 = buf_get_u32(a3_buf, 0, 32);
757  }
758 
759  if (xtensa->core_config->windowed) {
760  res = xtensa_window_state_save(target, &woe);
761  if (res != ERROR_OK)
762  return res;
763  /* Grab the windowbase, we need it. */
764  uint32_t wb_idx = (xtensa->core_config->core_type == XT_LX) ?
766  windowbase = xtensa_reg_get(target, wb_idx);
768  windowbase = (windowbase & XT_WB_P_MSK) >> XT_WB_P_SHIFT;
769 
770  /* Check if there are mismatches between the ARx and corresponding Ax registers.
771  * When the user sets a register on a windowed config, xt-gdb may set the ARx
772  * register directly. Thus we take ARx as priority over Ax if both are dirty
773  * and it's unclear if the user set one over the other explicitly.
774  */
775  for (unsigned int i = XT_REG_IDX_A0; i <= XT_REG_IDX_A15; i++) {
776  unsigned int j = xtensa_windowbase_offset_to_canonical(xtensa, i, windowbase);
777  if (reg_list[i].dirty && reg_list[j].dirty) {
778  if (memcmp(reg_list[i].value, reg_list[j].value, sizeof(xtensa_reg_val_t)) != 0) {
779  bool show_warning = true;
780  if (i == XT_REG_IDX_A3)
781  show_warning = xtensa_scratch_regs_fixup(xtensa,
782  reg_list, i, j, XT_AR_SCRATCH_A3, XT_AR_SCRATCH_AR3);
783  else if (i == XT_REG_IDX_A4)
784  show_warning = xtensa_scratch_regs_fixup(xtensa,
785  reg_list, i, j, XT_AR_SCRATCH_A4, XT_AR_SCRATCH_AR4);
786  if (show_warning)
787  LOG_WARNING(
788  "Warning: Both A%d [0x%08" PRIx32
789  "] as well as its underlying physical register "
790  "(AR%d) [0x%08" PRIx32 "] are dirty and differ in value",
791  i - XT_REG_IDX_A0,
792  buf_get_u32(reg_list[i].value, 0, 32),
793  j - XT_REG_IDX_AR0,
794  buf_get_u32(reg_list[j].value, 0, 32));
795  }
796  } else if (reg_list[i].dirty) {
797  memcpy(reg_list[j].value, reg_list[i].value, sizeof(xtensa_reg_val_t));
798  } else if (reg_list[j].dirty) {
799  memcpy(reg_list[i].value, reg_list[j].value, sizeof(xtensa_reg_val_t));
800  }
801  }
802  }
803 
804  /* Write A0-A16. */
805  for (unsigned int i = 0; i < 16; i++) {
806  if (reg_list[XT_REG_IDX_A0 + i].dirty) {
807  regval = xtensa_reg_get(target, XT_REG_IDX_A0 + i);
808  LOG_TARGET_DEBUG(target, "Writing back reg %s value %08" PRIX32 ", num =%i",
810  regval,
814  reg_list[XT_REG_IDX_A0 + i].dirty = false;
815  if (i == 3) {
816  /* Avoid stomping A3 during restore at end of function */
817  a3 = regval;
818  }
819  }
820  }
821 
822  if (xtensa->core_config->windowed) {
823  /* Now write AR registers */
824  for (unsigned int j = 0; j < XT_REG_IDX_ARLAST; j += 16) {
825  /* Write the 16 registers we can see */
826  for (unsigned int i = 0; i < 16; i++) {
827  if (i + j < xtensa->core_config->aregs_num) {
828  enum xtensa_reg_id realadr =
830  windowbase);
831  /* Write back any dirty un-windowed registers */
832  if (reg_list[realadr].dirty) {
833  regval = xtensa_reg_get(target, realadr);
835  target,
836  "Writing back reg %s value %08" PRIX32 ", num =%i",
837  xtensa_regs[realadr].name,
838  regval,
839  xtensa_regs[realadr].reg_num);
844  reg_list[realadr].dirty = false;
845  if ((i + j) == 3)
846  /* Avoid stomping AR during A3 restore at end of function */
847  a3 = regval;
848  }
849  }
850  }
851 
852  /* Now rotate the window so we'll see the next 16 registers. The final rotate
853  * will wraparound, leaving us in the state we were.
854  * Each ROTW rotates 4 registers on LX and 8 on NX */
855  int rotw_arg = (xtensa->core_config->core_type == XT_LX) ? 4 : 2;
857  }
858 
860 
861  for (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++)
862  xtensa->scratch_ars[s].intval = false;
863  }
864 
865  if (restore_ms) {
866  uint32_t ms_regno = xtensa->optregs[ms_idx - XT_NUM_REGS].reg_num;
870  LOG_TARGET_DEBUG(target, "Delayed MS (0x%x) write complete: 0x%x", ms_regno, ms);
871  }
872 
873  if (preserve_a3) {
876  }
877 
880 
881  return res;
882 }
883 
884 static inline bool xtensa_is_stopped(struct target *target)
885 {
888 }
889 
891 {
894 
896 
898  LOG_ERROR("XTensa core not configured; is xtensa-core-openocd.cfg missing?");
899  return ERROR_FAIL;
900  }
901 
907  if (res != ERROR_OK)
908  return res;
910  LOG_ERROR("Unexpected OCD_ID = %08" PRIx32, xtensa->dbg_mod.device_id);
911  return ERROR_TARGET_FAILURE;
912  }
913  LOG_DEBUG("OCD_ID = %08" PRIx32, xtensa->dbg_mod.device_id);
915  return ERROR_OK;
916 }
917 
919 {
922 
923  if (xtensa->reset_asserted)
926  /* TODO: can we join this with the write above? */
930 }
931 
932 int xtensa_smpbreak_write(struct xtensa *xtensa, uint32_t set)
933 {
934  uint32_t dsr_data = 0x00110000;
935  uint32_t clear = (set | OCDDCR_ENABLEOCD) ^
938 
939  LOG_TARGET_DEBUG(xtensa->target, "write smpbreak set=0x%" PRIx32 " clear=0x%" PRIx32, set, clear);
945 }
946 
947 int xtensa_smpbreak_set(struct target *target, uint32_t set)
948 {
950  int res = ERROR_OK;
951 
952  xtensa->smp_break = set;
955  LOG_TARGET_DEBUG(target, "set smpbreak=%" PRIx32 ", state %s", set,
957  return res;
958 }
959 
960 int xtensa_smpbreak_read(struct xtensa *xtensa, uint32_t *val)
961 {
962  uint8_t dcr_buf[sizeof(uint32_t)];
963 
967  *val = buf_get_u32(dcr_buf, 0, 32);
968 
969  return res;
970 }
971 
972 int xtensa_smpbreak_get(struct target *target, uint32_t *val)
973 {
975  *val = xtensa->smp_break;
976  return ERROR_OK;
977 }
978 
980 {
981  return buf_get_u32(reg->value, 0, 32);
982 }
983 
984 static inline void xtensa_reg_set_value(struct reg *reg, xtensa_reg_val_t value)
985 {
986  buf_set_u32(reg->value, 0, 32, value);
987  reg->dirty = true;
988 }
989 
991 {
993  for (enum xtensa_nx_reg_idx idx = XT_NX_REG_IDX_IEVEC; idx <= XT_NX_REG_IDX_MESR; idx++) {
994  enum xtensa_reg_id ridx = xtensa->nx_reg_idx[idx];
995  if (xtensa->nx_reg_idx[idx]) {
997  if (reg & XT_IMPR_EXC_MSK) {
998  LOG_TARGET_DEBUG(target, "Imprecise exception: %s: 0x%x",
999  xtensa->core_cache->reg_list[ridx].name, reg);
1000  return true;
1001  }
1002  }
1003  }
1004  return false;
1005 }
1006 
1008 {
1009  struct xtensa *xtensa = target_to_xtensa(target);
1010  for (enum xtensa_nx_reg_idx idx = XT_NX_REG_IDX_IEVEC; idx <= XT_NX_REG_IDX_MESRCLR; idx++) {
1011  enum xtensa_reg_id ridx = xtensa->nx_reg_idx[idx];
1012  if (ridx && idx != XT_NX_REG_IDX_MESR) {
1014  xtensa_reg_set(target, ridx, value);
1015  LOG_TARGET_DEBUG(target, "Imprecise exception: clearing %s (0x%x)",
1016  xtensa->core_cache->reg_list[ridx].name, value);
1017  }
1018  }
1019 }
1020 
1022 {
1023  struct xtensa *xtensa = target_to_xtensa(target);
1024  int res, needclear = 0, needimprclear = 0;
1025 
1028  LOG_TARGET_DEBUG(target, "DSR (%08" PRIX32 ")", dsr);
1029  if (dsr & OCDDSR_EXECBUSY) {
1031  LOG_TARGET_ERROR(target, "DSR (%08" PRIX32 ") indicates target still busy!", dsr);
1032  needclear = 1;
1033  }
1034  if (dsr & OCDDSR_EXECEXCEPTION) {
1037  "DSR (%08" PRIX32 ") indicates DIR instruction generated an exception!",
1038  dsr);
1039  needclear = 1;
1040  }
1041  if (dsr & OCDDSR_EXECOVERRUN) {
1044  "DSR (%08" PRIX32 ") indicates DIR instruction generated an overrun!",
1045  dsr);
1046  needclear = 1;
1047  }
1051  "%s: Imprecise exception occurred!", target_name(target));
1052  needclear = 1;
1053  needimprclear = 1;
1054  }
1055  if (needclear) {
1058  if (res != ERROR_OK && !xtensa->suppress_dsr_errors)
1059  LOG_TARGET_ERROR(target, "clearing DSR failed!");
1060  if (xtensa->core_config->core_type == XT_NX && needimprclear)
1062  return ERROR_FAIL;
1063  }
1064  return ERROR_OK;
1065 }
1066 
1068 {
1069  struct xtensa *xtensa = target_to_xtensa(target);
1070  struct reg *reg = &xtensa->core_cache->reg_list[reg_id];
1071  return xtensa_reg_get_value(reg);
1072 }
1073 
1075 {
1076  struct xtensa *xtensa = target_to_xtensa(target);
1077  struct reg *reg = &xtensa->core_cache->reg_list[reg_id];
1078  if (xtensa_reg_get_value(reg) == value)
1079  return;
1081 }
1082 
1083 /* Set Ax (XT_REG_RELGEN) register along with its underlying ARx (XT_REG_GENERAL) */
1085 {
1086  struct xtensa *xtensa = target_to_xtensa(target);
1087  uint32_t wb_idx = (xtensa->core_config->core_type == XT_LX) ?
1089  uint32_t windowbase = (xtensa->core_config->windowed ?
1090  xtensa_reg_get(target, wb_idx) : 0);
1091  if (xtensa->core_config->core_type == XT_NX)
1092  windowbase = (windowbase & XT_WB_P_MSK) >> XT_WB_P_SHIFT;
1093  int ar_idx = xtensa_windowbase_offset_to_canonical(xtensa, a_idx, windowbase);
1094  xtensa_reg_set(target, a_idx, value);
1095  xtensa_reg_set(target, ar_idx, value);
1096 }
1097 
1098 /* Read cause for entering halted state; return bitmask in DEBUGCAUSE_* format */
1099 uint32_t xtensa_cause_get(struct target *target)
1100 {
1101  struct xtensa *xtensa = target_to_xtensa(target);
1102  if (xtensa->core_config->core_type == XT_LX) {
1103  /* LX cause in DEBUGCAUSE */
1105  }
1107  return xtensa->nx_stop_cause;
1108 
1109  /* NX cause determined from DSR.StopCause */
1111  LOG_TARGET_ERROR(target, "Read DSR error");
1112  } else {
1113  uint32_t dsr = xtensa_dm_core_status_get(&xtensa->dbg_mod);
1114  /* NX causes are prioritized; only 1 bit can be set */
1115  switch ((dsr & OCDDSR_STOPCAUSE) >> OCDDSR_STOPCAUSE_SHIFT) {
1116  case OCDDSR_STOPCAUSE_DI:
1118  break;
1119  case OCDDSR_STOPCAUSE_SS:
1121  break;
1122  case OCDDSR_STOPCAUSE_IB:
1124  break;
1125  case OCDDSR_STOPCAUSE_B:
1126  case OCDDSR_STOPCAUSE_B1:
1128  break;
1129  case OCDDSR_STOPCAUSE_BN:
1131  break;
1132  case OCDDSR_STOPCAUSE_DB0:
1133  case OCDDSR_STOPCAUSE_DB1:
1135  break;
1136  default:
1137  LOG_TARGET_ERROR(target, "Unknown stop cause (DSR: 0x%08x)", dsr);
1138  break;
1139  }
1140  if (xtensa->nx_stop_cause)
1142  }
1143  return xtensa->nx_stop_cause;
1144 }
1145 
1147 {
1148  struct xtensa *xtensa = target_to_xtensa(target);
1149  if (xtensa->core_config->core_type == XT_LX) {
1152  } else {
1153  /* NX DSR.STOPCAUSE is not writeable; clear cached copy but leave it valid */
1155  }
1156 }
1157 
1159 {
1160  /* Clear DEBUGCAUSE_VALID to trigger re-read (on NX) */
1161  struct xtensa *xtensa = target_to_xtensa(target);
1162  xtensa->nx_stop_cause = 0;
1163 }
1164 
1166 {
1167  struct xtensa *xtensa = target_to_xtensa(target);
1168 
1169  LOG_TARGET_DEBUG(target, " begin");
1171  XDMREG_PWRCTL,
1175  int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
1176  if (res != ERROR_OK)
1177  return res;
1178 
1179  /* registers are now invalid */
1180  xtensa->reset_asserted = true;
1183  return ERROR_OK;
1184 }
1185 
1187 {
1188  struct xtensa *xtensa = target_to_xtensa(target);
1189 
1190  LOG_TARGET_DEBUG(target, "halt=%d", target->reset_halt);
1191  if (target->reset_halt)
1193  XDMREG_DCRSET,
1196  XDMREG_PWRCTL,
1200  int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
1201  if (res != ERROR_OK)
1202  return res;
1204  xtensa->reset_asserted = false;
1205  return res;
1206 }
1207 
1209 {
1210  LOG_TARGET_DEBUG(target, "begin");
1211  return xtensa_assert_reset(target);
1212 }
1213 
1215 {
1216  struct xtensa *xtensa = target_to_xtensa(target);
1217  struct reg *reg_list = xtensa->core_cache->reg_list;
1218  unsigned int reg_list_size = xtensa->core_cache->num_regs;
1219  xtensa_reg_val_t cpenable = 0, windowbase = 0, a0 = 0, a3;
1220  unsigned int ms_idx = reg_list_size;
1221  uint32_t ms = 0;
1222  uint32_t woe;
1223  uint8_t a0_buf[4], a3_buf[4], ms_buf[4];
1224  bool debug_dsrs = !xtensa->regs_fetched || LOG_LEVEL_IS(LOG_LVL_DEBUG);
1225 
1226  union xtensa_reg_val_u *regvals = calloc(reg_list_size, sizeof(*regvals));
1227  if (!regvals) {
1228  LOG_TARGET_ERROR(target, "unable to allocate memory for regvals!");
1229  return ERROR_FAIL;
1230  }
1231  union xtensa_reg_val_u *dsrs = calloc(reg_list_size, sizeof(*dsrs));
1232  if (!dsrs) {
1233  LOG_TARGET_ERROR(target, "unable to allocate memory for dsrs!");
1234  free(regvals);
1235  return ERROR_FAIL;
1236  }
1237 
1238  LOG_TARGET_DEBUG(target, "start");
1239 
1240  /* Save (windowed) A3 so cache matches physical AR3; A3 usable as scratch */
1243  if (xtensa->core_config->core_type == XT_NX) {
1244  /* Save (windowed) A0 as well--it will be required for reading PC */
1247 
1248  /* Set MS.DispSt, clear MS.DE prior to accessing ARs. This ensures ARs remain
1249  * in correct order even for reversed register groups (overflow/underflow).
1250  */
1251  ms_idx = xtensa->nx_reg_idx[XT_NX_REG_IDX_MS];
1252  uint32_t ms_regno = xtensa->optregs[ms_idx - XT_NUM_REGS].reg_num;
1256  LOG_TARGET_DEBUG(target, "Overriding MS (0x%x): 0x%x", ms_regno, XT_MS_DISPST_DBG);
1260  }
1261 
1262  int res = xtensa_window_state_save(target, &woe);
1263  if (res != ERROR_OK)
1264  goto xtensa_fetch_all_regs_done;
1265 
1266  /* Assume the CPU has just halted. We now want to fill the register cache with all the
1267  * register contents GDB needs. For speed, we pipeline all the read operations, execute them
1268  * in one go, then sort everything out from the regvals variable. */
1269 
1270  /* Start out with AREGS; we can reach those immediately. Grab them per 16 registers. */
1271  for (unsigned int j = 0; j < XT_AREGS_NUM_MAX; j += 16) {
1272  /*Grab the 16 registers we can see */
1273  for (unsigned int i = 0; i < 16; i++) {
1274  if (i + j < xtensa->core_config->aregs_num) {
1278  regvals[XT_REG_IDX_AR0 + i + j].buf);
1279  if (debug_dsrs)
1281  dsrs[XT_REG_IDX_AR0 + i + j].buf);
1282  }
1283  }
1284  if (xtensa->core_config->windowed) {
1285  /* Now rotate the window so we'll see the next 16 registers. The final rotate
1286  * will wraparound, leaving us in the state we were.
1287  * Each ROTW rotates 4 registers on LX and 8 on NX */
1288  int rotw_arg = (xtensa->core_config->core_type == XT_LX) ? 4 : 2;
1290  }
1291  }
1293 
1294  if (xtensa->core_config->coproc) {
1295  /* As the very first thing after AREGS, go grab CPENABLE */
1299  }
1301  if (res != ERROR_OK) {
1302  LOG_ERROR("Failed to read ARs (%d)!", res);
1303  goto xtensa_fetch_all_regs_done;
1304  }
1306 
1307  a3 = buf_get_u32(a3_buf, 0, 32);
1308  if (xtensa->core_config->core_type == XT_NX) {
1309  a0 = buf_get_u32(a0_buf, 0, 32);
1310  ms = buf_get_u32(ms_buf, 0, 32);
1311  }
1312 
1313  if (xtensa->core_config->coproc) {
1314  cpenable = buf_get_u32(regvals[XT_REG_IDX_CPENABLE].buf, 0, 32);
1315 
1316  /* Enable all coprocessors (by setting all bits in CPENABLE) so we can read FP and user registers. */
1320 
1321  /* Save CPENABLE; flag dirty later (when regcache updated) so original value is always restored */
1322  LOG_TARGET_DEBUG(target, "CPENABLE: was 0x%" PRIx32 ", all enabled", cpenable);
1324  }
1325  /* We're now free to use any of A0-A15 as scratch registers
1326  * Grab the SFRs and user registers first. We use A3 as a scratch register. */
1327  for (unsigned int i = 0; i < reg_list_size; i++) {
1328  struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs;
1329  unsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS;
1330  if (xtensa_reg_is_readable(rlist[ridx].flags, cpenable) && rlist[ridx].exist) {
1331  bool reg_fetched = true;
1332  unsigned int reg_num = rlist[ridx].reg_num;
1333  switch (rlist[ridx].type) {
1334  case XT_REG_USER:
1336  break;
1337  case XT_REG_FR:
1339  break;
1340  case XT_REG_SPECIAL:
1341  if (reg_num == XT_PC_REG_NUM_VIRTUAL) {
1342  if (xtensa->core_config->core_type == XT_LX) {
1343  /* reg number of PC for debug interrupt depends on NDEBUGLEVEL */
1346  } else {
1347  /* NX PC read through CALL0(0) and reading A0 */
1350  xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, regvals[i].buf);
1352  reg_fetched = false;
1353  }
1354  } else if ((xtensa->core_config->core_type == XT_LX)
1356  /* reg number of PS for debug interrupt depends on NDEBUGLEVEL */
1360  /* CPENABLE already read/updated; don't re-read */
1361  reg_fetched = false;
1362  break;
1363  } else {
1365  }
1366  break;
1367  default:
1368  reg_fetched = false;
1369  }
1370  if (reg_fetched) {
1372  xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, regvals[i].buf);
1373  if (debug_dsrs)
1375  }
1376  }
1377  }
1378  /* Ok, send the whole mess to the CPU. */
1380  if (res != ERROR_OK) {
1381  LOG_ERROR("Failed to fetch AR regs!");
1382  goto xtensa_fetch_all_regs_done;
1383  }
1385 
1386  if (debug_dsrs) {
1387  /* DSR checking: follows order in which registers are requested. */
1388  for (unsigned int i = 0; i < reg_list_size; i++) {
1389  struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs;
1390  unsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS;
1391  if (xtensa_reg_is_readable(rlist[ridx].flags, cpenable) && rlist[ridx].exist &&
1392  (rlist[ridx].type != XT_REG_DEBUG) &&
1393  (rlist[ridx].type != XT_REG_RELGEN) &&
1394  (rlist[ridx].type != XT_REG_TIE) &&
1395  (rlist[ridx].type != XT_REG_OTHER)) {
1396  if (buf_get_u32(dsrs[i].buf, 0, 32) & OCDDSR_EXECEXCEPTION) {
1397  LOG_ERROR("Exception reading %s!", reg_list[i].name);
1398  res = ERROR_FAIL;
1399  goto xtensa_fetch_all_regs_done;
1400  }
1401  }
1402  }
1403  }
1404 
1405  if (xtensa->core_config->windowed) {
1406  /* We need the windowbase to decode the general addresses. */
1407  uint32_t wb_idx = (xtensa->core_config->core_type == XT_LX) ?
1409  windowbase = buf_get_u32(regvals[wb_idx].buf, 0, 32);
1410  if (xtensa->core_config->core_type == XT_NX)
1411  windowbase = (windowbase & XT_WB_P_MSK) >> XT_WB_P_SHIFT;
1412  }
1413 
1414  /* Decode the result and update the cache. */
1415  for (unsigned int i = 0; i < reg_list_size; i++) {
1416  struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs;
1417  unsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS;
1418  if (xtensa_reg_is_readable(rlist[ridx].flags, cpenable) && rlist[ridx].exist) {
1419  if ((xtensa->core_config->windowed) && (rlist[ridx].type == XT_REG_GENERAL)) {
1420  /* The 64-value general register set is read from (windowbase) on down.
1421  * We need to get the real register address by subtracting windowbase and
1422  * wrapping around. */
1424  windowbase);
1425  buf_cpy(regvals[realadr].buf, reg_list[i].value, reg_list[i].size);
1426  } else if (rlist[ridx].type == XT_REG_RELGEN) {
1427  buf_cpy(regvals[rlist[ridx].reg_num].buf, reg_list[i].value, reg_list[i].size);
1428  if (xtensa_extra_debug_log) {
1429  xtensa_reg_val_t regval = buf_get_u32(regvals[rlist[ridx].reg_num].buf, 0, 32);
1430  LOG_DEBUG("%s = 0x%x", rlist[ridx].name, regval);
1431  }
1432  } else {
1433  xtensa_reg_val_t regval = buf_get_u32(regvals[i].buf, 0, 32);
1434  bool is_dirty = (i == XT_REG_IDX_CPENABLE);
1436  LOG_INFO("Register %s: 0x%X", reg_list[i].name, regval);
1437  if (rlist[ridx].reg_num == XT_PC_REG_NUM_VIRTUAL &&
1439  /* A0 from prior CALL0 points to next instruction; decrement it */
1440  regval -= 3;
1441  is_dirty = 1;
1442  } else if (i == ms_idx) {
1443  LOG_TARGET_DEBUG(target, "Caching MS: 0x%x", ms);
1444  regval = ms;
1445  is_dirty = 1;
1446  }
1447  xtensa_reg_set(target, i, regval);
1448  reg_list[i].dirty = is_dirty; /*always do this _after_ xtensa_reg_set! */
1449  }
1450  reg_list[i].valid = true;
1451  } else {
1452  if ((rlist[ridx].flags & XT_REGF_MASK) == XT_REGF_NOREAD) {
1453  /* Report read-only registers all-zero but valid */
1454  reg_list[i].valid = true;
1455  xtensa_reg_set(target, i, 0);
1456  } else {
1457  reg_list[i].valid = false;
1458  }
1459  }
1460  }
1461 
1462  if (xtensa->core_config->windowed) {
1463  /* We have used A3 as a scratch register.
1464  * Windowed configs: restore A3's AR (XT_REG_GENERAL) and and flag for write-back.
1465  */
1467  xtensa_reg_set(target, ar3_idx, a3);
1469 
1470  /* Reset scratch_ars[] on fetch. .chrval tracks AR mapping and changes w/ window */
1471  sprintf(xtensa->scratch_ars[XT_AR_SCRATCH_AR3].chrval, "ar%d", ar3_idx - XT_REG_IDX_AR0);
1473  sprintf(xtensa->scratch_ars[XT_AR_SCRATCH_AR4].chrval, "ar%d", ar4_idx - XT_REG_IDX_AR0);
1474  for (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++)
1475  xtensa->scratch_ars[s].intval = false;
1476  }
1477 
1478  /* We have used A3 (XT_REG_RELGEN) as a scratch register. Restore and flag for write-back. */
1481  if (xtensa->core_config->core_type == XT_NX) {
1484  }
1485 
1486  xtensa->regs_fetched = true;
1487 xtensa_fetch_all_regs_done:
1488  free(regvals);
1489  free(dsrs);
1490  return res;
1491 }
1492 
1494  struct reg **reg_list[],
1495  int *reg_list_size,
1496  enum target_register_class reg_class)
1497 {
1498  struct xtensa *xtensa = target_to_xtensa(target);
1499  unsigned int num_regs;
1500 
1501  if (reg_class == REG_CLASS_GENERAL) {
1503  LOG_ERROR("reg_class %d unhandled; 'xtgregs' not found", reg_class);
1504  return ERROR_FAIL;
1505  }
1506  num_regs = xtensa->genpkt_regs_num;
1507  } else {
1508  /* Determine whether to return a contiguous or sparse register map */
1510  }
1511 
1512  LOG_DEBUG("reg_class=%i, num_regs=%d", (int)reg_class, num_regs);
1513 
1514  *reg_list = calloc(num_regs, sizeof(struct reg *));
1515  if (!*reg_list)
1516  return ERROR_FAIL;
1517 
1518  *reg_list_size = num_regs;
1519  if (xtensa->regmap_contiguous) {
1520  assert((num_regs <= xtensa->total_regs_num) && "contiguous regmap size internal error!");
1521  for (unsigned int i = 0; i < num_regs; i++)
1522  (*reg_list)[i] = xtensa->contiguous_regs_list[i];
1523  return ERROR_OK;
1524  }
1525 
1526  for (unsigned int i = 0; i < num_regs; i++)
1527  (*reg_list)[i] = (struct reg *)&xtensa->empty_regs[i];
1528  unsigned int k = 0;
1529  for (unsigned int i = 0; i < xtensa->core_cache->num_regs && k < num_regs; i++) {
1530  if (xtensa->core_cache->reg_list[i].exist) {
1531  struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs;
1532  unsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS;
1533  int sparse_idx = rlist[ridx].dbreg_num;
1534  if (i == XT_REG_IDX_PS && xtensa->core_config->core_type == XT_LX) {
1535  if (xtensa->eps_dbglevel_idx == 0) {
1536  LOG_ERROR("eps_dbglevel_idx not set\n");
1537  return ERROR_FAIL;
1538  }
1539  (*reg_list)[sparse_idx] = &xtensa->core_cache->reg_list[xtensa->eps_dbglevel_idx];
1541  LOG_DEBUG("SPARSE GDB reg 0x%x getting EPS%d 0x%x",
1542  sparse_idx, xtensa->core_config->debug.irq_level,
1543  xtensa_reg_get_value((*reg_list)[sparse_idx]));
1544  } else if (rlist[ridx].type == XT_REG_RELGEN) {
1545  (*reg_list)[sparse_idx - XT_REG_IDX_ARFIRST] = &xtensa->core_cache->reg_list[i];
1546  } else {
1547  (*reg_list)[sparse_idx] = &xtensa->core_cache->reg_list[i];
1548  }
1549  if (i == XT_REG_IDX_PC)
1550  /* Make a duplicate copy of PC for external access */
1551  (*reg_list)[XT_PC_DBREG_NUM_BASE] = &xtensa->core_cache->reg_list[i];
1552  k++;
1553  }
1554  }
1555 
1556  if (k == num_regs)
1557  LOG_ERROR("SPARSE GDB reg list full (size %d)", k);
1558 
1559  return ERROR_OK;
1560 }
1561 
1562 int xtensa_mmu_is_enabled(struct target *target, bool *enabled)
1563 {
1564  struct xtensa *xtensa = target_to_xtensa(target);
1565  *enabled = xtensa->core_config->mmu.itlb_entries_count > 0 ||
1567  return ERROR_OK;
1568 }
1569 
1571 {
1572  struct xtensa *xtensa = target_to_xtensa(target);
1573 
1574  LOG_TARGET_DEBUG(target, "start");
1575  if (target->state == TARGET_HALTED) {
1576  LOG_TARGET_DEBUG(target, "target was already halted");
1577  return ERROR_OK;
1578  }
1579  /* First we have to read dsr and check if the target stopped */
1581  if (res != ERROR_OK) {
1582  LOG_TARGET_ERROR(target, "Failed to read core status!");
1583  return res;
1584  }
1585  LOG_TARGET_DEBUG(target, "Core status 0x%" PRIx32, xtensa_dm_core_status_get(&xtensa->dbg_mod));
1586  if (!xtensa_is_stopped(target)) {
1590  if (res != ERROR_OK)
1591  LOG_TARGET_ERROR(target, "Failed to set OCDDCR_DEBUGINTERRUPT. Can't halt.");
1592  }
1593 
1594  return res;
1595 }
1596 
1598  bool current,
1600  bool handle_breakpoints,
1601  bool debug_execution)
1602 {
1603  struct xtensa *xtensa = target_to_xtensa(target);
1604  uint32_t bpena = 0;
1605 
1607  "current=%d address=" TARGET_ADDR_FMT ", handle_breakpoints=%i, debug_execution=%i)",
1608  current,
1609  address,
1610  handle_breakpoints,
1611  debug_execution);
1612 
1613  if (target->state != TARGET_HALTED) {
1614  LOG_TARGET_ERROR(target, "not halted");
1615  return ERROR_TARGET_NOT_HALTED;
1616  }
1617  xtensa->halt_request = false;
1618 
1619  if (address && !current) {
1621  } else {
1622  uint32_t cause = xtensa_cause_get(target);
1623  LOG_TARGET_DEBUG(target, "DEBUGCAUSE 0x%x (watchpoint %lu) (break %lu)",
1624  cause, (cause & DEBUGCAUSE_DB), (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN)));
1625  if (cause & DEBUGCAUSE_DB)
1626  /* We stopped due to a watchpoint. We can't just resume executing the
1627  * instruction again because */
1628  /* that would trigger the watchpoint again. To fix this, we single-step,
1629  * which ignores watchpoints. */
1630  xtensa_do_step(target, current, address, handle_breakpoints);
1631  if (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN))
1632  /* We stopped due to a break instruction. We can't just resume executing the
1633  * instruction again because */
1634  /* that would trigger the break again. To fix this, we single-step, which
1635  * ignores break. */
1636  xtensa_do_step(target, current, address, handle_breakpoints);
1637  }
1638 
1639  /* Write back hw breakpoints. Current FreeRTOS SMP code can set a hw breakpoint on an
1640  * exception; we need to clear that and return to the breakpoints gdb has set on resume. */
1641  for (unsigned int slot = 0; slot < xtensa->core_config->debug.ibreaks_num; slot++) {
1642  if (xtensa->hw_brps[slot]) {
1643  /* Write IBREAKA[slot] and set bit #slot in IBREAKENABLE */
1645  if (xtensa->core_config->core_type == XT_NX)
1647  bpena |= BIT(slot);
1648  }
1649  }
1650  if (xtensa->core_config->core_type == XT_LX)
1652 
1653  /* Here we write all registers to the targets */
1655  if (res != ERROR_OK)
1656  LOG_TARGET_ERROR(target, "Failed to write back register cache.");
1657  return res;
1658 }
1659 
1661 {
1662  struct xtensa *xtensa = target_to_xtensa(target);
1663 
1664  LOG_TARGET_DEBUG(target, "start");
1665 
1668  int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
1669  if (res != ERROR_OK) {
1670  LOG_TARGET_ERROR(target, "Failed to exec RFDO %d!", res);
1671  return res;
1672  }
1674  return ERROR_OK;
1675 }
1676 
1678  bool current,
1680  bool handle_breakpoints,
1681  bool debug_execution)
1682 {
1683  LOG_TARGET_DEBUG(target, "start");
1684  int res = xtensa_prepare_resume(target, current, address,
1685  handle_breakpoints, debug_execution);
1686  if (res != ERROR_OK) {
1687  LOG_TARGET_ERROR(target, "Failed to prepare for resume!");
1688  return res;
1689  }
1690  res = xtensa_do_resume(target);
1691  if (res != ERROR_OK) {
1692  LOG_TARGET_ERROR(target, "Failed to resume!");
1693  return res;
1694  }
1695 
1697  if (!debug_execution)
1699  else
1701 
1703 
1704  return ERROR_OK;
1705 }
1706 
1708 {
1709  struct xtensa *xtensa = target_to_xtensa(target);
1710  uint8_t insn_buf[XT_ISNS_SZ_MAX];
1711  int err = xtensa_read_buffer(target, pc, sizeof(insn_buf), insn_buf);
1712  if (err != ERROR_OK)
1713  return false;
1714 
1715  xtensa_insn_t insn = buf_get_u32(insn_buf, 0, 24);
1716  xtensa_insn_t masked = insn & XT_INS_L32E_S32E_MASK(xtensa);
1717  if (masked == XT_INS_L32E(xtensa, 0, 0, 0) || masked == XT_INS_S32E(xtensa, 0, 0, 0))
1718  return true;
1719 
1720  masked = insn & XT_INS_RFWO_RFWU_MASK(xtensa);
1721  if (masked == XT_INS_RFWO(xtensa) || masked == XT_INS_RFWU(xtensa))
1722  return true;
1723 
1724  return false;
1725 }
1726 
1727 int xtensa_do_step(struct target *target, bool current, target_addr_t address,
1728  bool handle_breakpoints)
1729 {
1730  struct xtensa *xtensa = target_to_xtensa(target);
1731  int res;
1732  const uint32_t icount_val = -2; /* ICOUNT value to load for 1 step */
1734  xtensa_reg_val_t icountlvl, cause;
1735  xtensa_reg_val_t oldps, oldpc, cur_pc;
1736  bool ps_modified = false;
1737 
1738  LOG_TARGET_DEBUG(target, "current=%d, address=" TARGET_ADDR_FMT ", handle_breakpoints=%i",
1739  current, address, handle_breakpoints);
1740 
1741  if (target->state != TARGET_HALTED) {
1742  LOG_TARGET_ERROR(target, "not halted");
1743  return ERROR_TARGET_NOT_HALTED;
1744  }
1745 
1747  LOG_TARGET_ERROR(target, "eps_dbglevel_idx not set\n");
1748  return ERROR_FAIL;
1749  }
1750 
1751  /* Save old ps (EPS[dbglvl] on LX), pc */
1755 
1756  cause = xtensa_cause_get(target);
1757  LOG_TARGET_DEBUG(target, "oldps=%" PRIx32 ", oldpc=%" PRIx32 " dbg_cause=%" PRIx32 " exc_cause=%" PRIx32,
1758  oldps,
1759  oldpc,
1760  cause,
1762  if (handle_breakpoints && (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN))) {
1763  /* handle hard-coded SW breakpoints (e.g. syscalls) */
1764  LOG_TARGET_DEBUG(target, "Increment PC to pass break instruction...");
1765  xtensa_cause_clear(target); /* so we don't recurse into the same routine */
1766  /* pretend that we have stepped */
1767  if (cause & DEBUGCAUSE_BI)
1768  xtensa_reg_set(target, XT_REG_IDX_PC, oldpc + 3); /* PC = PC+3 */
1769  else
1770  xtensa_reg_set(target, XT_REG_IDX_PC, oldpc + 2); /* PC = PC+2 */
1771  return ERROR_OK;
1772  }
1773 
1774  /* Xtensa LX has an ICOUNTLEVEL register which sets the maximum interrupt level
1775  * at which the instructions are to be counted while stepping.
1776  *
1777  * For example, if we need to step by 2 instructions, and an interrupt occurs
1778  * in between, the processor will trigger the interrupt and halt after the 2nd
1779  * instruction within the interrupt vector and/or handler.
1780  *
1781  * However, sometimes we don't want the interrupt handlers to be executed at all
1782  * while stepping through the code. In this case (XT_STEPPING_ISR_OFF),
1783  * ICOUNTLEVEL can be lowered to the executing code's (level + 1) to prevent ISR
1784  * code from being counted during stepping. Note that C exception handlers must
1785  * run at level 0 and hence will be counted and stepped into, should one occur.
1786  *
1787  * TODO: Certain instructions should never be single-stepped and should instead
1788  * be emulated (per DUG): RSIL >= DBGLEVEL, RSR/WSR [ICOUNT|ICOUNTLEVEL], and
1789  * RFI >= DBGLEVEL.
1790  */
1792  if (xtensa->core_config->core_type == XT_LX) {
1795  "disabling IRQs while stepping is not implemented w/o high prio IRQs option!");
1796  return ERROR_FAIL;
1797  }
1798  /* Update ICOUNTLEVEL accordingly */
1799  icountlvl = MIN((oldps & 0xF) + 1, xtensa->core_config->debug.irq_level);
1800  } else {
1801  /* Xtensa NX does not have the ICOUNTLEVEL feature present in Xtensa LX
1802  * and instead disable interrupts while stepping. This could change
1803  * the timing of the system while under debug */
1804  xtensa_reg_val_t newps = oldps | XT_PS_DI_MSK;
1806  icountlvl = xtensa->core_config->debug.irq_level;
1807  ps_modified = true;
1808  }
1809  } else {
1810  icountlvl = xtensa->core_config->debug.irq_level;
1811  }
1812 
1813  if (cause & DEBUGCAUSE_DB) {
1814  /* We stopped due to a watchpoint. We can't just resume executing the instruction again because
1815  * that would trigger the watchpoint again. To fix this, we remove watchpoints,single-step and
1816  * re-enable the watchpoint. */
1818  target,
1819  "Single-stepping to get past instruction that triggered the watchpoint...");
1820  xtensa_cause_clear(target); /* so we don't recurse into the same routine */
1821  /* Save all DBREAKCx registers and set to 0 to disable watchpoints */
1822  for (unsigned int slot = 0; slot < xtensa->core_config->debug.dbreaks_num; slot++) {
1825  }
1826  }
1827 
1828  if (!handle_breakpoints && (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN)))
1829  /* handle normal SW breakpoint */
1830  xtensa_cause_clear(target); /* so we don't recurse into the same routine */
1831  if (xtensa->core_config->core_type == XT_LX && ((oldps & 0xf) >= icountlvl)) {
1832  /* Lower interrupt level to allow stepping, but flag eps[dbglvl] to be restored */
1833  ps_modified = true;
1834  uint32_t newps = (oldps & ~0xf) | (icountlvl - 1);
1837  "Lowering PS.INTLEVEL to allow stepping: %s <- 0x%08" PRIx32 " (was 0x%08" PRIx32 ")",
1839  newps,
1840  oldps);
1841  }
1842  do {
1843  if (xtensa->core_config->core_type == XT_LX) {
1845  xtensa_reg_set(target, XT_REG_IDX_ICOUNT, icount_val);
1846  } else {
1848  }
1849 
1850  /* Now that ICOUNT (LX) or DCR.StepRequest (NX) is set,
1851  * we can resume as if we were going to run
1852  */
1853  res = xtensa_prepare_resume(target, current, address, false, false);
1854  if (res != ERROR_OK) {
1855  LOG_TARGET_ERROR(target, "Failed to prepare resume for single step");
1856  return res;
1857  }
1858  res = xtensa_do_resume(target);
1859  if (res != ERROR_OK) {
1860  LOG_TARGET_ERROR(target, "Failed to resume after setting up single step");
1861  return res;
1862  }
1863 
1864  /* Wait for stepping to complete */
1865  long long start = timeval_ms();
1866  while (timeval_ms() < start + 500) {
1867  /* Do not use target_poll here, it also triggers other things... just manually read the DSR
1868  *until stepping is complete. */
1869  usleep(1000);
1871  if (res != ERROR_OK) {
1872  LOG_TARGET_ERROR(target, "Failed to read core status!");
1873  return res;
1874  }
1876  break;
1877  usleep(1000);
1878  }
1879  LOG_TARGET_DEBUG(target, "Finish stepping. dsr=0x%08" PRIx32,
1881  if (!xtensa_is_stopped(target)) {
1883  target,
1884  "Timed out waiting for target to finish stepping. dsr=0x%08" PRIx32,
1888  return ERROR_FAIL;
1889  }
1890 
1892  cur_pc = xtensa_reg_get(target, XT_REG_IDX_PC);
1893 
1895  "cur_ps=%" PRIx32 ", cur_pc=%" PRIx32 " dbg_cause=%" PRIx32 " exc_cause=%" PRIx32,
1897  cur_pc,
1900 
1901  /* Do not step into WindowOverflow if ISRs are masked.
1902  If we stop in WindowOverflow at breakpoint with masked ISRs and
1903  try to do a step it will get us out of that handler */
1904  if (xtensa->core_config->windowed &&
1906  xtensa_pc_in_winexc(target, cur_pc)) {
1907  /* isrmask = on, need to step out of the window exception handler */
1908  LOG_DEBUG("Stepping out of window exception, PC=%" PRIX32, cur_pc);
1909  oldpc = cur_pc;
1910  address = oldpc + 3;
1911  continue;
1912  }
1913 
1914  if (oldpc == cur_pc)
1915  LOG_TARGET_WARNING(target, "Stepping doesn't seem to change PC! dsr=0x%08" PRIx32,
1917  else
1918  LOG_DEBUG("Stepped from %" PRIX32 " to %" PRIX32, oldpc, cur_pc);
1919  break;
1920  } while (true);
1921 
1924  LOG_DEBUG("Done stepping, PC=%" PRIX32, cur_pc);
1925 
1926  if (cause & DEBUGCAUSE_DB) {
1927  LOG_TARGET_DEBUG(target, "...Done, re-installing watchpoints.");
1928  /* Restore the DBREAKCx registers */
1929  for (unsigned int slot = 0; slot < xtensa->core_config->debug.dbreaks_num; slot++)
1931  }
1932 
1933  /* Restore int level */
1934  if (ps_modified) {
1935  LOG_DEBUG("Restoring %s after stepping: 0x%08" PRIx32,
1940  }
1941 
1942  /* write ICOUNTLEVEL back to zero */
1944  /* TODO: can we skip writing dirty registers and re-fetching them? */
1947  return res;
1948 }
1949 
1950 int xtensa_step(struct target *target, bool current, target_addr_t address,
1951  bool handle_breakpoints)
1952 {
1953  int retval = xtensa_do_step(target, current, address, handle_breakpoints);
1954  if (retval != ERROR_OK)
1955  return retval;
1957 
1958  return ERROR_OK;
1959 }
1960 
1964 static inline bool xtensa_memory_regions_overlap(target_addr_t r1_start,
1965  target_addr_t r1_end,
1966  target_addr_t r2_start,
1967  target_addr_t r2_end)
1968 {
1969  if ((r2_start >= r1_start) && (r2_start < r1_end))
1970  return true; /* r2_start is in r1 region */
1971  if ((r2_end > r1_start) && (r2_end <= r1_end))
1972  return true; /* r2_end is in r1 region */
1973  return false;
1974 }
1975 
1980  target_addr_t r1_end,
1981  target_addr_t r2_start,
1982  target_addr_t r2_end)
1983 {
1984  if (xtensa_memory_regions_overlap(r1_start, r1_end, r2_start, r2_end)) {
1985  target_addr_t ov_start = r1_start < r2_start ? r2_start : r1_start;
1986  target_addr_t ov_end = r1_end > r2_end ? r2_end : r1_end;
1987  return ov_end - ov_start;
1988  }
1989  return 0;
1990 }
1991 
1995 static bool xtensa_memory_op_validate_range(struct xtensa *xtensa, target_addr_t address, size_t size, int access)
1996 {
1997  target_addr_t adr_pos = address; /* address cursor set to the beginning start */
1998  target_addr_t adr_end = address + size; /* region end */
1999  target_addr_t overlap_size;
2000  const struct xtensa_local_mem_region_config *cm; /* current mem region */
2001 
2002  while (adr_pos < adr_end) {
2004  if (!cm) /* address is not belong to anything */
2005  return false;
2006  if ((cm->access & access) != access) /* access check */
2007  return false;
2008  overlap_size = xtensa_get_overlap_size(cm->base, (cm->base + cm->size), adr_pos, adr_end);
2009  assert(overlap_size != 0);
2010  adr_pos += overlap_size;
2011  }
2012  return true;
2013 }
2014 
2015 int xtensa_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
2016 {
2017  struct xtensa *xtensa = target_to_xtensa(target);
2018  /* We are going to read memory in 32-bit increments. This may not be what the calling
2019  * function expects, so we may need to allocate a temp buffer and read into that first. */
2020  target_addr_t addrstart_al = ALIGN_DOWN(address, 4);
2021  target_addr_t addrend_al = ALIGN_UP(address + size * count, 4);
2022  target_addr_t adr = addrstart_al;
2023  uint8_t *albuff;
2024  bool bswap = xtensa->target->endianness == TARGET_BIG_ENDIAN;
2025 
2026  if (target->state != TARGET_HALTED) {
2027  LOG_TARGET_ERROR(target, "not halted");
2028  return ERROR_TARGET_NOT_HALTED;
2029  }
2030 
2031  if (!xtensa->permissive_mode) {
2033  XT_MEM_ACCESS_READ)) {
2034  LOG_DEBUG("address " TARGET_ADDR_FMT " not readable", address);
2035  return ERROR_FAIL;
2036  }
2037  }
2038 
2039  unsigned int alloc_bytes = ALIGN_UP(addrend_al - addrstart_al, sizeof(uint32_t));
2040  albuff = calloc(alloc_bytes, 1);
2041  if (!albuff) {
2042  LOG_TARGET_ERROR(target, "Out of memory allocating %" PRId64 " bytes!",
2043  addrend_al - addrstart_al);
2045  }
2046 
2047  /* We're going to use A3 here */
2049  /* Write start address to A3 */
2052  /* Now we can safely read data from addrstart_al up to addrend_al into albuff */
2053  if (xtensa->probe_lsddr32p != 0) {
2055  for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t))
2057  (adr + sizeof(uint32_t) == addrend_al) ? XDMREG_DDR : XDMREG_DDREXEC,
2058  &albuff[i]);
2059  } else {
2061  for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) {
2065  xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, adr + sizeof(uint32_t));
2067  }
2068  }
2069  int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
2070  if (res == ERROR_OK) {
2071  bool prev_suppress = xtensa->suppress_dsr_errors;
2072  xtensa->suppress_dsr_errors = true;
2074  if (xtensa->probe_lsddr32p == -1)
2075  xtensa->probe_lsddr32p = 1;
2076  xtensa->suppress_dsr_errors = prev_suppress;
2077  }
2078  if (res != ERROR_OK) {
2079  if (xtensa->probe_lsddr32p != 0) {
2080  /* Disable fast memory access instructions and retry before reporting an error */
2081  LOG_TARGET_DEBUG(target, "Disabling LDDR32.P/SDDR32.P");
2082  xtensa->probe_lsddr32p = 0;
2084  } else {
2085  LOG_TARGET_WARNING(target, "Failed reading %d bytes at address "TARGET_ADDR_FMT,
2086  count * size, address);
2087  }
2088  } else {
2089  if (bswap)
2090  buf_bswap32(albuff, albuff, addrend_al - addrstart_al);
2091  memcpy(buffer, albuff + (address & 3), (size * count));
2092  }
2093  free(albuff);
2094  return res;
2095 }
2096 
2098 {
2099  /* xtensa_read_memory can also read unaligned stuff. Just pass through to that routine. */
2101 }
2102 
2105  uint32_t size,
2106  uint32_t count,
2107  const uint8_t *buffer)
2108 {
2109  /* This memory write function can get thrown nigh everything into it, from
2110  * aligned uint32 writes to unaligned uint8ths. The Xtensa memory doesn't always
2111  * accept anything but aligned uint32 writes, though. That is why we convert
2112  * everything into that. */
2113  struct xtensa *xtensa = target_to_xtensa(target);
2114  target_addr_t addrstart_al = ALIGN_DOWN(address, 4);
2115  target_addr_t addrend_al = ALIGN_UP(address + size * count, 4);
2116  target_addr_t adr = addrstart_al;
2117  int res;
2118  uint8_t *albuff;
2119  bool fill_head_tail = false;
2120 
2121  if (target->state != TARGET_HALTED) {
2122  LOG_TARGET_ERROR(target, "not halted");
2123  return ERROR_TARGET_NOT_HALTED;
2124  }
2125 
2126  if (!xtensa->permissive_mode) {
2128  LOG_WARNING("address " TARGET_ADDR_FMT " not writable", address);
2129  return ERROR_FAIL;
2130  }
2131  }
2132 
2133  if (size == 0 || count == 0 || !buffer)
2135 
2136  /* Allocate a temporary buffer to put the aligned bytes in, if needed. */
2137  if (addrstart_al == address && addrend_al == address + (size * count)) {
2139  /* Need a buffer for byte-swapping */
2140  albuff = malloc(addrend_al - addrstart_al);
2141  else
2142  /* We discard the const here because albuff can also be non-const */
2143  albuff = (uint8_t *)buffer;
2144  } else {
2145  fill_head_tail = true;
2146  albuff = malloc(addrend_al - addrstart_al);
2147  }
2148  if (!albuff) {
2149  LOG_TARGET_ERROR(target, "Out of memory allocating %" PRId64 " bytes!",
2150  addrend_al - addrstart_al);
2152  }
2153 
2154  /* We're going to use A3 here */
2156 
2157  /* If we're using a temp aligned buffer, we need to fill the head and/or tail bit of it. */
2158  if (fill_head_tail) {
2159  /* See if we need to read the first and/or last word. */
2160  if (address & 3) {
2163  if (xtensa->probe_lsddr32p == 1) {
2165  } else {
2168  }
2170  }
2171  if ((address + (size * count)) & 3) {
2172  xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addrend_al - 4);
2174  if (xtensa->probe_lsddr32p == 1) {
2176  } else {
2179  }
2181  &albuff[addrend_al - addrstart_al - 4]);
2182  }
2183  /* Grab bytes */
2185  if (res != ERROR_OK) {
2186  LOG_ERROR("Error issuing unaligned memory write context instruction(s): %d", res);
2187  if (albuff != buffer)
2188  free(albuff);
2189  return res;
2190  }
2193  bool swapped_w0 = false;
2194  if (address & 3) {
2195  buf_bswap32(&albuff[0], &albuff[0], 4);
2196  swapped_w0 = true;
2197  }
2198  if ((address + (size * count)) & 3) {
2199  if ((addrend_al - addrstart_al - 4 == 0) && swapped_w0) {
2200  /* Don't double-swap if buffer start/end are within the same word */
2201  } else {
2202  buf_bswap32(&albuff[addrend_al - addrstart_al - 4],
2203  &albuff[addrend_al - addrstart_al - 4], 4);
2204  }
2205  }
2206  }
2207  /* Copy data to be written into the aligned buffer (in host-endianness) */
2208  memcpy(&albuff[address & 3], buffer, size * count);
2209  /* Now we can write albuff in aligned uint32s. */
2210  }
2211 
2213  buf_bswap32(albuff, fill_head_tail ? albuff : buffer, addrend_al - addrstart_al);
2214 
2215  /* Write start address to A3 */
2218  /* Write the aligned buffer */
2219  if (xtensa->probe_lsddr32p != 0) {
2220  for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) {
2221  if (i == 0) {
2224  } else {
2226  }
2227  }
2228  } else {
2230  for (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) {
2234  xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, adr + sizeof(uint32_t));
2236  }
2237  }
2238 
2240  if (res == ERROR_OK) {
2241  bool prev_suppress = xtensa->suppress_dsr_errors;
2242  xtensa->suppress_dsr_errors = true;
2244  if (xtensa->probe_lsddr32p == -1)
2245  xtensa->probe_lsddr32p = 1;
2246  xtensa->suppress_dsr_errors = prev_suppress;
2247  }
2248  if (res != ERROR_OK) {
2249  if (xtensa->probe_lsddr32p != 0) {
2250  /* Disable fast memory access instructions and retry before reporting an error */
2251  LOG_TARGET_INFO(target, "Disabling LDDR32.P/SDDR32.P");
2252  xtensa->probe_lsddr32p = 0;
2254  } else {
2255  LOG_TARGET_WARNING(target, "Failed writing %d bytes at address "TARGET_ADDR_FMT,
2256  count * size, address);
2257  }
2258  } else {
2259  /* Invalidate ICACHE, writeback DCACHE if present */
2260  bool issue_ihi = xtensa_is_icacheable(xtensa, address) &&
2261  xtensa_region_ar_exec(target, addrstart_al, addrend_al);
2262  bool issue_dhwbi = xtensa_is_dcacheable(xtensa, address);
2263  LOG_TARGET_DEBUG(target, "Cache OPs: IHI %d, DHWBI %d", issue_ihi, issue_dhwbi);
2264  if (issue_ihi || issue_dhwbi) {
2265  uint32_t ilinesize = issue_ihi ? xtensa->core_config->icache.line_size : UINT32_MAX;
2266  uint32_t dlinesize = issue_dhwbi ? xtensa->core_config->dcache.line_size : UINT32_MAX;
2267  uint32_t linesize = MIN(ilinesize, dlinesize);
2268  uint32_t off = 0;
2269  adr = addrstart_al;
2270 
2271  while ((adr + off) < addrend_al) {
2272  if (off == 0) {
2273  /* Write start address to A3 */
2276  }
2277  if (issue_ihi)
2279  if (issue_dhwbi)
2281  off += linesize;
2282  if (off > 1020) {
2283  /* IHI, DHWB have 8-bit immediate operands (0..1020) */
2284  adr += off;
2285  off = 0;
2286  }
2287  }
2288 
2289  /* Execute cache WB/INV instructions */
2291  if (res != ERROR_OK)
2293  "Error queuing cache writeback/invaldate instruction(s): %d",
2294  res);
2296  if (res != ERROR_OK)
2298  "Error issuing cache writeback/invaldate instruction(s): %d",
2299  res);
2300  }
2301  }
2302  if (albuff != buffer)
2303  free(albuff);
2304 
2305  return res;
2306 }
2307 
2308 int xtensa_write_buffer(struct target *target, target_addr_t address, uint32_t count, const uint8_t *buffer)
2309 {
2310  /* xtensa_write_memory can handle everything. Just pass on to that. */
2312 }
2313 
2314 int xtensa_checksum_memory(struct target *target, target_addr_t address, uint32_t count, uint32_t *checksum)
2315 {
2316  LOG_WARNING("not implemented yet");
2317  return ERROR_FAIL;
2318 }
2319 
2321 {
2322  struct xtensa *xtensa = target_to_xtensa(target);
2323  if (xtensa_dm_poll(&xtensa->dbg_mod) != ERROR_OK) {
2326  }
2327 
2331  LOG_TARGET_DEBUG(target, "PWRSTAT: read 0x%08" PRIx32 ", clear 0x%08lx, reread 0x%08" PRIx32,
2335  if (res != ERROR_OK)
2336  return res;
2337 
2339  LOG_TARGET_INFO(target, "Debug controller was reset.");
2341  if (res != ERROR_OK)
2342  return res;
2343  }
2345  LOG_TARGET_INFO(target, "Core was reset.");
2347  /* Enable JTAG, set reset if needed */
2348  res = xtensa_wakeup(target);
2349  if (res != ERROR_OK)
2350  return res;
2351 
2352  uint32_t prev_dsr = xtensa->dbg_mod.core_status.dsr;
2354  if (res != ERROR_OK)
2355  return res;
2356  if (prev_dsr != xtensa->dbg_mod.core_status.dsr)
2358  "DSR has changed: was 0x%08" PRIx32 " now 0x%08" PRIx32,
2359  prev_dsr,
2362  /* if RESET state is persitent */
2364  } else if (!xtensa_dm_is_powered(&xtensa->dbg_mod)) {
2365  LOG_TARGET_DEBUG(target, "not powered 0x%" PRIX32 "%ld",
2369  if (xtensa->come_online_probes_num == 0)
2370  target->examined = false;
2371  else
2373  } else if (xtensa_is_stopped(target)) {
2374  if (target->state != TARGET_HALTED) {
2375  enum target_state oldstate = target->state;
2377  /* Examine why the target has been halted */
2380  /* When setting debug reason DEBUGCAUSE events have the following
2381  * priorities: watchpoint == breakpoint > single step > debug interrupt. */
2382  /* Watchpoint and breakpoint events at the same time results in special
2383  * debug reason: DBG_REASON_WPTANDBKPT. */
2384  uint32_t halt_cause = xtensa_cause_get(target);
2385  /* TODO: Add handling of DBG_REASON_EXC_CATCH */
2386  if (halt_cause & DEBUGCAUSE_IC)
2388  if (halt_cause & (DEBUGCAUSE_IB | DEBUGCAUSE_BN | DEBUGCAUSE_BI)) {
2389  if (halt_cause & DEBUGCAUSE_DB)
2391  else
2393  } else if (halt_cause & DEBUGCAUSE_DB) {
2395  }
2396  LOG_TARGET_DEBUG(target, "Target halted, pc=0x%08" PRIx32
2397  ", debug_reason=%08" PRIx32 ", oldstate=%08" PRIx32,
2400  oldstate);
2401  LOG_TARGET_DEBUG(target, "Halt reason=0x%08" PRIX32 ", exc_cause=%" PRId32 ", dsr=0x%08" PRIx32,
2402  halt_cause,
2406  &xtensa->dbg_mod,
2410  if (xtensa->core_config->core_type == XT_NX) {
2411  /* Enable imprecise exceptions while in halted state */
2413  xtensa_reg_val_t newps = ps & ~(XT_PS_DIEXC_MSK);
2415  LOG_TARGET_DEBUG(target, "Enabling PS.DIEXC: 0x%08x -> 0x%08x", ps, newps);
2420  if (res != ERROR_OK) {
2421  LOG_TARGET_ERROR(target, "Failed to write PS.DIEXC (%d)!", res);
2422  return res;
2423  }
2425  }
2426  }
2427  } else {
2432  }
2433  }
2434  if (xtensa->trace_active) {
2435  /* Detect if tracing was active but has stopped. */
2438  if (res == ERROR_OK) {
2439  if (!(trace_status.stat & TRAXSTAT_TRACT)) {
2440  LOG_INFO("Detected end of trace.");
2441  if (trace_status.stat & TRAXSTAT_PCMTG)
2442  LOG_TARGET_INFO(target, "Trace stop triggered by PC match");
2443  if (trace_status.stat & TRAXSTAT_PTITG)
2444  LOG_TARGET_INFO(target, "Trace stop triggered by Processor Trigger Input");
2445  if (trace_status.stat & TRAXSTAT_CTITG)
2446  LOG_TARGET_INFO(target, "Trace stop triggered by Cross-trigger Input");
2447  xtensa->trace_active = false;
2448  }
2449  }
2450  }
2451  return ERROR_OK;
2452 }
2453 
2454 static int xtensa_update_instruction(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
2455 {
2456  struct xtensa *xtensa = target_to_xtensa(target);
2457  unsigned int issue_ihi = xtensa_is_icacheable(xtensa, address) &&
2459  unsigned int issue_dhwbi = xtensa_is_dcacheable(xtensa, address);
2460  uint32_t icache_line_size = issue_ihi ? xtensa->core_config->icache.line_size : UINT32_MAX;
2461  uint32_t dcache_line_size = issue_dhwbi ? xtensa->core_config->dcache.line_size : UINT32_MAX;
2462  unsigned int same_ic_line = ((address & (icache_line_size - 1)) + size) <= icache_line_size;
2463  unsigned int same_dc_line = ((address & (dcache_line_size - 1)) + size) <= dcache_line_size;
2464  int ret;
2465 
2466  if (size > icache_line_size)
2467  return ERROR_FAIL;
2468 
2469  if (issue_ihi || issue_dhwbi) {
2470  /* We're going to use A3 here */
2472 
2473  /* Write start address to A3 and invalidate */
2476  LOG_TARGET_DEBUG(target, "IHI %d, DHWBI %d for address " TARGET_ADDR_FMT,
2477  issue_ihi, issue_dhwbi, address);
2478  if (issue_dhwbi) {
2480  if (!same_dc_line) {
2482  "DHWBI second dcache line for address "TARGET_ADDR_FMT,
2483  address + 4);
2485  }
2486  }
2487  if (issue_ihi) {
2489  if (!same_ic_line) {
2491  "IHI second icache line for address "TARGET_ADDR_FMT,
2492  address + 4);
2494  }
2495  }
2496 
2497  /* Execute invalidate instructions */
2500  if (ret != ERROR_OK) {
2501  LOG_ERROR("Error issuing cache invaldate instruction(s): %d", ret);
2502  return ret;
2503  }
2504  }
2505 
2506  /* Write new instructions to memory */
2508  if (ret != ERROR_OK) {
2509  LOG_TARGET_ERROR(target, "Error writing instruction to memory: %d", ret);
2510  return ret;
2511  }
2512 
2513  if (issue_dhwbi) {
2514  /* Flush dcache so instruction propagates. A3 may be corrupted during memory write */
2518  LOG_DEBUG("DHWB dcache line for address "TARGET_ADDR_FMT, address);
2519  if (!same_dc_line) {
2520  LOG_TARGET_DEBUG(target, "DHWB second dcache line for address "TARGET_ADDR_FMT, address + 4);
2522  }
2523 
2524  /* Execute invalidate instructions */
2527  }
2528 
2529  /* TODO: Handle L2 cache if present */
2530  return ret;
2531 }
2532 
2534  struct breakpoint *breakpoint,
2535  struct xtensa_sw_breakpoint *sw_bp)
2536 {
2537  struct xtensa *xtensa = target_to_xtensa(target);
2539  if (ret != ERROR_OK) {
2540  LOG_TARGET_ERROR(target, "Failed to read original instruction (%d)!", ret);
2541  return ret;
2542  }
2543 
2545  sw_bp->oocd_bp = breakpoint;
2546 
2547  uint32_t break_insn = sw_bp->insn_sz == XT_ISNS_SZ_MAX ? XT_INS_BREAK(xtensa, 0, 0) : XT_INS_BREAKN(xtensa, 0);
2548 
2549  /* Underlying memory write will convert instruction endianness, don't do that here */
2550  ret = xtensa_update_instruction(target, breakpoint->address, sw_bp->insn_sz, (uint8_t *)&break_insn);
2551  if (ret != ERROR_OK) {
2552  LOG_TARGET_ERROR(target, "Failed to write breakpoint instruction (%d)!", ret);
2553  return ret;
2554  }
2555 
2556  return ERROR_OK;
2557 }
2558 
2560 {
2561  int ret = xtensa_update_instruction(target, sw_bp->oocd_bp->address, sw_bp->insn_sz, sw_bp->insn);
2562  if (ret != ERROR_OK) {
2563  LOG_TARGET_ERROR(target, "Failed to write insn (%d)!", ret);
2564  return ret;
2565  }
2566  sw_bp->oocd_bp = NULL;
2567  return ERROR_OK;
2568 }
2569 
2571 {
2572  struct xtensa *xtensa = target_to_xtensa(target);
2573  unsigned int slot;
2574 
2575  if (breakpoint->type == BKPT_SOFT) {
2576  for (slot = 0; slot < XT_SW_BREAKPOINTS_MAX_NUM; slot++) {
2577  if (!xtensa->sw_brps[slot].oocd_bp ||
2579  break;
2580  }
2582  LOG_TARGET_WARNING(target, "No free slots to add SW breakpoint!");
2584  }
2586  if (ret != ERROR_OK) {
2587  LOG_TARGET_ERROR(target, "Failed to add SW breakpoint!");
2588  return ret;
2589  }
2590  LOG_TARGET_DEBUG(target, "placed SW breakpoint %u @ " TARGET_ADDR_FMT,
2591  slot,
2592  breakpoint->address);
2593  return ERROR_OK;
2594  }
2595 
2596  for (slot = 0; slot < xtensa->core_config->debug.ibreaks_num; slot++) {
2597  if (!xtensa->hw_brps[slot] || xtensa->hw_brps[slot] == breakpoint)
2598  break;
2599  }
2601  LOG_TARGET_ERROR(target, "No free slots to add HW breakpoint!");
2603  }
2604 
2606  /* We will actually write the breakpoints when we resume the target. */
2607  LOG_TARGET_DEBUG(target, "placed HW breakpoint %u @ " TARGET_ADDR_FMT,
2608  slot,
2609  breakpoint->address);
2610 
2611  return ERROR_OK;
2612 }
2613 
2615 {
2616  struct xtensa *xtensa = target_to_xtensa(target);
2617  unsigned int slot;
2618 
2619  if (breakpoint->type == BKPT_SOFT) {
2620  for (slot = 0; slot < XT_SW_BREAKPOINTS_MAX_NUM; slot++) {
2622  break;
2623  }
2625  LOG_TARGET_WARNING(target, "Max SW breakpoints slot reached, slot=%u!", slot);
2627  }
2629  if (ret != ERROR_OK) {
2630  LOG_TARGET_ERROR(target, "Failed to remove SW breakpoint (%d)!", ret);
2631  return ret;
2632  }
2633  LOG_TARGET_DEBUG(target, "cleared SW breakpoint %u @ " TARGET_ADDR_FMT, slot, breakpoint->address);
2634  return ERROR_OK;
2635  }
2636 
2637  for (slot = 0; slot < xtensa->core_config->debug.ibreaks_num; slot++) {
2638  if (xtensa->hw_brps[slot] == breakpoint)
2639  break;
2640  }
2642  LOG_TARGET_ERROR(target, "HW breakpoint not found!");
2644  }
2645  xtensa->hw_brps[slot] = NULL;
2646  if (xtensa->core_config->core_type == XT_NX)
2648  LOG_TARGET_DEBUG(target, "cleared HW breakpoint %u @ " TARGET_ADDR_FMT, slot, breakpoint->address);
2649  return ERROR_OK;
2650 }
2651 
2653 {
2654  struct xtensa *xtensa = target_to_xtensa(target);
2655  unsigned int slot;
2656  xtensa_reg_val_t dbreakcval;
2657 
2658  if (target->state != TARGET_HALTED) {
2659  LOG_TARGET_ERROR(target, "not halted");
2660  return ERROR_TARGET_NOT_HALTED;
2661  }
2662 
2664  LOG_TARGET_ERROR(target, "watchpoint value masks not supported");
2666  }
2667 
2668  for (slot = 0; slot < xtensa->core_config->debug.dbreaks_num; slot++) {
2669  if (!xtensa->hw_wps[slot] || xtensa->hw_wps[slot] == watchpoint)
2670  break;
2671  }
2673  LOG_TARGET_WARNING(target, "No free slots to add HW watchpoint!");
2675  }
2676 
2677  /* Figure out value for dbreakc5..0
2678  * It's basically 0x3F with an incremental bit removed from the LSB for each extra length power of 2. */
2679  if (watchpoint->length < 1 || watchpoint->length > 64 ||
2683  target,
2684  "Watchpoint with length %d on address " TARGET_ADDR_FMT
2685  " not supported by hardware.",
2686  watchpoint->length,
2687  watchpoint->address);
2689  }
2690  dbreakcval = ALIGN_DOWN(0x3F, watchpoint->length);
2691 
2692  if (watchpoint->rw == WPT_READ)
2693  dbreakcval |= BIT(30);
2694  if (watchpoint->rw == WPT_WRITE)
2695  dbreakcval |= BIT(31);
2696  if (watchpoint->rw == WPT_ACCESS)
2697  dbreakcval |= BIT(30) | BIT(31);
2698 
2699  /* Write DBREAKA[slot] and DBCREAKC[slot] */
2703  LOG_TARGET_DEBUG(target, "placed HW watchpoint @ " TARGET_ADDR_FMT,
2704  watchpoint->address);
2705  return ERROR_OK;
2706 }
2707 
2709 {
2710  struct xtensa *xtensa = target_to_xtensa(target);
2711  unsigned int slot;
2712 
2713  for (slot = 0; slot < xtensa->core_config->debug.dbreaks_num; slot++) {
2714  if (xtensa->hw_wps[slot] == watchpoint)
2715  break;
2716  }
2718  LOG_TARGET_WARNING(target, "HW watchpoint " TARGET_ADDR_FMT " not found!", watchpoint->address);
2720  }
2722  xtensa->hw_wps[slot] = NULL;
2723  LOG_TARGET_DEBUG(target, "cleared HW watchpoint @ " TARGET_ADDR_FMT,
2724  watchpoint->address);
2725  return ERROR_OK;
2726 }
2727 
2729  int num_mem_params, struct mem_param *mem_params,
2730  int num_reg_params, struct reg_param *reg_params,
2731  target_addr_t entry_point, target_addr_t exit_point,
2732  void *arch_info)
2733 {
2734  struct xtensa *xtensa = target_to_xtensa(target);
2735  struct xtensa_algorithm *algorithm_info = arch_info;
2736  int retval = ERROR_OK;
2737  bool usr_ps = false;
2738  uint32_t newps;
2739 
2740  /* NOTE: xtensa_run_algorithm requires that each algorithm uses a software breakpoint
2741  * at the exit point */
2742 
2743  if (target->state != TARGET_HALTED) {
2744  LOG_WARNING("Target not halted!");
2745  return ERROR_TARGET_NOT_HALTED;
2746  }
2747 
2749  if (retval != ERROR_OK) {
2750  LOG_ERROR("Failed to write dirty regs (%d)", retval);
2751  return retval;
2752  }
2753 
2754  for (unsigned int i = 0; i < xtensa->core_cache->num_regs; i++) {
2755  struct reg *reg = &xtensa->core_cache->reg_list[i];
2757  }
2758  /* save debug reason, it will be changed */
2759  if (!algorithm_info) {
2760  LOG_ERROR("BUG: arch_info not specified");
2761  return ERROR_FAIL;
2762  }
2763  algorithm_info->ctx_debug_reason = target->debug_reason;
2764  if (xtensa->core_config->core_type == XT_LX) {
2765  /* save PS and set to debug_level - 1 */
2766  algorithm_info->ctx_ps = xtensa_reg_get(target, xtensa->eps_dbglevel_idx);
2767  newps = (algorithm_info->ctx_ps & ~0xf) | (xtensa->core_config->debug.irq_level - 1);
2769  }
2770  /* write mem params */
2771  for (int i = 0; i < num_mem_params; i++) {
2772  if (mem_params[i].direction != PARAM_IN) {
2773  retval = target_write_buffer(target, mem_params[i].address,
2774  mem_params[i].size,
2775  mem_params[i].value);
2776  if (retval != ERROR_OK)
2777  return retval;
2778  }
2779  }
2780  /* write reg params */
2781  for (int i = 0; i < num_reg_params; i++) {
2782  if (reg_params[i].size > 32) {
2783  LOG_ERROR("BUG: not supported register size (%d)", reg_params[i].size);
2784  return ERROR_FAIL;
2785  }
2786  struct reg *reg = register_get_by_name(xtensa->core_cache, reg_params[i].reg_name, 0);
2787  if (!reg) {
2788  LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
2789  return ERROR_FAIL;
2790  }
2791  if (reg->size != reg_params[i].size) {
2792  LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
2793  return ERROR_FAIL;
2794  }
2795  if (memcmp(reg_params[i].reg_name, "ps", 3)) {
2796  usr_ps = true;
2797  } else if (xtensa->core_config->core_type == XT_LX) {
2798  unsigned int reg_id = xtensa->eps_dbglevel_idx;
2799  assert(reg_id < xtensa->core_cache->num_regs && "Attempt to access non-existing reg!");
2800  reg = &xtensa->core_cache->reg_list[reg_id];
2801  }
2802  xtensa_reg_set_value(reg, buf_get_u32(reg_params[i].value, 0, reg->size));
2803  reg->valid = 1;
2804  }
2805  /* ignore custom core mode if custom PS value is specified */
2806  if (!usr_ps && xtensa->core_config->core_type == XT_LX) {
2807  unsigned int eps_reg_idx = xtensa->eps_dbglevel_idx;
2808  xtensa_reg_val_t ps = xtensa_reg_get(target, eps_reg_idx);
2809  enum xtensa_mode core_mode = XT_PS_RING_GET(ps);
2810  if (algorithm_info->core_mode != XT_MODE_ANY && algorithm_info->core_mode != core_mode) {
2811  LOG_DEBUG("setting core_mode: 0x%x", algorithm_info->core_mode);
2812  xtensa_reg_val_t new_ps = (ps & ~XT_PS_RING_MSK) | XT_PS_RING(algorithm_info->core_mode);
2813  /* save previous core mode */
2814  /* TODO: core_mode is not restored for now. Can be added to the end of wait_algorithm */
2815  algorithm_info->core_mode = core_mode;
2816  xtensa_reg_set(target, eps_reg_idx, new_ps);
2817  xtensa->core_cache->reg_list[eps_reg_idx].valid = 1;
2818  }
2819  }
2820 
2821  return xtensa_resume(target, false, entry_point, true, true);
2822 }
2823 
2826  int num_mem_params, struct mem_param *mem_params,
2827  int num_reg_params, struct reg_param *reg_params,
2828  target_addr_t exit_point, unsigned int timeout_ms,
2829  void *arch_info)
2830 {
2831  struct xtensa *xtensa = target_to_xtensa(target);
2832  struct xtensa_algorithm *algorithm_info = arch_info;
2833  int retval = ERROR_OK;
2834  xtensa_reg_val_t pc;
2835 
2836  /* NOTE: xtensa_run_algorithm requires that each algorithm uses a software breakpoint
2837  * at the exit point */
2838 
2839  retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
2840  /* If the target fails to halt due to the breakpoint, force a halt */
2841  if (retval != ERROR_OK || target->state != TARGET_HALTED) {
2842  retval = target_halt(target);
2843  if (retval != ERROR_OK)
2844  return retval;
2845  retval = target_wait_state(target, TARGET_HALTED, 500);
2846  if (retval != ERROR_OK)
2847  return retval;
2848  LOG_TARGET_ERROR(target, "not halted %d, pc 0x%" PRIx32 ", ps 0x%" PRIx32, retval,
2852  return ERROR_TARGET_TIMEOUT;
2853  }
2855  if (exit_point && pc != exit_point) {
2856  LOG_ERROR("failed algorithm halted at 0x%" PRIx32 ", expected " TARGET_ADDR_FMT, pc, exit_point);
2857  return ERROR_TARGET_TIMEOUT;
2858  }
2859  /* Copy core register values to reg_params[] */
2860  for (int i = 0; i < num_reg_params; i++) {
2861  if (reg_params[i].direction != PARAM_OUT) {
2862  struct reg *reg = register_get_by_name(xtensa->core_cache, reg_params[i].reg_name, 0);
2863  if (!reg) {
2864  LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
2865  return ERROR_FAIL;
2866  }
2867  if (reg->size != reg_params[i].size) {
2868  LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
2869  return ERROR_FAIL;
2870  }
2871  buf_set_u32(reg_params[i].value, 0, 32, xtensa_reg_get_value(reg));
2872  }
2873  }
2874  /* Read memory values to mem_params */
2875  LOG_DEBUG("Read mem params");
2876  for (int i = 0; i < num_mem_params; i++) {
2877  LOG_DEBUG("Check mem param @ " TARGET_ADDR_FMT, mem_params[i].address);
2878  if (mem_params[i].direction != PARAM_OUT) {
2879  LOG_DEBUG("Read mem param @ " TARGET_ADDR_FMT, mem_params[i].address);
2880  retval = target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value);
2881  if (retval != ERROR_OK)
2882  return retval;
2883  }
2884  }
2885 
2886  /* avoid gdb keep_alive warning */
2887  keep_alive();
2888 
2889  for (int i = xtensa->core_cache->num_regs - 1; i >= 0; i--) {
2890  struct reg *reg = &xtensa->core_cache->reg_list[i];
2891  if (i == XT_REG_IDX_PS) {
2892  continue; /* restore mapped reg number of PS depends on NDEBUGLEVEL */
2893  } else if (i == XT_REG_IDX_DEBUGCAUSE) {
2894  /*FIXME: restoring DEBUGCAUSE causes exception when executing corresponding
2895  * instruction in DIR */
2896  LOG_DEBUG("Skip restoring register %s: 0x%8.8" PRIx32 " -> 0x%8.8" PRIx32,
2898  buf_get_u32(reg->value, 0, 32),
2899  buf_get_u32(xtensa->algo_context_backup[i], 0, 32));
2901  xtensa->core_cache->reg_list[i].dirty = 0;
2902  xtensa->core_cache->reg_list[i].valid = 0;
2903  } else if (memcmp(xtensa->algo_context_backup[i], reg->value, reg->size / 8)) {
2904  if (reg->size <= 32) {
2905  LOG_DEBUG("restoring register %s: 0x%8.8" PRIx32 " -> 0x%8.8" PRIx32,
2907  buf_get_u32(reg->value, 0, reg->size),
2909  } else if (reg->size <= 64) {
2910  LOG_DEBUG("restoring register %s: 0x%8.8" PRIx64 " -> 0x%8.8" PRIx64,
2912  buf_get_u64(reg->value, 0, reg->size),
2914  } else {
2915  LOG_DEBUG("restoring register %s %u-bits", xtensa->core_cache->reg_list[i].name, reg->size);
2916  }
2918  xtensa->core_cache->reg_list[i].dirty = 1;
2919  xtensa->core_cache->reg_list[i].valid = 1;
2920  }
2921  }
2922  target->debug_reason = algorithm_info->ctx_debug_reason;
2923  if (xtensa->core_config->core_type == XT_LX)
2924  xtensa_reg_set(target, xtensa->eps_dbglevel_idx, algorithm_info->ctx_ps);
2925 
2927  if (retval != ERROR_OK)
2928  LOG_ERROR("Failed to write dirty regs (%d)!", retval);
2929 
2930  return retval;
2931 }
2932 
2934  int num_mem_params, struct mem_param *mem_params,
2935  int num_reg_params, struct reg_param *reg_params,
2936  target_addr_t entry_point, target_addr_t exit_point,
2937  unsigned int timeout_ms, void *arch_info)
2938 {
2939  int retval = xtensa_start_algorithm(target,
2940  num_mem_params, mem_params,
2941  num_reg_params, reg_params,
2942  entry_point, exit_point,
2943  arch_info);
2944 
2945  if (retval == ERROR_OK) {
2946  retval = xtensa_wait_algorithm(target,
2947  num_mem_params, mem_params,
2948  num_reg_params, reg_params,
2949  exit_point, timeout_ms,
2950  arch_info);
2951  }
2952 
2953  return retval;
2954 }
2955 
2957 {
2958  struct xtensa *xtensa = target_to_xtensa(target);
2959  struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
2960  unsigned int last_dbreg_num = 0;
2961 
2963  LOG_TARGET_WARNING(target, "Register count MISMATCH: %d core regs, %d extended regs; %d expected",
2965 
2966  struct reg_cache *reg_cache = calloc(1, sizeof(struct reg_cache));
2967 
2968  if (!reg_cache) {
2969  LOG_ERROR("Failed to alloc reg cache!");
2970  return ERROR_FAIL;
2971  }
2972  reg_cache->name = "Xtensa registers";
2973  reg_cache->next = NULL;
2974  /* Init reglist */
2975  unsigned int reg_list_size = XT_NUM_REGS + xtensa->num_optregs;
2976  struct reg *reg_list = calloc(reg_list_size, sizeof(struct reg));
2977  if (!reg_list) {
2978  LOG_ERROR("Failed to alloc reg list!");
2979  goto fail;
2980  }
2981  xtensa->dbregs_num = 0;
2982  unsigned int didx = 0;
2983  for (unsigned int whichlist = 0; whichlist < 2; whichlist++) {
2984  struct xtensa_reg_desc *rlist = (whichlist == 0) ? xtensa_regs : xtensa->optregs;
2985  unsigned int listsize = (whichlist == 0) ? XT_NUM_REGS : xtensa->num_optregs;
2986  for (unsigned int i = 0; i < listsize; i++, didx++) {
2987  reg_list[didx].exist = rlist[i].exist;
2988  reg_list[didx].name = rlist[i].name;
2989  reg_list[didx].size = 32;
2990  reg_list[didx].value = calloc(1, 4 /*XT_REG_LEN*/); /* make Clang Static Analyzer happy */
2991  if (!reg_list[didx].value) {
2992  LOG_ERROR("Failed to alloc reg list value!");
2993  goto fail;
2994  }
2995  reg_list[didx].dirty = false;
2996  reg_list[didx].valid = false;
2997  reg_list[didx].type = &xtensa_reg_type;
2998  reg_list[didx].arch_info = xtensa;
2999  if (rlist[i].exist && (rlist[i].dbreg_num > last_dbreg_num))
3000  last_dbreg_num = rlist[i].dbreg_num;
3001 
3002  if (xtensa_extra_debug_log) {
3004  "POPULATE %-16s list %d exist %d, idx %d, type %d, dbreg_num 0x%04x",
3005  reg_list[didx].name,
3006  whichlist,
3007  reg_list[didx].exist,
3008  didx,
3009  rlist[i].type,
3010  rlist[i].dbreg_num);
3011  }
3012  }
3013  }
3014 
3015  xtensa->dbregs_num = last_dbreg_num + 1;
3016  reg_cache->reg_list = reg_list;
3017  reg_cache->num_regs = reg_list_size;
3018 
3019  LOG_TARGET_DEBUG(target, "xtensa->total_regs_num %d reg_list_size %d xtensa->dbregs_num %d",
3020  xtensa->total_regs_num, reg_list_size, xtensa->dbregs_num);
3021 
3022  /* Construct empty-register list for handling unknown register requests */
3023  xtensa->empty_regs = calloc(xtensa->dbregs_num, sizeof(struct reg));
3024  if (!xtensa->empty_regs) {
3025  LOG_TARGET_ERROR(target, "Out of memory");
3026  goto fail;
3027  }
3028  for (unsigned int i = 0; i < xtensa->dbregs_num; i++) {
3029  xtensa->empty_regs[i].name = calloc(8, sizeof(char));
3030  if (!xtensa->empty_regs[i].name) {
3031  LOG_TARGET_ERROR(target, "Out of memory");
3032  goto fail;
3033  }
3034  sprintf((char *)xtensa->empty_regs[i].name, "?0x%04x", i & 0x0000FFFF);
3035  xtensa->empty_regs[i].size = 32;
3037  xtensa->empty_regs[i].value = calloc(1, 4 /*XT_REG_LEN*/); /* make Clang Static Analyzer happy */
3038  if (!xtensa->empty_regs[i].value) {
3039  LOG_ERROR("Failed to alloc empty reg list value!");
3040  goto fail;
3041  }
3043  }
3044 
3045  /* Construct contiguous register list from contiguous descriptor list */
3047  xtensa->contiguous_regs_list = calloc(xtensa->total_regs_num, sizeof(struct reg *));
3048  if (!xtensa->contiguous_regs_list) {
3049  LOG_TARGET_ERROR(target, "Out of memory");
3050  goto fail;
3051  }
3052  for (unsigned int i = 0; i < xtensa->total_regs_num; i++) {
3053  unsigned int j;
3054  for (j = 0; j < reg_cache->num_regs; j++) {
3055  if (!strcmp(reg_cache->reg_list[j].name, xtensa->contiguous_regs_desc[i]->name)) {
3056  /* Register number field is not filled above.
3057  Here we are assigning the corresponding index from the contiguous reg list.
3058  These indexes are in the same order with gdb g-packet request/response.
3059  Some more changes may be required for sparse reg lists.
3060  */
3061  reg_cache->reg_list[j].number = i;
3064  "POPULATE contiguous regs list: %-16s, dbreg_num 0x%04x",
3067  break;
3068  }
3069  }
3070  if (j == reg_cache->num_regs)
3071  LOG_TARGET_WARNING(target, "contiguous register %s not found",
3073  }
3074  }
3075 
3076  xtensa->algo_context_backup = calloc(reg_cache->num_regs, sizeof(void *));
3077  if (!xtensa->algo_context_backup) {
3078  LOG_ERROR("Failed to alloc mem for algorithm context backup!");
3079  goto fail;
3080  }
3081  for (unsigned int i = 0; i < reg_cache->num_regs; i++) {
3082  struct reg *reg = &reg_cache->reg_list[i];
3083  xtensa->algo_context_backup[i] = calloc(1, reg->size / 8);
3084  if (!xtensa->algo_context_backup[i]) {
3085  LOG_ERROR("Failed to alloc mem for algorithm context!");
3086  goto fail;
3087  }
3088  }
3090  if (cache_p)
3091  *cache_p = reg_cache;
3092  return ERROR_OK;
3093 
3094 fail:
3095  if (reg_list) {
3096  for (unsigned int i = 0; i < reg_list_size; i++)
3097  free(reg_list[i].value);
3098  free(reg_list);
3099  }
3100  if (xtensa->empty_regs) {
3101  for (unsigned int i = 0; i < xtensa->dbregs_num; i++) {
3102  free((void *)xtensa->empty_regs[i].name);
3103  free(xtensa->empty_regs[i].value);
3104  }
3105  free(xtensa->empty_regs);
3106  }
3107  if (xtensa->algo_context_backup) {
3108  for (unsigned int i = 0; i < reg_cache->num_regs; i++)
3109  free(xtensa->algo_context_backup[i]);
3110  free(xtensa->algo_context_backup);
3111  }
3112  free(reg_cache);
3113 
3114  return ERROR_FAIL;
3115 }
3116 
3117 static int32_t xtensa_gdbqc_parse_exec_tie_ops(struct target *target, char *opstr)
3118 {
3119  struct xtensa *xtensa = target_to_xtensa(target);
3121  /* Process op[] list */
3122  while (opstr && (*opstr == ':')) {
3123  uint8_t ops[32];
3124  unsigned int oplen = strtoul(opstr + 1, &opstr, 16);
3125  if (oplen > 32) {
3126  LOG_TARGET_ERROR(target, "TIE access instruction too long (%d)\n", oplen);
3127  break;
3128  }
3129  unsigned int i = 0;
3130  while ((i < oplen) && opstr && (*opstr == ':'))
3131  ops[i++] = strtoul(opstr + 1, &opstr, 16);
3132  if (i != oplen) {
3133  LOG_TARGET_ERROR(target, "TIE access instruction malformed (%d)\n", i);
3134  break;
3135  }
3136 
3137  char insn_buf[128];
3138  sprintf(insn_buf, "Exec %d-byte TIE sequence: ", oplen);
3139  for (i = 0; i < oplen; i++)
3140  sprintf(insn_buf + strlen(insn_buf), "%02x:", ops[i]);
3141  LOG_TARGET_DEBUG(target, "%s", insn_buf);
3142  xtensa_queue_exec_ins_wide(xtensa, ops, oplen); /* Handles endian-swap */
3143  status = ERROR_OK;
3144  }
3145  return status;
3146 }
3147 
3148 static int xtensa_gdbqc_qxtreg(struct target *target, const char *packet, char **response_p)
3149 {
3150  struct xtensa *xtensa = target_to_xtensa(target);
3151  bool iswrite = (packet[0] == 'Q');
3152  enum xtensa_qerr_e error;
3153 
3154  /* Read/write TIE register. Requires spill location.
3155  * qxtreg<num>:<len>:<oplen>:<op[0]>:<...>[:<oplen>:<op[0]>:<...>]
3156  * Qxtreg<num>:<len>:<oplen>:<op[0]>:<...>[:<oplen>:<op[0]>:<...>]=<value>
3157  */
3158  if (!(xtensa->spill_buf)) {
3159  LOG_ERROR("Spill location not specified. Try 'target remote <host>:3333 &spill_location0'");
3160  error = XT_QERR_FAIL;
3161  goto xtensa_gdbqc_qxtreg_fail;
3162  }
3163 
3164  char *delim;
3165  uint32_t regnum = strtoul(packet + 6, &delim, 16);
3166  if (*delim != ':') {
3167  LOG_ERROR("Malformed qxtreg packet");
3168  error = XT_QERR_INVAL;
3169  goto xtensa_gdbqc_qxtreg_fail;
3170  }
3171  uint32_t reglen = strtoul(delim + 1, &delim, 16);
3172  if (*delim != ':') {
3173  LOG_ERROR("Malformed qxtreg packet");
3174  error = XT_QERR_INVAL;
3175  goto xtensa_gdbqc_qxtreg_fail;
3176  }
3177  uint8_t regbuf[XT_QUERYPKT_RESP_MAX];
3178  memset(regbuf, 0, XT_QUERYPKT_RESP_MAX);
3179  LOG_DEBUG("TIE reg 0x%08" PRIx32 " %s (%d bytes)", regnum, iswrite ? "write" : "read", reglen);
3180  if (reglen * 2 + 1 > XT_QUERYPKT_RESP_MAX) {
3181  LOG_ERROR("TIE register too large");
3182  error = XT_QERR_MEM;
3183  goto xtensa_gdbqc_qxtreg_fail;
3184  }
3185 
3186  /* (1) Save spill memory, (1.5) [if write then store value to spill location],
3187  * (2) read old a4, (3) write spill address to a4.
3188  * NOTE: ensure a4 is restored properly by all error handling logic
3189  */
3190  unsigned int memop_size = (xtensa->spill_loc & 3) ? 1 : 4;
3191  int status = xtensa_read_memory(target, xtensa->spill_loc, memop_size,
3192  xtensa->spill_bytes / memop_size, xtensa->spill_buf);
3193  if (status != ERROR_OK) {
3194  LOG_ERROR("Spill memory save");
3195  error = XT_QERR_MEM;
3196  goto xtensa_gdbqc_qxtreg_fail;
3197  }
3198  if (iswrite) {
3199  /* Extract value and store in spill memory */
3200  unsigned int b = 0;
3201  char *valbuf = strchr(delim, '=');
3202  if (!(valbuf && (*valbuf == '='))) {
3203  LOG_ERROR("Malformed Qxtreg packet");
3204  error = XT_QERR_INVAL;
3205  goto xtensa_gdbqc_qxtreg_fail;
3206  }
3207  valbuf++;
3208  while (*valbuf && *(valbuf + 1)) {
3209  char bytestr[3] = { 0, 0, 0 };
3210  strncpy(bytestr, valbuf, 2);
3211  regbuf[b++] = strtoul(bytestr, NULL, 16);
3212  valbuf += 2;
3213  }
3214  if (b != reglen) {
3215  LOG_ERROR("Malformed Qxtreg packet");
3216  error = XT_QERR_INVAL;
3217  goto xtensa_gdbqc_qxtreg_fail;
3218  }
3220  reglen / memop_size, regbuf);
3221  if (status != ERROR_OK) {
3222  LOG_ERROR("TIE value store");
3223  error = XT_QERR_MEM;
3224  goto xtensa_gdbqc_qxtreg_fail;
3225  }
3226  }
3230 
3231  int32_t tieop_status = xtensa_gdbqc_parse_exec_tie_ops(target, delim);
3232 
3233  /* Restore a4 but not yet spill memory. Execute it all... */
3237  if (status != ERROR_OK) {
3238  LOG_TARGET_ERROR(target, "TIE queue execute: %d\n", status);
3239  tieop_status = status;
3240  }
3242  if (status != ERROR_OK) {
3243  LOG_TARGET_ERROR(target, "TIE instr execute: %d\n", status);
3244  tieop_status = status;
3245  }
3246 
3247  if (tieop_status == ERROR_OK) {
3248  if (iswrite) {
3249  /* TIE write succeeded; send OK */
3250  strcpy(*response_p, "OK");
3251  } else {
3252  /* TIE read succeeded; copy result from spill memory */
3253  status = xtensa_read_memory(target, xtensa->spill_loc, memop_size, reglen, regbuf);
3254  if (status != ERROR_OK) {
3255  LOG_TARGET_ERROR(target, "TIE result read");
3256  tieop_status = status;
3257  }
3258  unsigned int i;
3259  for (i = 0; i < reglen; i++)
3260  sprintf(*response_p + 2 * i, "%02x", regbuf[i]);
3261  *(*response_p + 2 * i) = '\0';
3262  LOG_TARGET_DEBUG(target, "TIE response: %s", *response_p);
3263  }
3264  }
3265 
3266  /* Restore spill memory first, then report any previous errors */
3268  xtensa->spill_bytes / memop_size, xtensa->spill_buf);
3269  if (status != ERROR_OK) {
3270  LOG_ERROR("Spill memory restore");
3271  error = XT_QERR_MEM;
3272  goto xtensa_gdbqc_qxtreg_fail;
3273  }
3274  if (tieop_status != ERROR_OK) {
3275  LOG_ERROR("TIE execution");
3276  error = XT_QERR_FAIL;
3277  goto xtensa_gdbqc_qxtreg_fail;
3278  }
3279  return ERROR_OK;
3280 
3281 xtensa_gdbqc_qxtreg_fail:
3282  strcpy(*response_p, xt_qerr[error].chrval);
3283  return xt_qerr[error].intval;
3284 }
3285 
3286 int xtensa_gdb_query_custom(struct target *target, const char *packet, char **response_p)
3287 {
3288  struct xtensa *xtensa = target_to_xtensa(target);
3289  enum xtensa_qerr_e error;
3290  if (!packet || !response_p) {
3291  LOG_TARGET_ERROR(target, "invalid parameter: packet %p response_p %p", packet, response_p);
3292  return ERROR_FAIL;
3293  }
3294 
3295  *response_p = xtensa->qpkt_resp;
3296  if (strncmp(packet, "qxtn", 4) == 0) {
3297  strcpy(*response_p, "OpenOCD");
3298  return ERROR_OK;
3299  } else if (strncasecmp(packet, "qxtgdbversion=", 14) == 0) {
3300  return ERROR_OK;
3301  } else if ((strncmp(packet, "Qxtsis=", 7) == 0) || (strncmp(packet, "Qxtsds=", 7) == 0)) {
3302  /* Confirm host cache params match core .cfg file */
3303  struct xtensa_cache_config *cachep = (packet[4] == 'i') ?
3305  unsigned int line_size = 0, size = 0, way_count = 0;
3306  sscanf(&packet[7], "%x,%x,%x", &line_size, &size, &way_count);
3307  if ((cachep->line_size != line_size) ||
3308  (cachep->size != size) ||
3309  (cachep->way_count != way_count)) {
3310  LOG_TARGET_WARNING(target, "%cCache mismatch; check xtensa-core-XXX.cfg file",
3311  cachep == &xtensa->core_config->icache ? 'I' : 'D');
3312  }
3313  strcpy(*response_p, "OK");
3314  return ERROR_OK;
3315  } else if ((strncmp(packet, "Qxtiram=", 8) == 0) || (strncmp(packet, "Qxtirom=", 8) == 0)) {
3316  /* Confirm host IRAM/IROM params match core .cfg file */
3317  struct xtensa_local_mem_config *memp = (packet[5] == 'a') ?
3319  unsigned int base = 0, size = 0, i;
3320  char *pkt = (char *)&packet[7];
3321  do {
3322  pkt++;
3323  size = strtoul(pkt, &pkt, 16);
3324  pkt++;
3325  base = strtoul(pkt, &pkt, 16);
3326  LOG_TARGET_DEBUG(target, "memcheck: %dB @ 0x%08x", size, base);
3327  for (i = 0; i < memp->count; i++) {
3328  if ((memp->regions[i].base == base) && (memp->regions[i].size == size))
3329  break;
3330  }
3331  if (i == memp->count) {
3332  LOG_TARGET_WARNING(target, "%s mismatch; check xtensa-core-XXX.cfg file",
3333  memp == &xtensa->core_config->iram ? "IRAM" : "IROM");
3334  break;
3335  }
3336  for (i = 0; i < 11; i++) {
3337  pkt++;
3338  strtoul(pkt, &pkt, 16);
3339  }
3340  } while (pkt && (pkt[0] == ','));
3341  strcpy(*response_p, "OK");
3342  return ERROR_OK;
3343  } else if (strncmp(packet, "Qxtexcmlvl=", 11) == 0) {
3344  /* Confirm host EXCM_LEVEL matches core .cfg file */
3345  unsigned int excm_level = strtoul(&packet[11], NULL, 0);
3347  (excm_level != xtensa->core_config->high_irq.excm_level))
3348  LOG_TARGET_WARNING(target, "EXCM_LEVEL mismatch; check xtensa-core-XXX.cfg file");
3349  strcpy(*response_p, "OK");
3350  return ERROR_OK;
3351  } else if ((strncmp(packet, "Qxtl2cs=", 8) == 0) ||
3352  (strncmp(packet, "Qxtl2ca=", 8) == 0) ||
3353  (strncmp(packet, "Qxtdensity=", 11) == 0)) {
3354  strcpy(*response_p, "OK");
3355  return ERROR_OK;
3356  } else if (strncmp(packet, "Qxtspill=", 9) == 0) {
3357  char *delim;
3358  uint32_t spill_loc = strtoul(packet + 9, &delim, 16);
3359  if (*delim != ':') {
3360  LOG_ERROR("Malformed Qxtspill packet");
3361  error = XT_QERR_INVAL;
3362  goto xtensa_gdb_query_custom_fail;
3363  }
3364  xtensa->spill_loc = spill_loc;
3365  xtensa->spill_bytes = strtoul(delim + 1, NULL, 16);
3366  if (xtensa->spill_buf)
3367  free(xtensa->spill_buf);
3368  xtensa->spill_buf = calloc(1, xtensa->spill_bytes);
3369  if (!xtensa->spill_buf) {
3370  LOG_ERROR("Spill buf alloc");
3371  error = XT_QERR_MEM;
3372  goto xtensa_gdb_query_custom_fail;
3373  }
3374  LOG_TARGET_DEBUG(target, "Set spill 0x%08" PRIx32 " (%d)", xtensa->spill_loc, xtensa->spill_bytes);
3375  strcpy(*response_p, "OK");
3376  return ERROR_OK;
3377  } else if (strncasecmp(packet, "qxtreg", 6) == 0) {
3378  return xtensa_gdbqc_qxtreg(target, packet, response_p);
3379  } else if ((strncmp(packet, "qTStatus", 8) == 0) ||
3380  (strncmp(packet, "qxtftie", 7) == 0) ||
3381  (strncmp(packet, "qxtstie", 7) == 0)) {
3382  /* Return empty string to indicate trace, TIE wire debug are unsupported */
3383  strcpy(*response_p, "");
3384  return ERROR_OK;
3385  }
3386 
3387  /* Warn for all other queries, but do not return errors */
3388  LOG_TARGET_WARNING(target, "Unknown target-specific query packet: %s", packet);
3389  strcpy(*response_p, "");
3390  return ERROR_OK;
3391 
3392 xtensa_gdb_query_custom_fail:
3393  strcpy(*response_p, xt_qerr[error].chrval);
3394  return xt_qerr[error].intval;
3395 }
3396 
3398  const struct xtensa_debug_module_config *dm_cfg)
3399 {
3400  target->arch_info = xtensa;
3402  xtensa->target = target;
3404 
3405  xtensa->core_config = calloc(1, sizeof(struct xtensa_config));
3406  if (!xtensa->core_config) {
3407  LOG_ERROR("Xtensa configuration alloc failed\n");
3408  return ERROR_FAIL;
3409  }
3410 
3411  /* Default cache settings are disabled with 1 way */
3414 
3415  /* chrval: AR3/AR4 register names will change with window mapping.
3416  * intval: tracks whether scratch register was set through gdb P packet.
3417  */
3418  for (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++) {
3419  xtensa->scratch_ars[s].chrval = calloc(8, sizeof(char));
3420  if (!xtensa->scratch_ars[s].chrval) {
3421  for (enum xtensa_ar_scratch_set_e f = 0; f < s; f++)
3422  free(xtensa->scratch_ars[f].chrval);
3423  free(xtensa->core_config);
3424  LOG_ERROR("Xtensa scratch AR alloc failed\n");
3425  return ERROR_FAIL;
3426  }
3427  xtensa->scratch_ars[s].intval = false;
3428  sprintf(xtensa->scratch_ars[s].chrval, "%s%d",
3429  ((s == XT_AR_SCRATCH_A3) || (s == XT_AR_SCRATCH_A4)) ? "a" : "ar",
3430  ((s == XT_AR_SCRATCH_A3) || (s == XT_AR_SCRATCH_AR3)) ? 3 : 4);
3431  }
3432 
3433  return xtensa_dm_init(&xtensa->dbg_mod, dm_cfg);
3434 }
3435 
3437 {
3439 }
3440 
3441 int xtensa_target_init(struct command_context *cmd_ctx, struct target *target)
3442 {
3443  struct xtensa *xtensa = target_to_xtensa(target);
3444 
3446  xtensa->hw_brps = calloc(XT_HW_IBREAK_MAX_NUM, sizeof(struct breakpoint *));
3447  if (!xtensa->hw_brps) {
3448  LOG_ERROR("Failed to alloc memory for HW breakpoints!");
3449  return ERROR_FAIL;
3450  }
3451  xtensa->hw_wps = calloc(XT_HW_DBREAK_MAX_NUM, sizeof(struct watchpoint *));
3452  if (!xtensa->hw_wps) {
3453  free(xtensa->hw_brps);
3454  LOG_ERROR("Failed to alloc memory for HW watchpoints!");
3455  return ERROR_FAIL;
3456  }
3457  xtensa->sw_brps = calloc(XT_SW_BREAKPOINTS_MAX_NUM, sizeof(struct xtensa_sw_breakpoint));
3458  if (!xtensa->sw_brps) {
3459  free(xtensa->hw_brps);
3460  free(xtensa->hw_wps);
3461  LOG_ERROR("Failed to alloc memory for SW breakpoints!");
3462  return ERROR_FAIL;
3463  }
3464 
3465  xtensa->spill_loc = 0xffffffff;
3466  xtensa->spill_bytes = 0;
3467  xtensa->spill_buf = NULL;
3468  xtensa->probe_lsddr32p = -1; /* Probe for fast load/store operations */
3469 
3471 }
3472 
3474 {
3475  struct xtensa *xtensa = target_to_xtensa(target);
3476  struct reg_cache *cache = xtensa->core_cache;
3477 
3478  if (cache) {
3480  for (unsigned int i = 0; i < cache->num_regs; i++) {
3481  free(xtensa->algo_context_backup[i]);
3482  free(cache->reg_list[i].value);
3483  }
3484  free(xtensa->algo_context_backup);
3485  free(cache->reg_list);
3486  free(cache);
3487  }
3488  xtensa->core_cache = NULL;
3490 
3491  if (xtensa->empty_regs) {
3492  for (unsigned int i = 0; i < xtensa->dbregs_num; i++) {
3493  free((void *)xtensa->empty_regs[i].name);
3494  free(xtensa->empty_regs[i].value);
3495  }
3496  free(xtensa->empty_regs);
3497  }
3498  xtensa->empty_regs = NULL;
3499  if (xtensa->optregs) {
3500  for (unsigned int i = 0; i < xtensa->num_optregs; i++)
3501  free((void *)xtensa->optregs[i].name);
3502  free(xtensa->optregs);
3503  }
3504  xtensa->optregs = NULL;
3509 }
3510 
3512 {
3513  struct xtensa *xtensa = target_to_xtensa(target);
3514 
3515  LOG_DEBUG("start");
3516 
3517  if (target_was_examined(target)) {
3519  if (ret != ERROR_OK) {
3520  LOG_ERROR("Failed to queue OCDDCR_ENABLEOCD clear operation!");
3521  return;
3522  }
3525  if (ret != ERROR_OK) {
3526  LOG_ERROR("Failed to clear OCDDCR_ENABLEOCD!");
3527  return;
3528  }
3530  }
3532  free(xtensa->hw_brps);
3533  free(xtensa->hw_wps);
3534  free(xtensa->sw_brps);
3535  if (xtensa->spill_buf) {
3536  free(xtensa->spill_buf);
3537  xtensa->spill_buf = NULL;
3538  }
3539  for (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++)
3540  free(xtensa->scratch_ars[s].chrval);
3541  free(xtensa->core_config);
3542 }
3543 
3544 const char *xtensa_get_gdb_arch(const struct target *target)
3545 {
3546  return "xtensa";
3547 }
3548 
3549 /* exe <ascii-encoded hexadecimal instruction bytes> */
3550 static COMMAND_HELPER(xtensa_cmd_exe_do, struct target *target)
3551 {
3552  struct xtensa *xtensa = target_to_xtensa(target);
3553 
3554  if (CMD_ARGC != 1)
3556 
3557  /* Process ascii-encoded hex byte string */
3558  const char *parm = CMD_ARGV[0];
3559  unsigned int parm_len = strlen(parm);
3560  if ((parm_len >= 64) || (parm_len & 1)) {
3561  command_print(CMD, "Invalid parameter length (%d): must be even, < 64 characters", parm_len);
3563  }
3564 
3565  uint8_t ops[32];
3566  memset(ops, 0, 32);
3567  unsigned int oplen = parm_len / 2;
3568  char encoded_byte[3] = { 0, 0, 0 };
3569  for (unsigned int i = 0; i < oplen; i++) {
3570  encoded_byte[0] = *parm++;
3571  encoded_byte[1] = *parm++;
3572  ops[i] = strtoul(encoded_byte, NULL, 16);
3573  }
3574 
3575  /* GDB must handle state save/restore.
3576  * Flush reg cache in case spill location is in an AR
3577  * Update CPENABLE only for this execution; later restore cached copy
3578  * Keep a copy of exccause in case executed code triggers an exception
3579  */
3581  if (status != ERROR_OK) {
3582  command_print(CMD, "%s: Failed to write back register cache.", target_name(target));
3583  return ERROR_FAIL;
3584  }
3594 
3595  /* Queue instruction list and execute everything */
3596  LOG_TARGET_DEBUG(target, "execute stub: %s", CMD_ARGV[0]);
3597  xtensa_queue_exec_ins_wide(xtensa, ops, oplen); /* Handles endian-swap */
3599  if (status != ERROR_OK) {
3600  command_print(CMD, "exec: queue error %d", status);
3601  } else {
3603  if (status != ERROR_OK)
3604  command_print(CMD, "exec: status error %d", status);
3605  }
3606 
3607  /* Reread register cache and restore saved regs after instruction execution */
3609  command_print(CMD, "post-exec: register fetch error");
3610  if (status != ERROR_OK) {
3611  command_print(CMD, "post-exec: EXCCAUSE 0x%02" PRIx32,
3613  }
3616  return status;
3617 }
3618 
3619 COMMAND_HANDLER(xtensa_cmd_exe)
3620 {
3621  return CALL_COMMAND_HANDLER(xtensa_cmd_exe_do, get_current_target(CMD_CTX));
3622 }
3623 
3624 /* xtdef <name> */
3625 COMMAND_HELPER(xtensa_cmd_xtdef_do, struct xtensa *xtensa)
3626 {
3627  if (CMD_ARGC != 1)
3629 
3630  const char *core_name = CMD_ARGV[0];
3631  if (strcasecmp(core_name, "LX") == 0) {
3633  } else if (strcasecmp(core_name, "NX") == 0) {
3635  } else {
3636  command_print(CMD, "xtdef [LX|NX]\n");
3638  }
3639  return ERROR_OK;
3640 }
3641 
3642 COMMAND_HANDLER(xtensa_cmd_xtdef)
3643 {
3644  return CALL_COMMAND_HANDLER(xtensa_cmd_xtdef_do,
3646 }
3647 
3648 static inline bool xtensa_cmd_xtopt_legal_val(char *opt, int val, int min, int max)
3649 {
3650  if ((val < min) || (val > max)) {
3651  LOG_ERROR("xtopt %s (%d) out of range [%d..%d]\n", opt, val, min, max);
3652  return false;
3653  }
3654  return true;
3655 }
3656 
3657 /* xtopt <name> <value> */
3658 COMMAND_HELPER(xtensa_cmd_xtopt_do, struct xtensa *xtensa)
3659 {
3660  if (CMD_ARGC != 2)
3662 
3663  const char *opt_name = CMD_ARGV[0];
3664  int opt_val = strtol(CMD_ARGV[1], NULL, 0);
3665  if (strcasecmp(opt_name, "arnum") == 0) {
3666  if (!xtensa_cmd_xtopt_legal_val("arnum", opt_val, 0, 64))
3668  xtensa->core_config->aregs_num = opt_val;
3669  } else if (strcasecmp(opt_name, "windowed") == 0) {
3670  if (!xtensa_cmd_xtopt_legal_val("windowed", opt_val, 0, 1))
3672  xtensa->core_config->windowed = opt_val;
3673  } else if (strcasecmp(opt_name, "cpenable") == 0) {
3674  if (!xtensa_cmd_xtopt_legal_val("cpenable", opt_val, 0, 1))
3676  xtensa->core_config->coproc = opt_val;
3677  } else if (strcasecmp(opt_name, "exceptions") == 0) {
3678  if (!xtensa_cmd_xtopt_legal_val("exceptions", opt_val, 0, 1))
3680  xtensa->core_config->exceptions = opt_val;
3681  } else if (strcasecmp(opt_name, "intnum") == 0) {
3682  if (!xtensa_cmd_xtopt_legal_val("intnum", opt_val, 0, 32))
3684  xtensa->core_config->irq.enabled = (opt_val > 0);
3685  xtensa->core_config->irq.irq_num = opt_val;
3686  } else if (strcasecmp(opt_name, "hipriints") == 0) {
3687  if (!xtensa_cmd_xtopt_legal_val("hipriints", opt_val, 0, 1))
3689  xtensa->core_config->high_irq.enabled = opt_val;
3690  } else if (strcasecmp(opt_name, "excmlevel") == 0) {
3691  if (!xtensa_cmd_xtopt_legal_val("excmlevel", opt_val, 1, 6))
3694  command_print(CMD, "xtopt excmlevel requires hipriints\n");
3696  }
3697  xtensa->core_config->high_irq.excm_level = opt_val;
3698  } else if (strcasecmp(opt_name, "intlevels") == 0) {
3699  if (xtensa->core_config->core_type == XT_LX) {
3700  if (!xtensa_cmd_xtopt_legal_val("intlevels", opt_val, 2, 6))
3702  } else {
3703  if (!xtensa_cmd_xtopt_legal_val("intlevels", opt_val, 1, 255))
3705  }
3707  command_print(CMD, "xtopt intlevels requires hipriints\n");
3709  }
3710  xtensa->core_config->high_irq.level_num = opt_val;
3711  } else if (strcasecmp(opt_name, "debuglevel") == 0) {
3712  if (xtensa->core_config->core_type == XT_LX) {
3713  if (!xtensa_cmd_xtopt_legal_val("debuglevel", opt_val, 2, 6))
3715  } else {
3716  if (!xtensa_cmd_xtopt_legal_val("debuglevel", opt_val, 0, 0))
3718  }
3720  xtensa->core_config->debug.irq_level = opt_val;
3721  } else if (strcasecmp(opt_name, "ibreaknum") == 0) {
3722  if (!xtensa_cmd_xtopt_legal_val("ibreaknum", opt_val, 0, 2))
3724  xtensa->core_config->debug.ibreaks_num = opt_val;
3725  } else if (strcasecmp(opt_name, "dbreaknum") == 0) {
3726  if (!xtensa_cmd_xtopt_legal_val("dbreaknum", opt_val, 0, 2))
3728  xtensa->core_config->debug.dbreaks_num = opt_val;
3729  } else if (strcasecmp(opt_name, "tracemem") == 0) {
3730  if (!xtensa_cmd_xtopt_legal_val("tracemem", opt_val, 0, 256 * 1024))
3732  xtensa->core_config->trace.mem_sz = opt_val;
3733  xtensa->core_config->trace.enabled = (opt_val > 0);
3734  } else if (strcasecmp(opt_name, "tracememrev") == 0) {
3735  if (!xtensa_cmd_xtopt_legal_val("tracememrev", opt_val, 0, 1))
3738  } else if (strcasecmp(opt_name, "perfcount") == 0) {
3739  if (!xtensa_cmd_xtopt_legal_val("perfcount", opt_val, 0, 8))
3741  xtensa->core_config->debug.perfcount_num = opt_val;
3742  } else {
3743  LOG_WARNING("Unknown xtensa command ignored: \"xtopt %s %s\"", CMD_ARGV[0], CMD_ARGV[1]);
3744  return ERROR_OK;
3745  }
3746 
3747  return ERROR_OK;
3748 }
3749 
3750 COMMAND_HANDLER(xtensa_cmd_xtopt)
3751 {
3752  return CALL_COMMAND_HANDLER(xtensa_cmd_xtopt_do,
3754 }
3755 
3756 /* xtmem <type> [parameters] */
3757 COMMAND_HELPER(xtensa_cmd_xtmem_do, struct xtensa *xtensa)
3758 {
3759  struct xtensa_cache_config *cachep = NULL;
3760  struct xtensa_local_mem_config *memp = NULL;
3761  int mem_access = 0;
3762  bool is_dcache = false;
3763 
3764  if (CMD_ARGC == 0)
3766 
3767  const char *mem_name = CMD_ARGV[0];
3768  if (strcasecmp(mem_name, "icache") == 0) {
3769  cachep = &xtensa->core_config->icache;
3770  } else if (strcasecmp(mem_name, "dcache") == 0) {
3771  cachep = &xtensa->core_config->dcache;
3772  is_dcache = true;
3773  } else if (strcasecmp(mem_name, "l2cache") == 0) {
3774  /* TODO: support L2 cache */
3775  } else if (strcasecmp(mem_name, "l2addr") == 0) {
3776  /* TODO: support L2 cache */
3777  } else if (strcasecmp(mem_name, "iram") == 0) {
3778  memp = &xtensa->core_config->iram;
3779  mem_access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE;
3780  } else if (strcasecmp(mem_name, "dram") == 0) {
3781  memp = &xtensa->core_config->dram;
3782  mem_access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE;
3783  } else if (strcasecmp(mem_name, "sram") == 0) {
3784  memp = &xtensa->core_config->sram;
3785  mem_access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE;
3786  } else if (strcasecmp(mem_name, "irom") == 0) {
3787  memp = &xtensa->core_config->irom;
3788  mem_access = XT_MEM_ACCESS_READ;
3789  } else if (strcasecmp(mem_name, "drom") == 0) {
3790  memp = &xtensa->core_config->drom;
3791  mem_access = XT_MEM_ACCESS_READ;
3792  } else if (strcasecmp(mem_name, "srom") == 0) {
3793  memp = &xtensa->core_config->srom;
3794  mem_access = XT_MEM_ACCESS_READ;
3795  } else {
3796  command_print(CMD, "xtmem types: <icache|dcache|l2cache|l2addr|iram|irom|dram|drom|sram|srom>\n");
3798  }
3799 
3800  if (cachep) {
3801  if (CMD_ARGC != 4 && CMD_ARGC != 5)
3803  cachep->line_size = strtoul(CMD_ARGV[1], NULL, 0);
3804  cachep->size = strtoul(CMD_ARGV[2], NULL, 0);
3805  cachep->way_count = strtoul(CMD_ARGV[3], NULL, 0);
3806  cachep->writeback = ((CMD_ARGC == 5) && is_dcache) ?
3807  strtoul(CMD_ARGV[4], NULL, 0) : 0;
3808  } else if (memp) {
3809  if (CMD_ARGC != 3)
3811  struct xtensa_local_mem_region_config *memcfgp = &memp->regions[memp->count];
3812  memcfgp->base = strtoul(CMD_ARGV[1], NULL, 0);
3813  memcfgp->size = strtoul(CMD_ARGV[2], NULL, 0);
3814  memcfgp->access = mem_access;
3815  memp->count++;
3816  }
3817 
3818  return ERROR_OK;
3819 }
3820 
3821 COMMAND_HANDLER(xtensa_cmd_xtmem)
3822 {
3823  return CALL_COMMAND_HANDLER(xtensa_cmd_xtmem_do,
3825 }
3826 
3827 /* xtmpu <num FG seg> <min seg size> <lockable> <executeonly> */
3828 COMMAND_HELPER(xtensa_cmd_xtmpu_do, struct xtensa *xtensa)
3829 {
3830  if (CMD_ARGC != 4)
3832 
3833  unsigned int nfgseg = strtoul(CMD_ARGV[0], NULL, 0);
3834  unsigned int minsegsize = strtoul(CMD_ARGV[1], NULL, 0);
3835  unsigned int lockable = strtoul(CMD_ARGV[2], NULL, 0);
3836  unsigned int execonly = strtoul(CMD_ARGV[3], NULL, 0);
3837 
3838  if ((nfgseg > 32)) {
3839  command_print(CMD, "<nfgseg> must be within [0..32]\n");
3841  } else if (minsegsize & (minsegsize - 1)) {
3842  command_print(CMD, "<minsegsize> must be a power of 2 >= 32\n");
3844  } else if (lockable > 1) {
3845  command_print(CMD, "<lockable> must be 0 or 1\n");
3847  } else if (execonly > 1) {
3848  command_print(CMD, "<execonly> must be 0 or 1\n");
3850  }
3851 
3852  xtensa->core_config->mpu.enabled = true;
3853  xtensa->core_config->mpu.nfgseg = nfgseg;
3854  xtensa->core_config->mpu.minsegsize = minsegsize;
3855  xtensa->core_config->mpu.lockable = lockable;
3856  xtensa->core_config->mpu.execonly = execonly;
3857  return ERROR_OK;
3858 }
3859 
3860 COMMAND_HANDLER(xtensa_cmd_xtmpu)
3861 {
3862  return CALL_COMMAND_HANDLER(xtensa_cmd_xtmpu_do,
3864 }
3865 
3866 /* xtmmu <NIREFILLENTRIES> <NDREFILLENTRIES> <IVARWAY56> <DVARWAY56> */
3867 COMMAND_HELPER(xtensa_cmd_xtmmu_do, struct xtensa *xtensa)
3868 {
3869  if (CMD_ARGC != 2)
3871 
3872  unsigned int nirefillentries = strtoul(CMD_ARGV[0], NULL, 0);
3873  unsigned int ndrefillentries = strtoul(CMD_ARGV[1], NULL, 0);
3874  if ((nirefillentries != 16) && (nirefillentries != 32)) {
3875  command_print(CMD, "<nirefillentries> must be 16 or 32\n");
3877  } else if ((ndrefillentries != 16) && (ndrefillentries != 32)) {
3878  command_print(CMD, "<ndrefillentries> must be 16 or 32\n");
3880  }
3881 
3882  xtensa->core_config->mmu.enabled = true;
3883  xtensa->core_config->mmu.itlb_entries_count = nirefillentries;
3884  xtensa->core_config->mmu.dtlb_entries_count = ndrefillentries;
3885  return ERROR_OK;
3886 }
3887 
3888 COMMAND_HANDLER(xtensa_cmd_xtmmu)
3889 {
3890  return CALL_COMMAND_HANDLER(xtensa_cmd_xtmmu_do,
3892 }
3893 
3894 /* xtregs <numregs>
3895  * xtreg <regname> <regnum> */
3896 COMMAND_HELPER(xtensa_cmd_xtreg_do, struct xtensa *xtensa)
3897 {
3898  if (CMD_ARGC == 1) {
3899  int32_t numregs = strtoul(CMD_ARGV[0], NULL, 0);
3900  if ((numregs <= 0) || (numregs > UINT16_MAX)) {
3901  command_print(CMD, "xtreg <numregs>: Invalid 'numregs' (%d)", numregs);
3903  }
3904  if ((xtensa->genpkt_regs_num > 0) && (numregs < (int32_t)xtensa->genpkt_regs_num)) {
3905  command_print(CMD, "xtregs (%d) must be larger than numgenregs (%d) (if xtregfmt specified)",
3906  numregs, xtensa->genpkt_regs_num);
3908  }
3909  xtensa->total_regs_num = numregs;
3910  xtensa->core_regs_num = 0;
3911  xtensa->num_optregs = 0;
3912  /* Prevent memory leak in case xtregs is called twice */
3913  free(xtensa->optregs);
3916  /* A little more memory than required, but saves a second initialization pass */
3917  xtensa->optregs = calloc(xtensa->total_regs_num, sizeof(struct xtensa_reg_desc));
3918  if (!xtensa->optregs) {
3919  LOG_ERROR("Failed to allocate xtensa->optregs!");
3920  return ERROR_FAIL;
3921  }
3922  return ERROR_OK;
3923  } else if (CMD_ARGC != 2) {
3925  }
3926 
3927  /* "xtregfmt contiguous" must be specified prior to the first "xtreg" definition
3928  * if general register (g-packet) requests or contiguous register maps are supported */
3930  xtensa->contiguous_regs_desc = calloc(xtensa->total_regs_num, sizeof(struct xtensa_reg_desc *));
3931  if (!xtensa->contiguous_regs_desc) {
3932  LOG_ERROR("Failed to allocate xtensa->contiguous_regs_desc!");
3933  return ERROR_FAIL;
3934  }
3935  }
3936 
3937  const char *regname = CMD_ARGV[0];
3938  unsigned int regnum = strtoul(CMD_ARGV[1], NULL, 0);
3939  if (regnum > UINT16_MAX) {
3940  command_print(CMD, "<regnum> must be a 16-bit number");
3942  }
3943 
3945  if (xtensa->total_regs_num)
3946  command_print(CMD, "'xtreg %s 0x%04x': Too many registers (%d expected, %d core %d extended)",
3947  regname, regnum,
3949  else
3950  command_print(CMD, "'xtreg %s 0x%04x': Number of registers unspecified",
3951  regname, regnum);
3952  return ERROR_FAIL;
3953  }
3954 
3955  /* Determine whether register belongs in xtensa_regs[] or xtensa->xtensa_spec_regs[] */
3956  struct xtensa_reg_desc *rptr = &xtensa->optregs[xtensa->num_optregs];
3957  bool is_extended_reg = true;
3958  unsigned int ridx;
3959  for (ridx = 0; ridx < XT_NUM_REGS; ridx++) {
3960  if (strcmp(CMD_ARGV[0], xtensa_regs[ridx].name) == 0) {
3961  /* Flag core register as defined */
3962  rptr = &xtensa_regs[ridx];
3963  xtensa->core_regs_num++;
3964  is_extended_reg = false;
3965  break;
3966  }
3967  }
3968 
3969  rptr->exist = true;
3970  if (is_extended_reg) {
3971  /* Register ID, debugger-visible register ID */
3972  rptr->name = strdup(CMD_ARGV[0]);
3973  rptr->dbreg_num = regnum;
3974  rptr->reg_num = (regnum & XT_REG_INDEX_MASK);
3975  xtensa->num_optregs++;
3976 
3977  /* Register type */
3978  if ((regnum & XT_REG_GENERAL_MASK) == XT_REG_GENERAL_VAL) {
3979  rptr->type = XT_REG_GENERAL;
3980  } else if ((regnum & XT_REG_USER_MASK) == XT_REG_USER_VAL) {
3981  rptr->type = XT_REG_USER;
3982  } else if ((regnum & XT_REG_FR_MASK) == XT_REG_FR_VAL) {
3983  rptr->type = XT_REG_FR;
3984  } else if ((regnum & XT_REG_SPECIAL_MASK) == XT_REG_SPECIAL_VAL) {
3985  rptr->type = XT_REG_SPECIAL;
3986  } else if ((regnum & XT_REG_RELGEN_MASK) == XT_REG_RELGEN_VAL) {
3987  /* WARNING: For these registers, regnum points to the
3988  * index of the corresponding ARx registers, NOT to
3989  * the processor register number! */
3990  rptr->type = XT_REG_RELGEN;
3991  rptr->reg_num += XT_REG_IDX_ARFIRST;
3992  rptr->dbreg_num += XT_REG_IDX_ARFIRST;
3993  } else if ((regnum & XT_REG_TIE_MASK) != 0) {
3994  rptr->type = XT_REG_TIE;
3995  } else {
3996  rptr->type = XT_REG_OTHER;
3997  }
3998 
3999  /* Register flags: includes intsetN, intclearN for LX8 */
4000  if ((strcmp(rptr->name, "mmid") == 0) || (strcmp(rptr->name, "eraccess") == 0) ||
4001  (strcmp(rptr->name, "ddr") == 0) || (strncmp(rptr->name, "intset", 6) == 0) ||
4002  (strncmp(rptr->name, "intclear", 8) == 0) || (strcmp(rptr->name, "mesrclr") == 0))
4003  rptr->flags = XT_REGF_NOREAD;
4004  else
4005  rptr->flags = 0;
4006 
4008  xtensa->core_config->core_type == XT_LX && rptr->type == XT_REG_SPECIAL) {
4010  LOG_DEBUG("Setting PS (%s) index to %d", rptr->name, xtensa->eps_dbglevel_idx);
4011  }
4012  if (xtensa->core_config->core_type == XT_NX) {
4014  if (strcmp(rptr->name, "ibreakc0") == 0)
4015  idx = XT_NX_REG_IDX_IBREAKC0;
4016  else if (strcmp(rptr->name, "wb") == 0)
4017  idx = XT_NX_REG_IDX_WB;
4018  else if (strcmp(rptr->name, "ms") == 0)
4019  idx = XT_NX_REG_IDX_MS;
4020  else if (strcmp(rptr->name, "ievec") == 0)
4021  idx = XT_NX_REG_IDX_IEVEC;
4022  else if (strcmp(rptr->name, "ieextern") == 0)
4023  idx = XT_NX_REG_IDX_IEEXTERN;
4024  else if (strcmp(rptr->name, "mesr") == 0)
4025  idx = XT_NX_REG_IDX_MESR;
4026  else if (strcmp(rptr->name, "mesrclr") == 0)
4027  idx = XT_NX_REG_IDX_MESRCLR;
4028  if (idx < XT_NX_REG_IDX_NUM) {
4029  if (xtensa->nx_reg_idx[idx] != 0) {
4030  command_print(CMD, "nx_reg_idx[%d] previously set to %d",
4031  idx, xtensa->nx_reg_idx[idx]);
4032  return ERROR_FAIL;
4033  }
4035  LOG_DEBUG("NX reg %s: index %d (%d)",
4036  rptr->name, xtensa->nx_reg_idx[idx], idx);
4037  }
4038  }
4039  } else if (strcmp(rptr->name, "cpenable") == 0) {
4040  xtensa->core_config->coproc = true;
4041  }
4042 
4043  /* Build out list of contiguous registers in specified order */
4044  unsigned int running_reg_count = xtensa->num_optregs + xtensa->core_regs_num;
4046  assert((running_reg_count <= xtensa->total_regs_num) && "contiguous register address internal error!");
4047  xtensa->contiguous_regs_desc[running_reg_count - 1] = rptr;
4048  }
4050  LOG_DEBUG("Added %s register %-16s: 0x%04x/0x%02x t%d (%d of %d)",
4051  is_extended_reg ? "config-specific" : "core",
4052  rptr->name, rptr->dbreg_num, rptr->reg_num, rptr->type,
4053  is_extended_reg ? xtensa->num_optregs : ridx,
4054  is_extended_reg ? xtensa->total_regs_num : XT_NUM_REGS);
4055  return ERROR_OK;
4056 }
4057 
4058 COMMAND_HANDLER(xtensa_cmd_xtreg)
4059 {
4060  return CALL_COMMAND_HANDLER(xtensa_cmd_xtreg_do,
4062 }
4063 
4064 /* xtregfmt <contiguous|sparse> [numgregs] */
4065 COMMAND_HELPER(xtensa_cmd_xtregfmt_do, struct xtensa *xtensa)
4066 {
4067  if ((CMD_ARGC == 1) || (CMD_ARGC == 2)) {
4068  if (!strcasecmp(CMD_ARGV[0], "sparse")) {
4069  return ERROR_OK;
4070  } else if (!strcasecmp(CMD_ARGV[0], "contiguous")) {
4071  xtensa->regmap_contiguous = true;
4072  if (CMD_ARGC == 2) {
4073  unsigned int numgregs = strtoul(CMD_ARGV[1], NULL, 0);
4074  if ((numgregs <= 0) ||
4075  ((numgregs > xtensa->total_regs_num) &&
4076  (xtensa->total_regs_num > 0))) {
4077  command_print(CMD, "xtregfmt: if specified, numgregs (%d) must be <= numregs (%d)",
4078  numgregs, xtensa->total_regs_num);
4080  }
4081  xtensa->genpkt_regs_num = numgregs;
4082  }
4083  return ERROR_OK;
4084  }
4085  }
4087 }
4088 
4089 COMMAND_HANDLER(xtensa_cmd_xtregfmt)
4090 {
4091  return CALL_COMMAND_HANDLER(xtensa_cmd_xtregfmt_do,
4093 }
4094 
4095 COMMAND_HELPER(xtensa_cmd_permissive_mode_do, struct xtensa *xtensa)
4096 {
4097  return CALL_COMMAND_HANDLER(handle_command_parse_bool,
4098  &xtensa->permissive_mode, "xtensa permissive mode");
4099 }
4100 
4101 COMMAND_HANDLER(xtensa_cmd_permissive_mode)
4102 {
4103  return CALL_COMMAND_HANDLER(xtensa_cmd_permissive_mode_do,
4105 }
4106 
4107 /* perfmon_enable <counter_id> <select> [mask] [kernelcnt] [tracelevel] */
4108 COMMAND_HELPER(xtensa_cmd_perfmon_enable_do, struct xtensa *xtensa)
4109 {
4110  struct xtensa_perfmon_config config = {
4111  .mask = 0xffff,
4112  .kernelcnt = 0,
4113  .tracelevel = -1 /* use DEBUGLEVEL by default */
4114  };
4115 
4116  if (CMD_ARGC < 2 || CMD_ARGC > 6)
4118 
4119  unsigned int counter_id = strtoul(CMD_ARGV[0], NULL, 0);
4120  if (counter_id >= XTENSA_MAX_PERF_COUNTERS) {
4121  command_print(CMD, "counter_id should be < %d", XTENSA_MAX_PERF_COUNTERS);
4123  }
4124 
4125  config.select = strtoul(CMD_ARGV[1], NULL, 0);
4126  if (config.select > XTENSA_MAX_PERF_SELECT) {
4127  command_print(CMD, "select should be < %d", XTENSA_MAX_PERF_SELECT);
4129  }
4130 
4131  if (CMD_ARGC >= 3) {
4132  config.mask = strtoul(CMD_ARGV[2], NULL, 0);
4133  if (config.mask > XTENSA_MAX_PERF_MASK) {
4134  command_print(CMD, "mask should be < %d", XTENSA_MAX_PERF_MASK);
4136  }
4137  }
4138 
4139  if (CMD_ARGC >= 4) {
4140  config.kernelcnt = strtoul(CMD_ARGV[3], NULL, 0);
4141  if (config.kernelcnt > 1) {
4142  command_print(CMD, "kernelcnt should be 0 or 1");
4144  }
4145  }
4146 
4147  if (CMD_ARGC >= 5) {
4148  config.tracelevel = strtoul(CMD_ARGV[4], NULL, 0);
4149  if (config.tracelevel > 7) {
4150  command_print(CMD, "tracelevel should be <=7");
4152  }
4153  }
4154 
4155  if (config.tracelevel == -1)
4156  config.tracelevel = xtensa->core_config->debug.irq_level;
4157 
4158  return xtensa_dm_perfmon_enable(&xtensa->dbg_mod, counter_id, &config);
4159 }
4160 
4161 COMMAND_HANDLER(xtensa_cmd_perfmon_enable)
4162 {
4163  return CALL_COMMAND_HANDLER(xtensa_cmd_perfmon_enable_do,
4165 }
4166 
4167 /* perfmon_dump [counter_id] */
4168 COMMAND_HELPER(xtensa_cmd_perfmon_dump_do, struct xtensa *xtensa)
4169 {
4170  if (CMD_ARGC > 1)
4172 
4173  int counter_id = -1;
4174  if (CMD_ARGC == 1) {
4175  counter_id = strtol(CMD_ARGV[0], NULL, 0);
4176  if (counter_id > XTENSA_MAX_PERF_COUNTERS) {
4177  command_print(CMD, "counter_id should be < %d", XTENSA_MAX_PERF_COUNTERS);
4179  }
4180  }
4181 
4182  unsigned int counter_start = (counter_id < 0) ? 0 : counter_id;
4183  unsigned int counter_end = (counter_id < 0) ? XTENSA_MAX_PERF_COUNTERS : counter_id + 1;
4184  for (unsigned int counter = counter_start; counter < counter_end; ++counter) {
4185  char result_buf[128] = { 0 };
4186  size_t result_pos = snprintf(result_buf, sizeof(result_buf), "Counter %d: ", counter);
4187  struct xtensa_perfmon_result result;
4188  int res = xtensa_dm_perfmon_dump(&xtensa->dbg_mod, counter, &result);
4189  if (res != ERROR_OK)
4190  return res;
4191  snprintf(result_buf + result_pos, sizeof(result_buf) - result_pos,
4192  "%-12" PRIu64 "%s",
4193  result.value,
4194  result.overflow ? " (overflow)" : "");
4195  command_print(CMD, "%s", result_buf);
4196  }
4197 
4198  return ERROR_OK;
4199 }
4200 
4201 COMMAND_HANDLER(xtensa_cmd_perfmon_dump)
4202 {
4203  return CALL_COMMAND_HANDLER(xtensa_cmd_perfmon_dump_do,
4205 }
4206 
4207 COMMAND_HELPER(xtensa_cmd_mask_interrupts_do, struct xtensa *xtensa)
4208 {
4209  int state = -1;
4210 
4211  if (CMD_ARGC < 1) {
4212  const char *st;
4214  if (state == XT_STEPPING_ISR_ON)
4215  st = "OFF";
4216  else if (state == XT_STEPPING_ISR_OFF)
4217  st = "ON";
4218  else
4219  st = "UNKNOWN";
4220  command_print(CMD, "Current ISR step mode: %s", st);
4221  return ERROR_OK;
4222  }
4223 
4224  /* Masking is ON -> interrupts during stepping are OFF, and vice versa */
4225  if (!strcasecmp(CMD_ARGV[0], "off"))
4227  else if (!strcasecmp(CMD_ARGV[0], "on"))
4229 
4230  if (state == -1) {
4231  command_print(CMD, "Argument unknown. Please pick one of ON, OFF");
4232  return ERROR_FAIL;
4233  }
4235  return ERROR_OK;
4236 }
4237 
4238 COMMAND_HANDLER(xtensa_cmd_mask_interrupts)
4239 {
4240  return CALL_COMMAND_HANDLER(xtensa_cmd_mask_interrupts_do,
4242 }
4243 
4244 COMMAND_HELPER(xtensa_cmd_smpbreak_do, struct target *target)
4245 {
4246  int res;
4247  uint32_t val = 0;
4248 
4249  if (CMD_ARGC >= 1) {
4250  for (unsigned int i = 0; i < CMD_ARGC; i++) {
4251  if (!strcasecmp(CMD_ARGV[0], "none")) {
4252  val = 0;
4253  } else if (!strcasecmp(CMD_ARGV[i], "BreakIn")) {
4254  val |= OCDDCR_BREAKINEN;
4255  } else if (!strcasecmp(CMD_ARGV[i], "BreakOut")) {
4256  val |= OCDDCR_BREAKOUTEN;
4257  } else if (!strcasecmp(CMD_ARGV[i], "RunStallIn")) {
4258  val |= OCDDCR_RUNSTALLINEN;
4259  } else if (!strcasecmp(CMD_ARGV[i], "DebugModeOut")) {
4260  val |= OCDDCR_DEBUGMODEOUTEN;
4261  } else if (!strcasecmp(CMD_ARGV[i], "BreakInOut")) {
4263  } else if (!strcasecmp(CMD_ARGV[i], "RunStall")) {
4265  } else {
4266  command_print(CMD, "Unknown arg %s", CMD_ARGV[i]);
4267  command_print(
4268  CMD,
4269  "use either BreakInOut, None or RunStall as arguments, or any combination of BreakIn, BreakOut, RunStallIn and DebugModeOut.");
4270  return ERROR_OK;
4271  }
4272  }
4273  res = xtensa_smpbreak_set(target, val);
4274  if (res != ERROR_OK)
4275  command_print(CMD, "Failed to set smpbreak config %d", res);
4276  } else {
4277  struct xtensa *xtensa = target_to_xtensa(target);
4278  res = xtensa_smpbreak_read(xtensa, &val);
4279  if (res == ERROR_OK)
4280  command_print(CMD, "Current bits set:%s%s%s%s",
4281  (val & OCDDCR_BREAKINEN) ? " BreakIn" : "",
4282  (val & OCDDCR_BREAKOUTEN) ? " BreakOut" : "",
4283  (val & OCDDCR_RUNSTALLINEN) ? " RunStallIn" : "",
4284  (val & OCDDCR_DEBUGMODEOUTEN) ? " DebugModeOut" : ""
4285  );
4286  else
4287  command_print(CMD, "Failed to get smpbreak config %d", res);
4288  }
4289  return res;
4290 }
4291 
4292 COMMAND_HANDLER(xtensa_cmd_smpbreak)
4293 {
4294  return CALL_COMMAND_HANDLER(xtensa_cmd_smpbreak_do,
4296 }
4297 
4298 COMMAND_HELPER(xtensa_cmd_dm_rw_do, struct xtensa *xtensa)
4299 {
4300  if (CMD_ARGC == 1) {
4301  // read: xtensa dm addr
4302  uint32_t addr = strtoul(CMD_ARGV[0], NULL, 0);
4303  uint32_t val;
4304  int res = xtensa_dm_read(&xtensa->dbg_mod, addr, &val);
4305  if (res == ERROR_OK)
4306  command_print(CMD, "xtensa DM(0x%08" PRIx32 ") -> 0x%08" PRIx32, addr, val);
4307  else
4308  command_print(CMD, "xtensa DM(0x%08" PRIx32 ") : read ERROR %" PRId32, addr, res);
4309  return res;
4310  } else if (CMD_ARGC == 2) {
4311  // write: xtensa dm addr value
4312  uint32_t addr = strtoul(CMD_ARGV[0], NULL, 0);
4313  uint32_t val = strtoul(CMD_ARGV[1], NULL, 0);
4314  int res = xtensa_dm_write(&xtensa->dbg_mod, addr, val);
4315  if (res == ERROR_OK)
4316  command_print(CMD, "xtensa DM(0x%08" PRIx32 ") <- 0x%08" PRIx32, addr, val);
4317  else
4318  command_print(CMD, "xtensa DM(0x%08" PRIx32 ") : write ERROR %" PRId32, addr, res);
4319  return res;
4320  }
4322 }
4323 
4324 COMMAND_HANDLER(xtensa_cmd_dm_rw)
4325 {
4326  return CALL_COMMAND_HANDLER(xtensa_cmd_dm_rw_do,
4328 }
4329 
4330 COMMAND_HELPER(xtensa_cmd_tracestart_do, struct xtensa *xtensa)
4331 {
4333  struct xtensa_trace_start_config cfg = {
4334  .stoppc = 0,
4335  .stopmask = XTENSA_STOPMASK_DISABLED,
4336  .after = 0,
4337  .after_is_words = false
4338  };
4339 
4340  /* Parse arguments */
4341  for (unsigned int i = 0; i < CMD_ARGC; i++) {
4342  if ((!strcasecmp(CMD_ARGV[i], "pc")) && CMD_ARGC > i) {
4343  char *e;
4344  i++;
4345  cfg.stoppc = strtol(CMD_ARGV[i], &e, 0);
4346  cfg.stopmask = 0;
4347  if (*e == '/')
4348  cfg.stopmask = strtol(e, NULL, 0);
4349  } else if ((!strcasecmp(CMD_ARGV[i], "after")) && CMD_ARGC > i) {
4350  i++;
4351  cfg.after = strtol(CMD_ARGV[i], NULL, 0);
4352  } else if (!strcasecmp(CMD_ARGV[i], "ins")) {
4353  cfg.after_is_words = 0;
4354  } else if (!strcasecmp(CMD_ARGV[i], "words")) {
4355  cfg.after_is_words = 1;
4356  } else {
4357  command_print(CMD, "Did not understand %s", CMD_ARGV[i]);
4358  return ERROR_FAIL;
4359  }
4360  }
4361 
4363  if (res != ERROR_OK)
4364  return res;
4365  if (trace_status.stat & TRAXSTAT_TRACT) {
4366  LOG_WARNING("Silently stop active tracing!");
4367  res = xtensa_dm_trace_stop(&xtensa->dbg_mod, false);
4368  if (res != ERROR_OK)
4369  return res;
4370  }
4371 
4372  res = xtensa_dm_trace_start(&xtensa->dbg_mod, &cfg);
4373  if (res != ERROR_OK)
4374  return res;
4375 
4376  xtensa->trace_active = true;
4377  command_print(CMD, "Trace started.");
4378  return ERROR_OK;
4379 }
4380 
4381 COMMAND_HANDLER(xtensa_cmd_tracestart)
4382 {
4383  return CALL_COMMAND_HANDLER(xtensa_cmd_tracestart_do,
4385 }
4386 
4387 COMMAND_HELPER(xtensa_cmd_tracestop_do, struct xtensa *xtensa)
4388 {
4390 
4392  if (res != ERROR_OK)
4393  return res;
4394 
4395  if (!(trace_status.stat & TRAXSTAT_TRACT)) {
4396  command_print(CMD, "No trace is currently active.");
4397  return ERROR_FAIL;
4398  }
4399 
4400  res = xtensa_dm_trace_stop(&xtensa->dbg_mod, true);
4401  if (res != ERROR_OK)
4402  return res;
4403 
4404  xtensa->trace_active = false;
4405  command_print(CMD, "Trace stop triggered.");
4406  return ERROR_OK;
4407 }
4408 
4409 COMMAND_HANDLER(xtensa_cmd_tracestop)
4410 {
4411  return CALL_COMMAND_HANDLER(xtensa_cmd_tracestop_do,
4413 }
4414 
4415 COMMAND_HELPER(xtensa_cmd_tracedump_do, struct xtensa *xtensa, const char *fname)
4416 {
4417  struct xtensa_trace_config trace_config;
4419  uint32_t memsz, wmem;
4420 
4422  if (res != ERROR_OK)
4423  return res;
4424 
4425  if (trace_status.stat & TRAXSTAT_TRACT) {
4426  command_print(CMD, "Tracing is still active. Please stop it first.");
4427  return ERROR_FAIL;
4428  }
4429 
4430  res = xtensa_dm_trace_config_read(&xtensa->dbg_mod, &trace_config);
4431  if (res != ERROR_OK)
4432  return res;
4433 
4434  if (!(trace_config.ctrl & TRAXCTRL_TREN)) {
4435  command_print(CMD, "No active trace found; nothing to dump.");
4436  return ERROR_FAIL;
4437  }
4438 
4439  memsz = trace_config.memaddr_end - trace_config.memaddr_start + 1;
4440  command_print(CMD, "Total trace memory: %d words", memsz);
4441  if ((trace_config.addr &
4443  /*Memory hasn't overwritten itself yet. */
4444  wmem = trace_config.addr & TRAXADDR_TADDR_MASK;
4445  command_print(CMD, "...but trace is only %d words", wmem);
4446  if (wmem < memsz)
4447  memsz = wmem;
4448  } else {
4449  if (trace_config.addr & TRAXADDR_TWSAT) {
4450  command_print(CMD, "Real trace is many times longer than that (overflow)");
4451  } else {
4452  uint32_t trc_sz = (trace_config.addr >> TRAXADDR_TWRAP_SHIFT) & TRAXADDR_TWRAP_MASK;
4453  trc_sz = (trc_sz * memsz) + (trace_config.addr & TRAXADDR_TADDR_MASK);
4454  command_print(CMD, "Real trace is %d words, but the start has been truncated.", trc_sz);
4455  }
4456  }
4457 
4458  uint8_t *tracemem = malloc(memsz * 4);
4459  if (!tracemem) {
4460  command_print(CMD, "Failed to alloc memory for trace data!");
4461  return ERROR_FAIL;
4462  }
4463  res = xtensa_dm_trace_data_read(&xtensa->dbg_mod, tracemem, memsz * 4);
4464  if (res != ERROR_OK) {
4465  free(tracemem);
4466  return res;
4467  }
4468 
4469  int f = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0666);
4470  if (f <= 0) {
4471  free(tracemem);
4472  command_print(CMD, "Unable to open file %s", fname);
4473  return ERROR_FAIL;
4474  }
4475  if (write(f, tracemem, memsz * 4) != (int)memsz * 4)
4476  command_print(CMD, "Unable to write to file %s", fname);
4477  else
4478  command_print(CMD, "Written %d bytes of trace data to %s", memsz * 4, fname);
4479  close(f);
4480 
4481  bool is_all_zeroes = true;
4482  for (unsigned int i = 0; i < memsz * 4; i++) {
4483  if (tracemem[i] != 0) {
4484  is_all_zeroes = false;
4485  break;
4486  }
4487  }
4488  free(tracemem);
4489  if (is_all_zeroes)
4490  command_print(
4491  CMD,
4492  "WARNING: File written is all zeroes. Are you sure you enabled trace memory?");
4493 
4494  return ERROR_OK;
4495 }
4496 
4497 COMMAND_HANDLER(xtensa_cmd_tracedump)
4498 {
4499  if (CMD_ARGC != 1) {
4500  command_print(CMD, "Command takes exactly 1 parameter.Need filename to dump to as output!");
4501  return ERROR_FAIL;
4502  }
4503 
4504  return CALL_COMMAND_HANDLER(xtensa_cmd_tracedump_do,
4506 }
4507 
4508 static const struct command_registration xtensa_any_command_handlers[] = {
4509  {
4510  .name = "xtdef",
4511  .handler = xtensa_cmd_xtdef,
4512  .mode = COMMAND_CONFIG,
4513  .help = "Configure Xtensa core type",
4514  .usage = "<type>",
4515  },
4516  {
4517  .name = "xtopt",
4518  .handler = xtensa_cmd_xtopt,
4519  .mode = COMMAND_CONFIG,
4520  .help = "Configure Xtensa core option",
4521  .usage = "<name> <value>",
4522  },
4523  {
4524  .name = "xtmem",
4525  .handler = xtensa_cmd_xtmem,
4526  .mode = COMMAND_CONFIG,
4527  .help = "Configure Xtensa memory/cache option",
4528  .usage = "<type> [parameters]",
4529  },
4530  {
4531  .name = "xtmmu",
4532  .handler = xtensa_cmd_xtmmu,
4533  .mode = COMMAND_CONFIG,
4534  .help = "Configure Xtensa MMU option",
4535  .usage = "<NIREFILLENTRIES> <NDREFILLENTRIES> <IVARWAY56> <DVARWAY56>",
4536  },
4537  {
4538  .name = "xtmpu",
4539  .handler = xtensa_cmd_xtmpu,
4540  .mode = COMMAND_CONFIG,
4541  .help = "Configure Xtensa MPU option",
4542  .usage = "<num FG seg> <min seg size> <lockable> <executeonly>",
4543  },
4544  {
4545  .name = "xtreg",
4546  .handler = xtensa_cmd_xtreg,
4547  .mode = COMMAND_CONFIG,
4548  .help = "Configure Xtensa register",
4549  .usage = "<regname> <regnum>",
4550  },
4551  {
4552  .name = "xtregs",
4553  .handler = xtensa_cmd_xtreg,
4554  .mode = COMMAND_CONFIG,
4555  .help = "Configure number of Xtensa registers",
4556  .usage = "<numregs>",
4557  },
4558  {
4559  .name = "xtregfmt",
4560  .handler = xtensa_cmd_xtregfmt,
4561  .mode = COMMAND_CONFIG,
4562  .help = "Configure format of Xtensa register map",
4563  .usage = "<contiguous|sparse> [numgregs]",
4564  },
4565  {
4566  .name = "set_permissive",
4567  .handler = xtensa_cmd_permissive_mode,
4568  .mode = COMMAND_ANY,
4569  .help = "When set to 1, enable Xtensa permissive mode (fewer client-side checks)",
4570  .usage = "[0|1]",
4571  },
4572  {
4573  .name = "maskisr",
4574  .handler = xtensa_cmd_mask_interrupts,
4575  .mode = COMMAND_ANY,
4576  .help = "mask Xtensa interrupts at step",
4577  .usage = "['on'|'off']",
4578  },
4579  {
4580  .name = "smpbreak",
4581  .handler = xtensa_cmd_smpbreak,
4582  .mode = COMMAND_ANY,
4583  .help = "Set the way the CPU chains OCD breaks",
4584  .usage = "[none|breakinout|runstall] | [BreakIn] [BreakOut] [RunStallIn] [DebugModeOut]",
4585  },
4586  {
4587  .name = "dm",
4588  .handler = xtensa_cmd_dm_rw,
4589  .mode = COMMAND_ANY,
4590  .help = "Xtensa DM read/write",
4591  .usage = "addr [value]"
4592  },
4593  {
4594  .name = "perfmon_enable",
4595  .handler = xtensa_cmd_perfmon_enable,
4596  .mode = COMMAND_EXEC,
4597  .help = "Enable and start performance counter",
4598  .usage = "<counter_id> <select> [mask] [kernelcnt] [tracelevel]",
4599  },
4600  {
4601  .name = "perfmon_dump",
4602  .handler = xtensa_cmd_perfmon_dump,
4603  .mode = COMMAND_EXEC,
4604  .help = "Dump performance counter value. If no argument specified, dumps all counters.",
4605  .usage = "[counter_id]",
4606  },
4607  {
4608  .name = "tracestart",
4609  .handler = xtensa_cmd_tracestart,
4610  .mode = COMMAND_EXEC,
4611  .help =
4612  "Tracing: Set up and start a trace. Optionally set stop trigger address and amount of data captured after.",
4613  .usage = "[pc <pcval>/[maskbitcount]] [after <n> [ins|words]]",
4614  },
4615  {
4616  .name = "tracestop",
4617  .handler = xtensa_cmd_tracestop,
4618  .mode = COMMAND_EXEC,
4619  .help = "Tracing: Stop current trace as started by the tracestart command",
4620  .usage = "",
4621  },
4622  {
4623  .name = "tracedump",
4624  .handler = xtensa_cmd_tracedump,
4625  .mode = COMMAND_EXEC,
4626  .help = "Tracing: Dump trace memory to a files. One file per core.",
4627  .usage = "<outfile>",
4628  },
4629  {
4630  .name = "exe",
4631  .handler = xtensa_cmd_exe,
4632  .mode = COMMAND_ANY,
4633  .help = "Xtensa stub execution",
4634  .usage = "<ascii-encoded hexadecimal instruction bytes>",
4635  },
4637 };
4638 
4640  {
4641  .name = "xtensa",
4642  .mode = COMMAND_ANY,
4643  .help = "Xtensa command group",
4644  .usage = "",
4645  .chain = xtensa_any_command_handlers,
4646  },
4648 };
@ PARAM_OUT
Definition: algorithm.h:16
@ PARAM_IN
Definition: algorithm.h:15
#define IS_ALIGNED(x, a)
Definition: align.h:22
#define IS_PWR_OF_2(x)
Definition: align.h:24
#define ALIGN_DOWN(x, a)
Definition: align.h:21
#define ALIGN_UP(x, a)
Definition: align.h:20
const char * name
Definition: am13e230x.c:167
void * buf_cpy(const void *from, void *_to, unsigned int size)
Copies size bits out of from and into to.
Definition: binarybuffer.c:43
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned int first, unsigned int num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
Definition: binarybuffer.h:104
static void buf_set_u32(uint8_t *_buffer, unsigned int first, unsigned int num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:34
static uint64_t buf_get_u64(const uint8_t *_buffer, unsigned int first, unsigned int num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 64-bit word.
Definition: binarybuffer.h:134
@ BKPT_SOFT
Definition: breakpoints.h:19
#define WATCHPOINT_IGNORE_DATA_VALUE_MASK
Definition: breakpoints.h:39
@ WPT_ACCESS
Definition: breakpoints.h:23
@ WPT_READ
Definition: breakpoints.h:23
@ WPT_WRITE
Definition: breakpoints.h:23
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:389
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
Definition: command.h:146
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
Definition: command.h:123
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:161
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:405
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:156
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
Definition: command.h:151
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:256
#define ERROR_COMMAND_ARGUMENT_INVALID
Definition: command.h:407
@ COMMAND_CONFIG
Definition: command.h:41
@ COMMAND_ANY
Definition: command.h:42
@ COMMAND_EXEC
Definition: command.h:40
uint64_t buffer
Pointer to data buffer to send over SPI.
Definition: dw-spi-helper.h:0
uint32_t size
Size of dw_spi_transaction::buffer.
Definition: dw-spi-helper.h:4
uint32_t address
Starting address. Sector aligned.
Definition: dw-spi-helper.h:0
uint8_t type
Definition: esp_usb_jtag.c:0
static uint16_t direction
Definition: ftdi.c:157
void keep_alive(void)
Definition: log.c:437
static int64_t start
Definition: log.c:38
#define LOG_TARGET_INFO(target, fmt_str,...)
Definition: log.h:167
#define LOG_TARGET_WARNING(target, fmt_str,...)
Definition: log.h:173
#define LOG_WARNING(expr ...)
Definition: log.h:144
#define ERROR_FAIL
Definition: log.h:188
#define LOG_TARGET_ERROR(target, fmt_str,...)
Definition: log.h:176
#define LOG_TARGET_DEBUG(target, fmt_str,...)
Definition: log.h:164
#define LOG_ERROR(expr ...)
Definition: log.h:147
#define LOG_LEVEL_IS(FOO)
Definition: log.h:112
#define LOG_INFO(expr ...)
Definition: log.h:141
#define LOG_DEBUG(expr ...)
Definition: log.h:124
#define ERROR_OK
Definition: log.h:182
@ LOG_LVL_DEBUG
Definition: log.h:55
#define a3
Definition: mips32.c:191
#define a0
Definition: mips32.c:188
struct reg * register_get_by_name(struct reg_cache *first, const char *name, bool search_all)
Definition: register.c:50
struct reg_cache ** register_get_last_cache_p(struct reg_cache **first)
Definition: register.c:72
void register_unlink_cache(struct reg_cache **cache_p, const struct reg_cache *cache)
Definition: register.c:85
void register_cache_invalidate(struct reg_cache *cache)
Marks the contents of the register cache as invalid (and clean).
Definition: register.c:94
#define MIN(a, b)
Definition: replacements.h:22
slot
Definition: riscv-011.c:124
target_addr_t addr
Start address to search for the control block.
Definition: rtt/rtt.c:28
struct target * target
Definition: rtt/rtt.c:26
#define BIT(nr)
Definition: stm32l4x.h:18
unsigned int length
Definition: breakpoints.h:29
enum breakpoint_type type
Definition: breakpoints.h:30
target_addr_t address
Definition: breakpoints.h:27
const char * name
Definition: command.h:239
int(* get)(struct reg *reg)
Definition: register.h:152
const char * name
Definition: register.h:145
unsigned int num_regs
Definition: register.h:148
struct reg * reg_list
Definition: register.h:147
struct reg_cache * next
Definition: register.h:146
uint32_t size
Definition: algorithm.h:29
const char * reg_name
Definition: algorithm.h:28
Definition: register.h:111
bool valid
Definition: register.h:126
bool exist
Definition: register.h:128
uint32_t size
Definition: register.h:132
uint8_t * value
Definition: register.h:122
uint32_t number
Definition: register.h:115
void * arch_info
Definition: register.h:140
bool dirty
Definition: register.h:124
const struct reg_arch_type * type
Definition: register.h:141
const char * name
Definition: register.h:113
Definition: target.h:119
enum target_debug_reason debug_reason
Definition: target.h:164
enum target_state state
Definition: target.h:167
enum target_endianness endianness
Definition: target.h:165
struct reg_cache * reg_cache
Definition: target.h:168
void * arch_info
Definition: target.h:174
bool reset_halt
Definition: target.h:154
bool examined
Indicates whether this target has been examined, remembers the last result of examine call.
Definition: target.h:135
uint64_t mask
Definition: breakpoints.h:44
enum watchpoint_rw rw
Definition: breakpoints.h:46
unsigned int length
Definition: breakpoints.h:43
target_addr_t address
Definition: breakpoints.h:42
Xtensa algorithm data.
Definition: xtensa.h:229
xtensa_reg_val_t ctx_ps
Definition: xtensa.h:234
enum target_debug_reason ctx_debug_reason
Used internally to backup and restore core state.
Definition: xtensa.h:233
enum xtensa_mode core_mode
User can set this to specify which core mode algorithm should be run in.
Definition: xtensa.h:231
uint8_t way_count
Definition: xtensa.h:113
uint32_t size
Definition: xtensa.h:115
uint32_t line_size
Definition: xtensa.h:114
struct xtensa_cache_config dcache
Definition: xtensa.h:182
struct xtensa_debug_config debug
Definition: xtensa.h:179
struct xtensa_tracing_config trace
Definition: xtensa.h:180
struct xtensa_local_mem_config irom
Definition: xtensa.h:183
struct xtensa_local_mem_config drom
Definition: xtensa.h:185
struct xtensa_mpu_config mpu
Definition: xtensa.h:178
enum xtensa_type core_type
Definition: xtensa.h:170
struct xtensa_cache_config icache
Definition: xtensa.h:181
struct xtensa_local_mem_config iram
Definition: xtensa.h:184
struct xtensa_high_prio_irq_config high_irq
Definition: xtensa.h:176
struct xtensa_mmu_config mmu
Definition: xtensa.h:177
uint8_t aregs_num
Definition: xtensa.h:171
struct xtensa_irq_config irq
Definition: xtensa.h:175
struct xtensa_local_mem_config dram
Definition: xtensa.h:186
struct xtensa_local_mem_config sram
Definition: xtensa.h:187
bool windowed
Definition: xtensa.h:172
struct xtensa_local_mem_config srom
Definition: xtensa.h:188
bool coproc
Definition: xtensa.h:173
bool exceptions
Definition: xtensa.h:174
uint8_t irq_level
Definition: xtensa.h:157
uint8_t ibreaks_num
Definition: xtensa.h:158
uint8_t dbreaks_num
Definition: xtensa.h:159
uint8_t perfcount_num
Definition: xtensa.h:160
struct xtensa_power_status power_status
const struct xtensa_power_ops * pwr_ops
struct xtensa_core_status core_status
uint8_t irq_num
Definition: xtensa.h:146
struct xtensa_local_mem_region_config regions[XT_LOCAL_MEM_REGIONS_NUM_MAX]
Definition: xtensa.h:127
uint8_t itlb_entries_count
Definition: xtensa.h:132
uint8_t dtlb_entries_count
Definition: xtensa.h:133
uint8_t nfgseg
Definition: xtensa.h:138
uint32_t minsegsize
Definition: xtensa.h:139
int(* queue_reg_write)(struct xtensa_debug_module *dm, enum xtensa_dm_pwr_reg reg, uint32_t data)
register write.
xtensa_pwrstat_t stath
unsigned int reg_num
Definition: xtensa_regs.h:116
enum xtensa_reg_flags flags
Definition: xtensa_regs.h:119
const char * name
Definition: xtensa_regs.h:114
unsigned int dbreg_num
Definition: xtensa_regs.h:117
enum xtensa_reg_type type
Definition: xtensa_regs.h:118
uint8_t insn[XT_ISNS_SZ_MAX]
Definition: xtensa.h:221
struct breakpoint * oocd_bp
Definition: xtensa.h:219
bool reversed_mem_access
Definition: xtensa.h:166
Represents a generic Xtensa core.
Definition: xtensa.h:242
struct watchpoint ** hw_wps
Definition: xtensa.h:268
uint8_t come_online_probes_num
Definition: xtensa.h:282
unsigned int dbregs_num
Definition: xtensa.h:263
struct xtensa_reg_desc ** contiguous_regs_desc
Definition: xtensa.h:252
unsigned int total_regs_num
Definition: xtensa.h:248
struct reg * empty_regs
Definition: xtensa.h:257
struct xtensa_debug_module dbg_mod
Definition: xtensa.h:246
char qpkt_resp[XT_QUERYPKT_RESP_MAX]
Definition: xtensa.h:258
bool permissive_mode
Definition: xtensa.h:271
uint32_t smp_break
Definition: xtensa.h:273
bool suppress_dsr_errors
Definition: xtensa.h:272
struct reg ** contiguous_regs_list
Definition: xtensa.h:253
bool trace_active
Definition: xtensa.h:270
uint32_t spill_loc
Definition: xtensa.h:274
struct target * target
Definition: xtensa.h:264
int8_t probe_lsddr32p
Definition: xtensa.h:277
unsigned int eps_dbglevel_idx
Definition: xtensa.h:262
void ** algo_context_backup
Definition: xtensa.h:261
bool reset_asserted
Definition: xtensa.h:265
uint8_t * spill_buf
Definition: xtensa.h:276
struct xtensa_sw_breakpoint * sw_brps
Definition: xtensa.h:269
uint32_t nx_stop_cause
Definition: xtensa.h:285
unsigned int genpkt_regs_num
Definition: xtensa.h:251
enum xtensa_stepping_isr_mode stepping_isr_mode
Definition: xtensa.h:266
bool regmap_contiguous
Definition: xtensa.h:250
bool halt_request
Definition: xtensa.h:284
struct reg_cache * core_cache
Definition: xtensa.h:247
bool regs_fetched
Definition: xtensa.h:288
unsigned int num_optregs
Definition: xtensa.h:256
unsigned int core_regs_num
Definition: xtensa.h:249
struct xtensa_keyval_info scratch_ars[XT_AR_SCRATCH_NUM]
Definition: xtensa.h:287
struct xtensa_reg_desc * optregs
Definition: xtensa.h:255
uint32_t nx_reg_idx[XT_NX_REG_IDX_NUM]
Definition: xtensa.h:286
struct breakpoint ** hw_brps
Definition: xtensa.h:267
unsigned int common_magic
Definition: xtensa.h:243
struct xtensa_config * core_config
Definition: xtensa.h:245
unsigned int spill_bytes
Definition: xtensa.h:275
int target_call_event_callbacks(struct target *target, enum target_event event)
Definition: target.c:1816
int target_halt(struct target *target)
Definition: target.c:518
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
Definition: target.c:2410
int target_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
Definition: target.c:2475
const char * target_state_name(const struct target *t)
Return the name of this targets current state.
Definition: target.c:271
int target_wait_state(struct target *target, enum target_state state, unsigned int ms)
Definition: target.c:3238
struct target * get_current_target(struct command_context *cmd_ctx)
Definition: target.c:469
uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer)
Definition: target.c:327
@ DBG_REASON_WPTANDBKPT
Definition: target.h:75
@ DBG_REASON_NOTHALTED
Definition: target.h:77
@ DBG_REASON_DBGRQ
Definition: target.h:72
@ DBG_REASON_SINGLESTEP
Definition: target.h:76
@ DBG_REASON_WATCHPOINT
Definition: target.h:74
@ DBG_REASON_BREAKPOINT
Definition: target.h:73
target_register_class
Definition: target.h:113
@ REG_CLASS_GENERAL
Definition: target.h:115
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:818
static bool target_was_examined(const struct target *target)
Definition: target.h:444
@ TARGET_EVENT_HALTED
Definition: target.h:266
@ TARGET_EVENT_RESUMED
Definition: target.h:267
static const char * target_name(const struct target *target)
Returns the instance-specific name of the specified target.
Definition: target.h:247
target_state
Definition: target.h:55
@ TARGET_RESET
Definition: target.h:59
@ TARGET_DEBUG_RUNNING
Definition: target.h:60
@ TARGET_UNKNOWN
Definition: target.h:56
@ TARGET_HALTED
Definition: target.h:58
@ TARGET_RUNNING
Definition: target.h:57
#define ERROR_TARGET_NOT_EXAMINED
Definition: target.h:825
@ TARGET_BIG_ENDIAN
Definition: target.h:85
#define ERROR_TARGET_TIMEOUT
Definition: target.h:817
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
Definition: target.h:822
#define ERROR_TARGET_FAILURE
Definition: target.h:819
int64_t timeval_ms(void)
trace_status
Definition: trace.h:36
#define TARGET_ADDR_FMT
Definition: types.h:286
#define DIV_ROUND_UP(m, n)
Rounds m up to the nearest multiple of n using division.
Definition: types.h:79
uint64_t target_addr_t
Definition: types.h:279
static void buf_bswap32(uint8_t *dst, const uint8_t *src, size_t len)
Byte-swap buffer 32-bit.
Definition: types.h:249
xtensa_reg_val_t val
Definition: xtensa.c:330
uint8_t buf[4]
Definition: xtensa.c:331
#define NULL
Definition: usb.h:16
uint8_t status[4]
Definition: vdebug.c:17
uint8_t cmd
Definition: vdebug.c:1
uint8_t state[4]
Definition: vdebug.c:21
uint8_t count[4]
Definition: vdebug.c:22
int xtensa_gdb_query_custom(struct target *target, const char *packet, char **response_p)
Definition: xtensa.c:3286
#define XT_INS_RSR(X, SR, T)
Definition: xtensa.c:134
static int xtensa_core_reg_set(struct reg *reg, uint8_t *buf)
Definition: xtensa.c:450
static bool xtensa_memory_op_validate_range(struct xtensa *xtensa, target_addr_t address, size_t size, int access)
Check if the address gets to memory regions, and its access mode.
Definition: xtensa.c:1995
void xtensa_reg_set_deep_relgen(struct target *target, enum xtensa_reg_id a_idx, xtensa_reg_val_t value)
Definition: xtensa.c:1084
static COMMAND_HELPER(xtensa_cmd_exe_do, struct target *target)
Definition: xtensa.c:3550
#define XT_INS_L32E(X, R, S, T)
Definition: xtensa.c:153
static void xtensa_mark_register_dirty(struct xtensa *xtensa, enum xtensa_reg_id reg_idx)
Definition: xtensa.c:521
#define XT_INS_SDDR32P(X, S)
Definition: xtensa.c:107
static bool xtensa_reg_is_readable(int flags, int cpenable)
Definition: xtensa.c:641
static enum xtensa_reg_id xtensa_canonical_to_windowbase_offset(struct xtensa *xtensa, enum xtensa_reg_id reg_idx, int windowbase)
Definition: xtensa.c:514
#define XT_INS_IHI(X, S, IMM8)
Definition: xtensa.c:124
int xtensa_breakpoint_add(struct target *target, struct breakpoint *breakpoint)
Definition: xtensa.c:2570
#define XT_HW_DBREAK_MAX_NUM
Definition: xtensa.c:188
#define XT_WATCHPOINTS_NUM_MAX
Definition: xtensa.c:167
void xtensa_target_deinit(struct target *target)
Definition: xtensa.c:3511
static const bool xtensa_extra_debug_log
Definition: xtensa.c:342
int xtensa_watchpoint_add(struct target *target, struct watchpoint *watchpoint)
Definition: xtensa.c:2652
static int xtensa_queue_pwr_reg_write(struct xtensa *xtensa, unsigned int reg, uint32_t data)
Definition: xtensa.c:589
static enum xtensa_reg_id xtensa_windowbase_offset_to_canonical(struct xtensa *xtensa, enum xtensa_reg_id reg_idx, int windowbase)
Definition: xtensa.c:496
static bool xtensa_cmd_xtopt_legal_val(char *opt, int val, int min, int max)
Definition: xtensa.c:3648
#define XT_INS_WFR(X, FR, T)
Definition: xtensa.c:151
const char * xtensa_get_gdb_arch(const struct target *target)
Definition: xtensa.c:3544
uint32_t xtensa_cause_get(struct target *target)
Definition: xtensa.c:1099
#define XT_INS_RUR(X, UR, T)
Definition: xtensa.c:144
xtensa_mem_region_type
Types of memory used at xtensa target.
Definition: xtensa.c:297
@ XTENSA_MEM_REG_IRAM
Definition: xtensa.c:299
@ XTENSA_MEM_REGS_NUM
Definition: xtensa.c:304
@ XTENSA_MEM_REG_IROM
Definition: xtensa.c:298
@ XTENSA_MEM_REG_DRAM
Definition: xtensa.c:301
@ XTENSA_MEM_REG_SRAM
Definition: xtensa.c:302
@ XTENSA_MEM_REG_SROM
Definition: xtensa.c:303
@ XTENSA_MEM_REG_DROM
Definition: xtensa.c:300
#define XT_INS_ROTW(X, N)
Definition: xtensa.c:141
static bool xtensa_pc_in_winexc(struct target *target, target_addr_t pc)
Definition: xtensa.c:1707
int xtensa_smpbreak_read(struct xtensa *xtensa, uint32_t *val)
Definition: xtensa.c:960
int xtensa_poll(struct target *target)
Definition: xtensa.c:2320
#define XT_SR_WB
Definition: xtensa.c:174
#define XT_HW_IBREAK_MAX_NUM
Definition: xtensa.c:187
#define XT_REG_A3
Definition: xtensa.c:176
int xtensa_halt(struct target *target)
Definition: xtensa.c:1570
static const struct command_registration xtensa_any_command_handlers[]
Definition: xtensa.c:4508
static void xtensa_reg_set_value(struct reg *reg, xtensa_reg_val_t value)
Definition: xtensa.c:984
int xtensa_breakpoint_remove(struct target *target, struct breakpoint *breakpoint)
Definition: xtensa.c:2614
static bool xtensa_scratch_regs_fixup(struct xtensa *xtensa, struct reg *reg_list, int i, int j, int a_idx, int ar_idx)
Definition: xtensa.c:650
int xtensa_read_buffer(struct target *target, target_addr_t address, uint32_t count, uint8_t *buffer)
Definition: xtensa.c:2097
int xtensa_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size, enum target_register_class reg_class)
Definition: xtensa.c:1493
int xtensa_target_init(struct command_context *cmd_ctx, struct target *target)
Definition: xtensa.c:3441
static bool xtensa_region_ar_exec(struct target *target, target_addr_t start, target_addr_t end)
Definition: xtensa.c:552
int xtensa_checksum_memory(struct target *target, target_addr_t address, uint32_t count, uint32_t *checksum)
Definition: xtensa.c:2314
#define XT_TLB1_ACC_SHIFT
Definition: xtensa.c:164
#define XT_SW_BREAKPOINTS_MAX_NUM
Definition: xtensa.c:186
const struct command_registration xtensa_command_handlers[]
Definition: xtensa.c:4639
int xtensa_smpbreak_set(struct target *target, uint32_t set)
Definition: xtensa.c:947
static bool xtensa_memory_regions_overlap(target_addr_t r1_start, target_addr_t r1_end, target_addr_t r2_start, target_addr_t r2_end)
Returns true if two ranges are overlapping.
Definition: xtensa.c:1964
int xtensa_examine(struct target *target)
Definition: xtensa.c:890
static void xtensa_free_reg_cache(struct target *target)
Definition: xtensa.c:3473
int xtensa_do_step(struct target *target, bool current, target_addr_t address, bool handle_breakpoints)
Definition: xtensa.c:1727
int xtensa_start_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t entry_point, target_addr_t exit_point, void *arch_info)
Definition: xtensa.c:2728
int xtensa_init_arch_info(struct target *target, struct xtensa *xtensa, const struct xtensa_debug_module_config *dm_cfg)
Definition: xtensa.c:3397
int xtensa_fetch_all_regs(struct target *target)
Definition: xtensa.c:1214
#define XT_SR_DDR
Definition: xtensa.c:172
#define XT_SR_PS
Definition: xtensa.c:173
#define XT_INS_CALL0(X, IMM18)
Definition: xtensa.c:131
#define XT_INS_L32E_S32E_MASK(X)
Definition: xtensa.c:155
#define XT_REG_A0
Definition: xtensa.c:175
int xtensa_mmu_is_enabled(struct target *target, bool *enabled)
Definition: xtensa.c:1562
int xtensa_watchpoint_remove(struct target *target, struct watchpoint *watchpoint)
Definition: xtensa.c:2708
void xtensa_cause_reset(struct target *target)
Definition: xtensa.c:1158
int xtensa_write_buffer(struct target *target, target_addr_t address, uint32_t count, const uint8_t *buffer)
Definition: xtensa.c:2308
static void xtensa_window_state_restore(struct target *target, uint32_t woe)
Definition: xtensa.c:627
xtensa_mpu_access_type
Types of access rights for MPU option The first block is kernel RWX ARs; the second block is user rwx...
Definition: xtensa.c:311
@ XTENSA_ACC_RWX_000
Definition: xtensa.c:317
@ XTENSA_ACC_RW0_RWX
Definition: xtensa.c:319
@ XTENSA_ACC_RW0_R00
Definition: xtensa.c:320
@ XTENSA_ACC_RW0_000
Definition: xtensa.c:316
@ XTENSA_ACC_R00_R00
Definition: xtensa.c:322
@ XTENSA_ACC_R0X_R0X
Definition: xtensa.c:323
@ XTENSA_ACC_RW0_RW0
Definition: xtensa.c:324
@ XTENSA_ACC_00X_000
Definition: xtensa.c:312
@ XTENSA_ACC_R00_000
Definition: xtensa.c:314
@ XTENSA_ACC_RWX_R0X
Definition: xtensa.c:321
@ XTENSA_ACC_R0X_000
Definition: xtensa.c:315
@ XTENSA_ACC_0W0_0W0
Definition: xtensa.c:318
@ XTENSA_ACC_000_00X
Definition: xtensa.c:313
@ XTENSA_ACC_RWX_RWX
Definition: xtensa.c:325
static void xtensa_queue_exec_ins(struct xtensa *xtensa, uint32_t ins)
Definition: xtensa.c:527
static bool xtensa_is_icacheable(struct xtensa *xtensa, target_addr_t address)
Definition: xtensa.c:415
static int xtensa_window_state_save(struct target *target, uint32_t *woe)
Definition: xtensa.c:596
static bool xtensa_is_cacheable(const struct xtensa_cache_config *cache, const struct xtensa_local_mem_config *mem, target_addr_t address)
Definition: xtensa.c:406
int xtensa_smpbreak_write(struct xtensa *xtensa, uint32_t set)
Definition: xtensa.c:932
int xtensa_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
Definition: xtensa.c:2103
static const struct xtensa_keyval_info xt_qerr[XT_QERR_NUM]
Definition: xtensa.c:334
static int xtensa_imprecise_exception_occurred(struct target *target)
Definition: xtensa.c:990
void xtensa_reg_set(struct target *target, enum xtensa_reg_id reg_id, xtensa_reg_val_t value)
Definition: xtensa.c:1074
void xtensa_cause_clear(struct target *target)
Definition: xtensa.c:1146
#define XT_INS_L32I(X, S, T, IMM8)
Definition: xtensa.c:110
COMMAND_HANDLER(xtensa_cmd_exe)
Definition: xtensa.c:3619
int xtensa_smpbreak_get(struct target *target, uint32_t *val)
Definition: xtensa.c:972
struct xtensa_reg_desc xtensa_regs[XT_NUM_REGS]
Definition: xtensa.c:190
static int xtensa_core_reg_get(struct reg *reg)
Definition: xtensa.c:431
#define XT_INS_PPTLB(X, S, T)
Definition: xtensa.c:162
int xtensa_core_status_check(struct target *target)
Definition: xtensa.c:1021
#define XT_INS_RFR(X, FR, T)
Definition: xtensa.c:149
static int xtensa_update_instruction(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
Definition: xtensa.c:2454
static int32_t xtensa_gdbqc_parse_exec_tie_ops(struct target *target, char *opstr)
Definition: xtensa.c:3117
#define XT_INS_S32E(X, R, S, T)
Definition: xtensa.c:154
int xtensa_do_resume(struct target *target)
Definition: xtensa.c:1660
#define XT_PC_REG_NUM_VIRTUAL
Definition: xtensa.c:182
int xtensa_wakeup(struct target *target)
Definition: xtensa.c:918
static xtensa_reg_val_t xtensa_reg_get_value(struct reg *reg)
Definition: xtensa.c:979
static void xtensa_imprecise_exception_clear(struct target *target)
Definition: xtensa.c:1007
#define XT_PS_REG_NUM
Definition: xtensa.c:179
#define XT_INS_DHWBI(X, S, IMM8)
Definition: xtensa.c:125
static const struct reg_arch_type xtensa_reg_type
Definition: xtensa.c:490
#define XT_INS_RFDO(X)
Definition: xtensa.c:100
static bool xtensa_is_stopped(struct target *target)
Definition: xtensa.c:884
static int xtensa_gdbqc_qxtreg(struct target *target, const char *packet, char **response_p)
Definition: xtensa.c:3148
static int xtensa_write_dirty_registers(struct target *target)
Definition: xtensa.c:663
void xtensa_set_permissive_mode(struct target *target, bool state)
Definition: xtensa.c:3436
#define XT_PC_DBREG_NUM_BASE
Definition: xtensa.c:183
#define XT_INS_WUR(X, UR, T)
Definition: xtensa.c:146
#define XT_INS_JX(X, S)
Definition: xtensa.c:130
int xtensa_deassert_reset(struct target *target)
Definition: xtensa.c:1186
#define XT_INS_RFWU(X)
Definition: xtensa.c:158
int xtensa_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
Definition: xtensa.c:2015
static const struct xtensa_local_mem_config * xtensa_get_mem_config(struct xtensa *xtensa, enum xtensa_mem_region_type type)
Gets a config for the specific mem type.
Definition: xtensa.c:347
static int xtensa_sw_breakpoint_add(struct target *target, struct breakpoint *breakpoint, struct xtensa_sw_breakpoint *sw_bp)
Definition: xtensa.c:2533
static int xtensa_sw_breakpoint_remove(struct target *target, struct xtensa_sw_breakpoint *sw_bp)
Definition: xtensa.c:2559
static const struct xtensa_local_mem_region_config * xtensa_target_memory_region_find(struct xtensa *xtensa, target_addr_t address)
Returns a corresponding xtensa_local_mem_region_config from the xtensa target for a given address Ret...
Definition: xtensa.c:391
int xtensa_soft_reset_halt(struct target *target)
Definition: xtensa.c:1208
#define XT_EPS_REG_NUM_BASE
Definition: xtensa.c:180
static bool xtensa_is_dcacheable(struct xtensa *xtensa, target_addr_t address)
Definition: xtensa.c:423
int xtensa_assert_reset(struct target *target)
Definition: xtensa.c:1165
#define XT_INS_S32I(X, S, T, IMM8)
Definition: xtensa.c:117
#define XT_TLB1_ACC_MSK
Definition: xtensa.c:165
#define XT_INS_LDDR32P(X, S)
Definition: xtensa.c:105
#define XT_EPC_REG_NUM_BASE
Definition: xtensa.c:181
static void xtensa_queue_exec_ins_wide(struct xtensa *xtensa, uint8_t *ops, uint8_t oplen)
Definition: xtensa.c:532
static target_addr_t xtensa_get_overlap_size(target_addr_t r1_start, target_addr_t r1_end, target_addr_t r2_start, target_addr_t r2_end)
Returns a size of overlapped region of two ranges.
Definition: xtensa.c:1979
#define XT_INS_RFWO(X)
Definition: xtensa.c:157
#define XT_REG_A4
Definition: xtensa.c:177
#define XT_INS_DHWB(X, S, IMM8)
Definition: xtensa.c:126
int xtensa_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t entry_point, target_addr_t exit_point, unsigned int timeout_ms, void *arch_info)
Definition: xtensa.c:2933
static const struct xtensa_local_mem_region_config * xtensa_memory_region_find(const struct xtensa_local_mem_config *mem, target_addr_t address)
Extracts an exact xtensa_local_mem_region_config from xtensa_local_mem_config for a given address Ret...
Definition: xtensa.c:374
static int xtensa_build_reg_cache(struct target *target)
Definition: xtensa.c:2956
#define XT_INS_WSR(X, SR, T)
Definition: xtensa.c:136
int xtensa_step(struct target *target, bool current, target_addr_t address, bool handle_breakpoints)
Definition: xtensa.c:1950
int xtensa_resume(struct target *target, bool current, target_addr_t address, bool handle_breakpoints, bool debug_execution)
Definition: xtensa.c:1677
#define XT_INS_RFWO_RFWU_MASK(X)
Definition: xtensa.c:159
xtensa_reg_val_t xtensa_reg_get(struct target *target, enum xtensa_reg_id reg_id)
Definition: xtensa.c:1067
int xtensa_prepare_resume(struct target *target, bool current, target_addr_t address, bool handle_breakpoints, bool debug_execution)
Definition: xtensa.c:1597
int xtensa_wait_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t exit_point, unsigned int timeout_ms, void *arch_info)
Waits for an algorithm in the target.
Definition: xtensa.c:2825
Holds the interface to Xtensa cores.
#define XT_MEM_ACCESS_READ
Definition: xtensa.h:78
xtensa_qerr_e
Definition: xtensa.h:84
@ XT_QERR_FAIL
Definition: xtensa.h:86
@ XT_QERR_INVAL
Definition: xtensa.h:87
@ XT_QERR_MEM
Definition: xtensa.h:88
@ XT_QERR_NUM
Definition: xtensa.h:89
#define XT_PS_WOE_MSK
Definition: xtensa.h:44
#define XT_PS_RING_GET(_v_)
Definition: xtensa.h:41
static struct xtensa * target_to_xtensa(struct target *target)
Definition: xtensa.h:291
static int xtensa_queue_dbg_reg_write(struct xtensa *xtensa, enum xtensa_dm_reg reg, uint32_t data)
Definition: xtensa.h:340
#define XT_AREGS_NUM_MAX
Definition: xtensa.h:74
@ XT_STEPPING_ISR_OFF
Definition: xtensa.h:194
@ XT_STEPPING_ISR_ON
Definition: xtensa.h:195
#define XT_ISNS_SZ_MAX
Definition: xtensa.h:36
#define XT_PS_RING(_v_)
Definition: xtensa.h:39
#define XT_PS_DI_MSK
Definition: xtensa.h:48
@ XT_LX
Definition: xtensa.h:108
@ XT_UNDEF
Definition: xtensa.h:107
@ XT_NX
Definition: xtensa.h:109
#define XT_MEM_ACCESS_WRITE
Definition: xtensa.h:79
#define XT_MESRCLR_IMPR_EXC_MSK
Definition: xtensa.h:70
xtensa_nx_reg_idx
Definition: xtensa.h:198
@ XT_NX_REG_IDX_IEVEC
Definition: xtensa.h:202
@ XT_NX_REG_IDX_MS
Definition: xtensa.h:201
@ XT_NX_REG_IDX_NUM
Definition: xtensa.h:206
@ XT_NX_REG_IDX_MESR
Definition: xtensa.h:204
@ XT_NX_REG_IDX_IBREAKC0
Definition: xtensa.h:199
@ XT_NX_REG_IDX_MESRCLR
Definition: xtensa.h:205
@ XT_NX_REG_IDX_IEEXTERN
Definition: xtensa.h:203
@ XT_NX_REG_IDX_WB
Definition: xtensa.h:200
#define XT_PS_RING_MSK
Definition: xtensa.h:40
#define XT_INS_BREAK(X, S, T)
Definition: xtensa.h:29
xtensa_ar_scratch_set_e
Definition: xtensa.h:93
@ XT_AR_SCRATCH_A3
Definition: xtensa.h:94
@ XT_AR_SCRATCH_AR4
Definition: xtensa.h:97
@ XT_AR_SCRATCH_NUM
Definition: xtensa.h:98
@ XT_AR_SCRATCH_A4
Definition: xtensa.h:96
@ XT_AR_SCRATCH_AR3
Definition: xtensa.h:95
#define XT_INS_BREAKN(X, IMM4)
Definition: xtensa.h:34
xtensa_mode
Definition: xtensa.h:210
@ XT_MODE_ANY
Definition: xtensa.h:215
#define XT_QUERYPKT_RESP_MAX
Definition: xtensa.h:82
#define XTENSA_COMMON_MAGIC
Definition: xtensa.h:237
#define XT_IMPR_EXC_MSK
Definition: xtensa.h:69
#define XT_WB_P_SHIFT
Definition: xtensa.h:56
#define XT_PS_DIEXC_MSK
Definition: xtensa.h:47
#define XT_MS_DISPST_DBG
Definition: xtensa.h:53
#define XT_IBREAKC_FB
Definition: xtensa.h:66
#define XT_WB_P_MSK
Definition: xtensa.h:57
#define XT_WB_S_MSK
Definition: xtensa.h:63
uint32_t xtensa_insn_t
Definition: xtensa.h:191
static int xtensa_queue_dbg_reg_read(struct xtensa *xtensa, enum xtensa_dm_reg reg, uint8_t *data)
Definition: xtensa.h:328
int xtensa_dm_trace_status_read(struct xtensa_debug_module *dm, struct xtensa_trace_status *status)
int xtensa_dm_trace_start(struct xtensa_debug_module *dm, struct xtensa_trace_start_config *cfg)
int xtensa_dm_trace_stop(struct xtensa_debug_module *dm, bool pto_enable)
int xtensa_dm_write(struct xtensa_debug_module *dm, uint32_t addr, uint32_t val)
int xtensa_dm_power_status_read(struct xtensa_debug_module *dm, uint32_t clear)
int xtensa_dm_poll(struct xtensa_debug_module *dm)
int xtensa_dm_perfmon_enable(struct xtensa_debug_module *dm, int counter_id, const struct xtensa_perfmon_config *config)
void xtensa_dm_deinit(struct xtensa_debug_module *dm)
int xtensa_dm_trace_config_read(struct xtensa_debug_module *dm, struct xtensa_trace_config *config)
int xtensa_dm_trace_data_read(struct xtensa_debug_module *dm, uint8_t *dest, uint32_t size)
int xtensa_dm_core_status_clear(struct xtensa_debug_module *dm, xtensa_dsr_t bits)
int xtensa_dm_core_status_read(struct xtensa_debug_module *dm)
int xtensa_dm_queue_enable(struct xtensa_debug_module *dm)
int xtensa_dm_init(struct xtensa_debug_module *dm, const struct xtensa_debug_module_config *cfg)
int xtensa_dm_read(struct xtensa_debug_module *dm, uint32_t addr, uint32_t *val)
int xtensa_dm_perfmon_dump(struct xtensa_debug_module *dm, int counter_id, struct xtensa_perfmon_result *out_result)
#define PWRSTAT_DEBUGWASRESET(x)
#define TRAXADDR_TWRAP_SHIFT
#define OCDDCR_DEBUGMODEOUTEN
static void xtensa_dm_power_status_cache(struct xtensa_debug_module *dm)
#define XTENSA_MAX_PERF_COUNTERS
#define DEBUGCAUSE_DI
#define OCDDSR_DEBUGPENDTRAX
#define TRAXCTRL_TREN
#define OCDDSR_STOPCAUSE_IB
#define OCDDSR_EXECBUSY
#define OCDDCR_BREAKOUTEN
#define DEBUGCAUSE_IB
#define TRAXADDR_TWSAT
#define OCDDCR_ENABLEOCD
#define OCDDCR_STEPREQUEST
#define OCDDSR_DEBUGPENDHOST
#define OCDDSR_STOPCAUSE_DB1
#define OCDDSR_STOPCAUSE_BN
#define DEBUGCAUSE_BI
#define DEBUGCAUSE_IC
uint32_t xtensa_dsr_t
static void xtensa_dm_queue_tdi_idle(struct xtensa_debug_module *dm)
static bool xtensa_dm_core_was_reset(struct xtensa_debug_module *dm)
#define OCDDSR_DEBUGINTTRAX
static xtensa_dsr_t xtensa_dm_core_status_get(struct xtensa_debug_module *dm)
@ XDMREG_PWRCTL
#define TRAXSTAT_CTITG
#define OCDDSR_EXECEXCEPTION
#define TRAXSTAT_PCMTG
#define OCDDSR_STOPCAUSE
#define OCDDSR_STOPCAUSE_B1
static bool xtensa_dm_is_powered(struct xtensa_debug_module *dm)
#define PWRCTL_CORERESET(x)
#define TRAXADDR_TWRAP_MASK
#define OCDDSR_STOPCAUSE_SHIFT
#define OCDDSR_STOPCAUSE_DB0
#define TRAXSTAT_TRACT
#define DEBUGCAUSE_BN
#define XTENSA_MAX_PERF_SELECT
#define OCDDSR_DEBUGINTBREAK
static bool xtensa_dm_tap_was_reset(struct xtensa_debug_module *dm)
#define PWRCTL_MEMWAKEUP(x)
#define TRAXSTAT_PTITG
#define OCDDSR_STOPCAUSE_B
#define PWRCTL_JTAGDEBUGUSE(x)
static int xtensa_dm_queue_execute(struct xtensa_debug_module *dm)
#define OCDDCR_BREAKINEN
@ XDMREG_DCRSET
@ XDMREG_DDREXEC
@ XDMREG_DSR
@ XDMREG_DIR0
@ XDMREG_DDR
@ XDMREG_DCRCLR
@ XDMREG_DIR0EXEC
#define PWRCTL_COREWAKEUP(x)
#define OCDDSR_DEBUGPENDBREAK
static bool xtensa_dm_is_online(struct xtensa_debug_module *dm)
#define OCDDSR_STOPCAUSE_DI
#define OCDDSR_DEBUGINTHOST
#define PWRSTAT_COREWASRESET(x)
#define OCDDCR_DEBUGINTERRUPT
#define PWRCTL_DEBUGWAKEUP(x)
#define DEBUGCAUSE_VALID
#define OCDDSR_EXECOVERRUN
#define XTENSA_STOPMASK_DISABLED
#define OCDDCR_RUNSTALLINEN
#define XTENSA_MAX_PERF_MASK
#define OCDDSR_STOPCAUSE_SS
#define OCDDSR_STOPPED
#define TRAXADDR_TADDR_MASK
#define DEBUGCAUSE_DB
xtensa_reg_id
Definition: xtensa_regs.h:15
@ XT_REG_IDX_AR12
Definition: xtensa_regs.h:30
@ XT_REG_IDX_AR10
Definition: xtensa_regs.h:28
@ XT_REG_IDX_A15
Definition: xtensa_regs.h:66
@ XT_REG_IDX_A0
Definition: xtensa_regs.h:51
@ XT_REG_IDX_AR5
Definition: xtensa_regs.h:23
@ XT_REG_IDX_AR14
Definition: xtensa_regs.h:32
@ XT_REG_IDX_PS
Definition: xtensa_regs.h:37
@ XT_REG_IDX_ARFIRST
Definition: xtensa_regs.h:18
@ XT_REG_IDX_ARLAST
Definition: xtensa_regs.h:34
@ XT_REG_IDX_AR6
Definition: xtensa_regs.h:24
@ XT_REG_IDX_PC
Definition: xtensa_regs.h:16
@ XT_REG_IDX_DEBUGCAUSE
Definition: xtensa_regs.h:48
@ XT_REG_IDX_AR1
Definition: xtensa_regs.h:19
@ XT_REG_IDX_AR15
Definition: xtensa_regs.h:33
@ XT_REG_IDX_A3
Definition: xtensa_regs.h:54
@ XT_REG_IDX_AR0
Definition: xtensa_regs.h:17
@ XT_REG_IDX_ICOUNT
Definition: xtensa_regs.h:49
@ XT_REG_IDX_AR9
Definition: xtensa_regs.h:27
@ XT_REG_IDX_ICOUNTLEVEL
Definition: xtensa_regs.h:50
@ XT_REG_IDX_AR8
Definition: xtensa_regs.h:26
@ XT_REG_IDX_AR2
Definition: xtensa_regs.h:20
@ XT_REG_IDX_AR11
Definition: xtensa_regs.h:29
@ XT_REG_IDX_DBREAKC0
Definition: xtensa_regs.h:44
@ XT_NUM_REGS
Definition: xtensa_regs.h:67
@ XT_REG_IDX_A4
Definition: xtensa_regs.h:55
@ XT_REG_IDX_EXCCAUSE
Definition: xtensa_regs.h:47
@ XT_REG_IDX_AR4
Definition: xtensa_regs.h:22
@ XT_REG_IDX_DBREAKA0
Definition: xtensa_regs.h:42
@ XT_REG_IDX_AR7
Definition: xtensa_regs.h:25
@ XT_REG_IDX_IBREAKENABLE
Definition: xtensa_regs.h:38
@ XT_REG_IDX_WINDOWBASE
Definition: xtensa_regs.h:35
@ XT_REG_IDX_CPENABLE
Definition: xtensa_regs.h:46
@ XT_REG_IDX_AR3
Definition: xtensa_regs.h:21
@ XT_REG_IDX_AR13
Definition: xtensa_regs.h:31
@ XT_REG_IDX_IBREAKA0
Definition: xtensa_regs.h:40
xtensa_reg_type
Definition: xtensa_regs.h:74
@ XT_REG_GENERAL_VAL
Definition: xtensa_regs.h:88
@ XT_REG_RELGEN_MASK
Definition: xtensa_regs.h:95
@ XT_REG_USER
Definition: xtensa_regs.h:76
@ XT_REG_INDEX_MASK
Definition: xtensa_regs.h:104
@ XT_REG_DEBUG
Definition: xtensa_regs.h:78
@ XT_REG_RELGEN
Definition: xtensa_regs.h:79
@ XT_REG_SPECIAL_MASK
Definition: xtensa_regs.h:91
@ XT_REG_SPECIAL_VAL
Definition: xtensa_regs.h:92
@ XT_REG_USER_VAL
Definition: xtensa_regs.h:90
@ XT_REG_FR_VAL
Definition: xtensa_regs.h:98
@ XT_REG_USER_MASK
Definition: xtensa_regs.h:89
@ XT_REG_RELGEN_VAL
Definition: xtensa_regs.h:96
@ XT_REG_GENERAL
Definition: xtensa_regs.h:75
@ XT_REG_GENERAL_MASK
Definition: xtensa_regs.h:87
@ XT_REG_OTHER
Definition: xtensa_regs.h:83
@ XT_REG_SPECIAL
Definition: xtensa_regs.h:77
@ XT_REG_TIE
Definition: xtensa_regs.h:82
@ XT_REG_FR
Definition: xtensa_regs.h:81
@ XT_REG_TIE_MASK
Definition: xtensa_regs.h:99
@ XT_REG_FR_MASK
Definition: xtensa_regs.h:97
@ XT_REGF_COPROC0
Definition: xtensa_regs.h:109
@ XT_REGF_MASK
Definition: xtensa_regs.h:110
@ XT_REGF_NOREAD
Definition: xtensa_regs.h:108
uint32_t xtensa_reg_val_t
Definition: xtensa_regs.h:70
#define XT_MK_REG_DESC(n, r, t, f)
Definition: xtensa_regs.h:128