OpenOCD
xtensa_debug_module.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Xtensa Debug Module (XDM) Support for OpenOCD *
5  * Copyright (C) 2020-2022 Cadence Design Systems, Inc. *
6  * Copyright (C) 2019 Espressif Systems Ltd. *
7  ***************************************************************************/
8 
9 #ifdef HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12 
13 #include <helper/align.h>
14 #include "xtensa_debug_module.h"
15 
16 #define TAPINS_PWRCTL 0x08
17 #define TAPINS_PWRSTAT 0x09
18 #define TAPINS_NARSEL 0x1C
19 #define TAPINS_IDCODE 0x1E
20 #define TAPINS_BYPASS 0x1F
21 
22 #define TAPINS_PWRCTL_LEN 8
23 #define TAPINS_PWRSTAT_LEN 8
24 #define TAPINS_NARSEL_ADRLEN 8
25 #define TAPINS_NARSEL_DATALEN 32
26 #define TAPINS_IDCODE_LEN 32
27 #define TAPINS_BYPASS_LEN 1
28 
29 /* Table of power register offsets for APB space */
32 
33 /* Table of debug register offsets for Nexus and APB space */
34 static const struct xtensa_dm_reg_offsets xdm_regs[XDMREG_NUM] =
36 
37 static enum xtensa_dm_reg xtensa_dm_regaddr_to_id(uint32_t addr)
38 {
39  enum xtensa_dm_reg id;
40  uint32_t addr_masked = (addr & (XTENSA_DM_APB_ALIGN - 1));
41  for (id = XDMREG_TRAXID; id < XDMREG_NUM; id++)
42  if (xdm_regs[id].apb == addr_masked)
43  break;
44  return id;
45 }
46 
47 static void xtensa_dm_add_set_ir(struct xtensa_debug_module *dm, uint8_t value)
48 {
49  struct scan_field field;
50  uint8_t t[4] = { 0, 0, 0, 0 };
51 
52  memset(&field, 0, sizeof(field));
53  field.num_bits = dm->tap->ir_length;
54  field.out_value = t;
55  buf_set_u32(t, 0, field.num_bits, value);
56  jtag_add_ir_scan(dm->tap, &field, TAP_IDLE);
57 }
58 
60  int len,
61  const uint8_t *src,
62  uint8_t *dest,
63  tap_state_t endstate)
64 {
65  struct scan_field field;
66 
67  memset(&field, 0, sizeof(field));
68  field.num_bits = len;
69  field.out_value = src;
70  field.in_value = dest;
71  jtag_add_dr_scan(dm->tap, 1, &field, endstate);
72 }
73 
75 {
76  if (!dm || !cfg)
77  return ERROR_FAIL;
79  LOG_ERROR("Xtensa DM APB offset must be aligned to a %dKB multiple",
80  XTENSA_DM_APB_ALIGN / 1024);
81  return ERROR_FAIL;
82  }
83 
84  dm->pwr_ops = cfg->pwr_ops;
85  dm->dbg_ops = cfg->dbg_ops;
86  dm->tap = cfg->tap;
87  dm->queue_tdi_idle = cfg->queue_tdi_idle;
89  dm->dap = cfg->dap;
90  dm->debug_ap = cfg->debug_ap;
91  dm->debug_apsel = cfg->debug_apsel;
92  dm->ap_offset = cfg->ap_offset;
93  return ERROR_OK;
94 }
95 
97 {
98  if (dm->debug_ap) {
99  dap_put_ap(dm->debug_ap);
100  dm->debug_ap = NULL;
101  }
102 }
103 
105 {
106  /* Check if debug_ap is available to prevent segmentation fault.
107  * If the re-examination after an error does not find a MEM-AP
108  * (e.g. the target stopped communicating), debug_ap pointer
109  * can suddenly become NULL.
110  */
111  return (!dm || (dm->dap && !dm->debug_ap)) ? ERROR_FAIL : ERROR_OK;
112 }
113 
115 {
116  struct adiv5_dap *swjdp = dm->dap;
117  int retval = ERROR_OK;
118 
119  if (swjdp) {
120  LOG_DEBUG("DM examine: DAP AP select %d", dm->debug_apsel);
121  if (dm->debug_ap) {
122  dap_put_ap(dm->debug_ap);
123  dm->debug_ap = NULL;
124  }
125  if (dm->debug_apsel == DP_APSEL_INVALID) {
126  LOG_DEBUG("DM examine: search for APB-type MEM-AP...");
127  /* TODO: Determine whether AP_TYPE_AXI_AP APs can be supported... */
128  retval = dap_find_get_ap(swjdp, AP_TYPE_APB_AP, &dm->debug_ap);
129  if (retval != ERROR_OK) {
130  LOG_ERROR("Could not find MEM-AP to control the core");
131  return retval;
132  }
133  } else {
134  dm->debug_ap = dap_get_ap(swjdp, dm->debug_apsel);
135  }
136 
137  /* TODO: Allow a user-specified AP instead of relying on AP_TYPE_APB_AP */
138  dm->debug_apsel = dm->debug_ap->ap_num;
139  LOG_DEBUG("DM examine: Setting apsel to %d", dm->debug_apsel);
140 
141  /* Leave (only) generic DAP stuff for debugport_init(); */
142  dm->debug_ap->memaccess_tck = 8;
143 
144  retval = mem_ap_init(dm->debug_ap);
145  if (retval != ERROR_OK) {
146  LOG_ERROR("MEM-AP init failed: %d", retval);
147  return retval;
148  }
149 
150  /* TODO: how to set autoincrement range? Hard-code it to 1024 bytes for now */
151  dm->debug_ap->tar_autoincr_block = (1 << 10);
152  }
153 
154  return retval;
155 }
156 
158 {
160 }
161 
162 int xtensa_dm_queue_reg_read(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint8_t *value)
163 {
164  if (reg >= XDMREG_NUM) {
165  LOG_ERROR("Invalid DBG reg ID %d!", reg);
166  return ERROR_FAIL;
167  }
168  if (dm->dap)
169  /* NOTE: Future optimization: mem_ap_read_u32() offers higher performance with
170  * queued reads, but requires an API change to pass value as a 32-bit pointer.
171  */
172  return mem_ap_read_buf(dm->debug_ap, value, 4, 1, xdm_regs[reg].apb + dm->ap_offset);
173  uint8_t regdata = (xdm_regs[reg].nar << 1) | 0;
174  uint8_t dummy[4] = { 0, 0, 0, 0 };
178  return ERROR_OK;
179 }
180 
181 int xtensa_dm_queue_reg_write(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint32_t value)
182 {
183  if (reg >= XDMREG_NUM) {
184  LOG_ERROR("Invalid DBG reg ID %d!", reg);
185  return ERROR_FAIL;
186  }
187  if (dm->dap)
188  return mem_ap_write_u32(dm->debug_ap, xdm_regs[reg].apb + dm->ap_offset, value);
189  uint8_t regdata = (xdm_regs[reg].nar << 1) | 1;
190  uint8_t valdata[] = { value, value >> 8, value >> 16, value >> 24 };
194  return ERROR_OK;
195 }
196 
198  enum xtensa_dm_pwr_reg reg,
199  uint8_t *data,
200  uint32_t clear)
201 {
202  if (reg >= XDMREG_PWRNUM) {
203  LOG_ERROR("Invalid PWR reg ID %d!", reg);
204  return ERROR_FAIL;
205  }
206  if (dm->dap) {
207  /* NOTE: Future optimization: mem_ap_read_u32() offers higher performance with
208  * queued reads, but requires an API change to pass value as a 32-bit pointer.
209  */
210  uint32_t apbreg = xdm_pwr_regs[reg].apb + dm->ap_offset;
211  int retval = mem_ap_read_buf(dm->debug_ap, data, 4, 1, apbreg);
212  if (retval == ERROR_OK)
213  retval = mem_ap_write_u32(dm->debug_ap, apbreg, clear);
214  return retval;
215  }
216  uint8_t value_clr = (uint8_t)clear;
217  uint8_t tap_insn = (reg == XDMREG_PWRCTL) ? TAPINS_PWRCTL : TAPINS_PWRSTAT;
218  int tap_insn_sz = (reg == XDMREG_PWRCTL) ? TAPINS_PWRCTL_LEN : TAPINS_PWRSTAT_LEN;
219  xtensa_dm_add_set_ir(dm, tap_insn);
220  xtensa_dm_add_dr_scan(dm, tap_insn_sz, &value_clr, data, TAP_IDLE);
221  return ERROR_OK;
222 }
223 
225  enum xtensa_dm_pwr_reg reg,
226  uint32_t data)
227 {
228  if (reg >= XDMREG_PWRNUM) {
229  LOG_ERROR("Invalid PWR reg ID %d!", reg);
230  return ERROR_FAIL;
231  }
232  if (dm->dap) {
233  uint32_t apbreg = xdm_pwr_regs[reg].apb + dm->ap_offset;
234  return mem_ap_write_u32(dm->debug_ap, apbreg, data);
235  }
236  uint8_t tap_insn = (reg == XDMREG_PWRCTL) ? TAPINS_PWRCTL : TAPINS_PWRSTAT;
237  int tap_insn_sz = (reg == XDMREG_PWRCTL) ? TAPINS_PWRCTL_LEN : TAPINS_PWRSTAT_LEN;
238  uint8_t value = (uint8_t)data;
239  xtensa_dm_add_set_ir(dm, tap_insn);
240  xtensa_dm_add_dr_scan(dm, tap_insn_sz, &value, NULL, TAP_IDLE);
241  return ERROR_OK;
242 }
243 
245 {
246  uint8_t id_buf[sizeof(uint32_t)];
247 
248  dm->dbg_ops->queue_reg_read(dm, XDMREG_OCDID, id_buf);
250  int res = xtensa_dm_queue_execute(dm);
251  if (res != ERROR_OK)
252  return res;
253  dm->device_id = buf_get_u32(id_buf, 0, 32);
254  return ERROR_OK;
255 }
256 
257 int xtensa_dm_power_status_read(struct xtensa_debug_module *dm, uint32_t clear)
258 {
259  uint8_t stat_buf[sizeof(uint32_t)] = { 0, 0, 0, 0 };
260  uint8_t stath_buf[sizeof(uint32_t)] = { 0, 0, 0, 0 };
261 
262  /* TODO: JTAG does not work when PWRCTL_JTAGDEBUGUSE is not set.
263  * It is set in xtensa_examine(), need to move reading of XDMREG_OCDID out of this function */
264  /* dm->dbg_ops->queue_reg_read(dm, XDMREG_OCDID, id_buf);
265  *Read reset state */
266  dm->pwr_ops->queue_reg_read(dm, XDMREG_PWRSTAT, stat_buf, clear);
267  dm->pwr_ops->queue_reg_read(dm, XDMREG_PWRSTAT, stath_buf, clear);
269  int res = xtensa_dm_queue_execute(dm);
270  if (res != ERROR_OK)
271  return res;
272  dm->power_status.stat = buf_get_u32(stat_buf, 0, 32);
273  dm->power_status.stath = buf_get_u32(stath_buf, 0, 32);
274  return res;
275 }
276 
278 {
279  uint8_t dsr_buf[sizeof(uint32_t)];
280 
282  dm->dbg_ops->queue_reg_read(dm, XDMREG_DSR, dsr_buf);
284  int res = xtensa_dm_queue_execute(dm);
285  if (res != ERROR_OK)
286  return res;
287  dm->core_status.dsr = buf_get_u32(dsr_buf, 0, 32);
288  return res;
289 }
290 
292 {
295  return xtensa_dm_queue_execute(dm);
296 }
297 
298 int xtensa_dm_read(struct xtensa_debug_module *dm, uint32_t addr, uint32_t *val)
299 {
301  uint8_t buf[sizeof(uint32_t)];
302  if (reg < XDMREG_NUM) {
304  dm->dbg_ops->queue_reg_read(dm, reg, buf);
306  int res = xtensa_dm_queue_execute(dm);
307  if (res == ERROR_OK && val)
308  *val = buf_get_u32(buf, 0, 32);
309  return res;
310  }
311  return ERROR_FAIL;
312 }
313 
314 int xtensa_dm_write(struct xtensa_debug_module *dm, uint32_t addr, uint32_t val)
315 {
317  if (reg < XDMREG_NUM) {
319  dm->dbg_ops->queue_reg_write(dm, reg, val);
321  return xtensa_dm_queue_execute(dm);
322  }
323  return ERROR_FAIL;
324 }
325 
327 {
328  /*Turn off trace unit so we can start a new trace. */
331  int res = xtensa_dm_queue_execute(dm);
332  if (res != ERROR_OK)
333  return res;
334 
335  /*Set up parameters */
337  if (cfg->stopmask != XTENSA_STOPMASK_DISABLED) {
339  (cfg->stopmask << PCMATCHCTRL_PCML_SHIFT));
341  }
343  /*Options are mostly hardcoded for now. ToDo: make this more configurable. */
345  dm,
347  TRAXCTRL_TREN |
351  return xtensa_dm_queue_execute(dm);
352 }
353 
354 int xtensa_dm_trace_stop(struct xtensa_debug_module *dm, bool pto_enable)
355 {
356  uint8_t traxctl_buf[sizeof(uint32_t)];
357  uint32_t traxctl;
359 
360  dm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXCTRL, traxctl_buf);
362  int res = xtensa_dm_queue_execute(dm);
363  if (res != ERROR_OK)
364  return res;
365  traxctl = buf_get_u32(traxctl_buf, 0, 32);
366 
367  if (!pto_enable)
368  traxctl &= ~(TRAXCTRL_PTOWS | TRAXCTRL_PTOWT);
369 
372  res = xtensa_dm_queue_execute(dm);
373  if (res != ERROR_OK)
374  return res;
375 
376  /*Check current status of trace hardware */
378  if (res != ERROR_OK)
379  return res;
380 
381  if (trace_status.stat & TRAXSTAT_TRACT) {
382  LOG_ERROR("Failed to stop tracing (0x%x)!", trace_status.stat);
383  return ERROR_FAIL;
384  }
385  return ERROR_OK;
386 }
387 
389 {
390  uint8_t traxstat_buf[sizeof(uint32_t)];
391 
392  dm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXSTAT, traxstat_buf);
394  int res = xtensa_dm_queue_execute(dm);
395  if (res == ERROR_OK && status)
396  status->stat = buf_get_u32(traxstat_buf, 0, 32);
397  return res;
398 }
399 
401 {
402  uint8_t traxctl_buf[sizeof(uint32_t)];
403  uint8_t memadrstart_buf[sizeof(uint32_t)];
404  uint8_t memadrend_buf[sizeof(uint32_t)];
405  uint8_t adr_buf[sizeof(uint32_t)];
406 
407  if (!config)
408  return ERROR_FAIL;
409 
410  dm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXCTRL, traxctl_buf);
411  dm->dbg_ops->queue_reg_read(dm, XDMREG_MEMADDRSTART, memadrstart_buf);
412  dm->dbg_ops->queue_reg_read(dm, XDMREG_MEMADDREND, memadrend_buf);
413  dm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXADDR, adr_buf);
415  int res = xtensa_dm_queue_execute(dm);
416  if (res == ERROR_OK) {
417  config->ctrl = buf_get_u32(traxctl_buf, 0, 32);
418  config->memaddr_start = buf_get_u32(memadrstart_buf, 0, 32);
419  config->memaddr_end = buf_get_u32(memadrend_buf, 0, 32);
420  config->addr = buf_get_u32(adr_buf, 0, 32);
421  }
422  return res;
423 }
424 
425 int xtensa_dm_trace_data_read(struct xtensa_debug_module *dm, uint8_t *dest, uint32_t size)
426 {
427  if (!dest)
428  return ERROR_FAIL;
429 
430  for (unsigned int i = 0; i < size / 4; i++)
431  dm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXDATA, &dest[i * 4]);
433  return xtensa_dm_queue_execute(dm);
434 }
435 
436 int xtensa_dm_perfmon_enable(struct xtensa_debug_module *dm, int counter_id,
437  const struct xtensa_perfmon_config *config)
438 {
439  if (!config)
440  return ERROR_FAIL;
441 
442  uint8_t pmstat_buf[4];
443  uint32_t pmctrl = ((config->tracelevel) << 4) +
444  (config->select << 8) +
445  (config->mask << 16) +
446  (config->kernelcnt << 3);
447 
448  /* enable performance monitor */
449  dm->dbg_ops->queue_reg_write(dm, XDMREG_PMG, 0x1);
450  /* reset counter */
451  dm->dbg_ops->queue_reg_write(dm, XDMREG_PM0 + counter_id, 0);
452  dm->dbg_ops->queue_reg_write(dm, XDMREG_PMCTRL0 + counter_id, pmctrl);
453  dm->dbg_ops->queue_reg_read(dm, XDMREG_PMSTAT0 + counter_id, pmstat_buf);
455  return xtensa_dm_queue_execute(dm);
456 }
457 
458 int xtensa_dm_perfmon_dump(struct xtensa_debug_module *dm, int counter_id,
459  struct xtensa_perfmon_result *out_result)
460 {
461  uint8_t pmstat_buf[4];
462  uint8_t pmcount_buf[4];
463 
464  dm->dbg_ops->queue_reg_read(dm, XDMREG_PMSTAT0 + counter_id, pmstat_buf);
465  dm->dbg_ops->queue_reg_read(dm, XDMREG_PM0 + counter_id, pmcount_buf);
467  int res = xtensa_dm_queue_execute(dm);
468  if (res == ERROR_OK) {
469  uint32_t stat = buf_get_u32(pmstat_buf, 0, 32);
470  uint64_t result = buf_get_u32(pmcount_buf, 0, 32);
471 
472  /* TODO: if counter # counter_id+1 has 'select' set to 1, use its value as the
473  * high 32 bits of the counter. */
474  if (out_result) {
475  out_result->overflow = ((stat & 1) != 0);
476  out_result->value = result;
477  }
478  }
479 
480  return res;
481 }
#define IS_ALIGNED(x, a)
Definition: align.h:22
int mem_ap_read_buf(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint32_t count, target_addr_t address)
Definition: arm_adi_v5.c:722
int mem_ap_write_u32(struct adiv5_ap *ap, target_addr_t address, uint32_t value)
Asynchronous (queued) write of a word to memory or a system register.
Definition: arm_adi_v5.c:289
int dap_find_get_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_ap **ap_out)
Definition: arm_adi_v5.c:1106
struct adiv5_ap * dap_get_ap(struct adiv5_dap *dap, uint64_t ap_num)
Definition: arm_adi_v5.c:1188
int dap_put_ap(struct adiv5_ap *ap)
Definition: arm_adi_v5.c:1208
int mem_ap_init(struct adiv5_ap *ap)
Initialize a DAP.
Definition: arm_adi_v5.c:887
@ AP_TYPE_APB_AP
Definition: arm_adi_v5.h:491
#define DP_APSEL_INVALID
Definition: arm_adi_v5.h:110
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned first, unsigned num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
Definition: binarybuffer.h:99
static void buf_set_u32(uint8_t *_buffer, unsigned first, unsigned num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:31
void jtag_add_ir_scan(struct jtag_tap *active, struct scan_field *in_fields, tap_state_t state)
Generate an IR SCAN with a list of scan fields with one entry for each enabled TAP.
Definition: jtag/core.c:374
void jtag_add_dr_scan(struct jtag_tap *active, int in_num_fields, const struct scan_field *in_fields, tap_state_t state)
Generate a DR SCAN using the fields passed to the function.
Definition: jtag/core.c:451
@ TAP_IDLE
Definition: jtag.h:53
enum tap_state tap_state_t
Defines JTAG Test Access Port states.
#define ERROR_FAIL
Definition: log.h:170
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:164
uint8_t bits[QN908X_FLASH_MAX_BLOCKS *QN908X_FLASH_PAGES_PER_BLOCK/8]
Definition: qn908x.c:0
target_addr_t addr
Start address to search for the control block.
Definition: rtt/rtt.c:28
size_t size
Size of the control block search area.
Definition: rtt/rtt.c:30
char id[RTT_CB_MAX_ID_LENGTH]
Control block identifier.
Definition: rtt/rtt.c:32
uint32_t tar_autoincr_block
Definition: arm_adi_v5.h:309
uint64_t ap_num
ADIv5: Number of this AP (0~255) ADIv6: Base address of this AP (4k aligned) TODO: to be more coheren...
Definition: arm_adi_v5.h:261
uint32_t memaccess_tck
Configures how many extra tck clocks are added after starting a MEM-AP access before we try to read i...
Definition: arm_adi_v5.h:306
This represents an ARM Debug Interface (v5) Debug Access Port (DAP).
Definition: arm_adi_v5.h:348
int ir_length
size of instruction register
Definition: jtag.h:110
Definition: register.h:111
This structure defines a single scan field in the scan.
Definition: jtag.h:87
int num_bits
The number of bits this field specifies.
Definition: jtag.h:89
uint8_t * in_value
A pointer to a 32-bit memory location for data scanned out.
Definition: jtag.h:93
const uint8_t * out_value
A pointer to value to be scanned into the device.
Definition: jtag.h:91
void(* queue_tdi_idle)(struct target *target)
const struct xtensa_debug_ops * dbg_ops
const struct xtensa_power_ops * pwr_ops
struct xtensa_power_status power_status
void(* queue_tdi_idle)(struct target *target)
const struct xtensa_power_ops * pwr_ops
struct jtag_tap * tap
struct xtensa_core_status core_status
struct adiv5_dap * dap
const struct xtensa_debug_ops * dbg_ops
struct adiv5_ap * debug_ap
int(* queue_reg_write)(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint32_t data)
register write.
int(* queue_reg_read)(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint8_t *data)
register read.
int(* queue_reg_read)(struct xtensa_debug_module *dm, enum xtensa_dm_pwr_reg reg, uint8_t *data, uint32_t clear)
register read.
xtensa_pwrstat_t stath
xtensa_traxstat_t stat
trace_status
Definition: trace.h:36
#define NULL
Definition: usb.h:16
uint8_t status[4]
Definition: vdebug.c:17
uint8_t dummy[96]
Definition: vdebug.c:23
static void xtensa_dm_add_set_ir(struct xtensa_debug_module *dm, uint8_t value)
#define TAPINS_PWRCTL
int xtensa_dm_trace_status_read(struct xtensa_debug_module *dm, struct xtensa_trace_status *status)
static void xtensa_dm_add_dr_scan(struct xtensa_debug_module *dm, int len, const uint8_t *src, uint8_t *dest, tap_state_t endstate)
int xtensa_dm_queue_reg_read(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint8_t *value)
int xtensa_dm_queue_pwr_reg_write(struct xtensa_debug_module *dm, enum xtensa_dm_pwr_reg reg, uint32_t data)
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_device_id_read(struct xtensa_debug_module *dm)
int xtensa_dm_queue_pwr_reg_read(struct xtensa_debug_module *dm, enum xtensa_dm_pwr_reg reg, uint8_t *data, uint32_t clear)
#define TAPINS_NARSEL
static const struct xtensa_dm_reg_offsets xdm_regs[XDMREG_NUM]
int xtensa_dm_write(struct xtensa_debug_module *dm, uint32_t addr, uint32_t val)
int xtensa_dm_queue_reg_write(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint32_t value)
#define TAPINS_PWRSTAT_LEN
static enum xtensa_dm_reg xtensa_dm_regaddr_to_id(uint32_t addr)
int xtensa_dm_power_status_read(struct xtensa_debug_module *dm, uint32_t clear)
int xtensa_dm_poll(struct xtensa_debug_module *dm)
static const struct xtensa_dm_pwr_reg_offsets xdm_pwr_regs[XDMREG_PWRNUM]
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)
#define TAPINS_NARSEL_DATALEN
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)
#define TAPINS_PWRSTAT
int xtensa_dm_queue_enable(struct xtensa_debug_module *dm)
#define TAPINS_PWRCTL_LEN
int xtensa_dm_init(struct xtensa_debug_module *dm, const struct xtensa_debug_module_config *cfg)
int xtensa_dm_examine(struct xtensa_debug_module *dm)
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 TAPINS_NARSEL_ADRLEN
#define TRAXCTRL_TMEN
#define TRAXCTRL_PTOWT
#define TRAXCTRL_TREN
#define TRAXCTRL_PTOWS
#define XTENSA_DM_REG_OFFSETS
#define OCDDCR_ENABLEOCD
uint32_t xtensa_dsr_t
static void xtensa_dm_queue_tdi_idle(struct xtensa_debug_module *dm)
#define TRAXCTRL_SMPER_SHIFT
xtensa_dm_pwr_reg
@ XDMREG_PWRNUM
@ XDMREG_PWRSTAT
@ XDMREG_PWRCTL
#define TRAXCTRL_PCMEN
#define TRAXSTAT_TRACT
static int xtensa_dm_queue_execute(struct xtensa_debug_module *dm)
xtensa_dm_reg
@ XDMREG_DCRSET
@ XDMREG_PCMATCHCTRL
@ XDMREG_TRAXDATA
@ XDMREG_TRAXADDR
@ XDMREG_TRAXSTAT
@ XDMREG_DELAYCNT
@ XDMREG_MEMADDREND
@ XDMREG_PMCTRL0
@ XDMREG_DSR
@ XDMREG_TRAXID
@ XDMREG_NUM
@ XDMREG_PM0
@ XDMREG_TRIGGERPC
@ XDMREG_TRAXCTRL
@ XDMREG_PMSTAT0
@ XDMREG_OCDID
@ XDMREG_MEMADDRSTART
@ XDMREG_PMG
#define PCMATCHCTRL_PCML_SHIFT
#define TRAXCTRL_CNTU
#define XTENSA_DM_APB_ALIGN
#define XTENSA_STOPMASK_DISABLED
#define XTENSA_DM_PWR_REG_OFFSETS
#define TRAXCTRL_TRSTP