target/xtensa: virtualize XDM registers
[openocd.git] / src / target / xtensa / xtensa.h
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /***************************************************************************
4 * Generic Xtensa target *
5 * Copyright (C) 2020-2022 Cadence Design Systems, Inc. *
6 * Copyright (C) 2019 Espressif Systems Ltd. *
7 ***************************************************************************/
8
9 #ifndef OPENOCD_TARGET_XTENSA_H
10 #define OPENOCD_TARGET_XTENSA_H
11
12 #include "assert.h"
13 #include <target/target.h>
14 #include <target/breakpoints.h>
15 #include "xtensa_regs.h"
16 #include "xtensa_debug_module.h"
17
18 /**
19 * @file
20 * Holds the interface to Xtensa cores.
21 */
22
23 /* Big-endian vs. little-endian detection */
24 #define XT_ISBE(X) ((X)->target->endianness == TARGET_BIG_ENDIAN)
25
26 /* 24-bit break; BE version field-swapped then byte-swapped for use in memory R/W fns */
27 #define XT_INS_BREAK_LE(S, T) (0x004000 | (((S) & 0xF) << 8) | (((T) & 0xF) << 4))
28 #define XT_INS_BREAK_BE(S, T) (0x000400 | (((S) & 0xF) << 12) | ((T) & 0xF))
29 #define XT_INS_BREAK(X, S, T) (XT_ISBE(X) ? XT_INS_BREAK_BE(S, T) : XT_INS_BREAK_LE(S, T))
30
31 /* 16-bit break; BE version field-swapped then byte-swapped for use in memory R/W fns */
32 #define XT_INS_BREAKN_LE(IMM4) (0xF02D | (((IMM4) & 0xF) << 8))
33 #define XT_INS_BREAKN_BE(IMM4) (0x0FD2 | (((IMM4) & 0xF) << 12))
34 #define XT_INS_BREAKN(X, IMM4) (XT_ISBE(X) ? XT_INS_BREAKN_BE(IMM4) : XT_INS_BREAKN_LE(IMM4))
35
36 #define XT_ISNS_SZ_MAX 3
37
38 #define XT_PS_RING(_v_) ((uint32_t)((_v_) & 0x3) << 6)
39 #define XT_PS_RING_MSK (0x3 << 6)
40 #define XT_PS_RING_GET(_v_) (((_v_) >> 6) & 0x3)
41 #define XT_PS_CALLINC_MSK (0x3 << 16)
42 #define XT_PS_OWB_MSK (0xF << 8)
43 #define XT_PS_WOE_MSK BIT(18)
44
45 #define XT_LOCAL_MEM_REGIONS_NUM_MAX 8
46
47 #define XT_AREGS_NUM_MAX 64
48 #define XT_USER_REGS_NUM_MAX 256
49
50 #define XT_MEM_ACCESS_NONE 0x0
51 #define XT_MEM_ACCESS_READ 0x1
52 #define XT_MEM_ACCESS_WRITE 0x2
53
54 #define XT_MAX_TIE_REG_WIDTH (512) /* TIE register file max 4096 bits */
55 #define XT_QUERYPKT_RESP_MAX (XT_MAX_TIE_REG_WIDTH * 2 + 1)
56
57 enum xtensa_qerr_e {
58 XT_QERR_INTERNAL = 0,
59 XT_QERR_FAIL,
60 XT_QERR_INVAL,
61 XT_QERR_MEM,
62 XT_QERR_NUM,
63 };
64
65 /* An and ARn registers potentially used as scratch regs */
66 enum xtensa_ar_scratch_set_e {
67 XT_AR_SCRATCH_A3 = 0,
68 XT_AR_SCRATCH_AR3,
69 XT_AR_SCRATCH_A4,
70 XT_AR_SCRATCH_AR4,
71 XT_AR_SCRATCH_NUM
72 };
73
74 struct xtensa_keyval_info_s {
75 char *chrval;
76 int intval;
77 };
78
79 enum xtensa_type {
80 XT_UNDEF = 0,
81 XT_LX,
82 };
83
84 struct xtensa_cache_config {
85 uint8_t way_count;
86 uint32_t line_size;
87 uint32_t size;
88 int writeback;
89 };
90
91 struct xtensa_local_mem_region_config {
92 target_addr_t base;
93 uint32_t size;
94 int access;
95 };
96
97 struct xtensa_local_mem_config {
98 uint16_t count;
99 struct xtensa_local_mem_region_config regions[XT_LOCAL_MEM_REGIONS_NUM_MAX];
100 };
101
102 struct xtensa_mmu_config {
103 bool enabled;
104 uint8_t itlb_entries_count;
105 uint8_t dtlb_entries_count;
106 };
107
108 struct xtensa_mpu_config {
109 bool enabled;
110 uint8_t nfgseg;
111 uint32_t minsegsize;
112 bool lockable;
113 bool execonly;
114 };
115
116 struct xtensa_irq_config {
117 bool enabled;
118 uint8_t irq_num;
119 };
120
121 struct xtensa_high_prio_irq_config {
122 bool enabled;
123 uint8_t level_num;
124 uint8_t excm_level;
125 };
126
127 struct xtensa_debug_config {
128 bool enabled;
129 uint8_t irq_level;
130 uint8_t ibreaks_num;
131 uint8_t dbreaks_num;
132 uint8_t perfcount_num;
133 };
134
135 struct xtensa_tracing_config {
136 bool enabled;
137 uint32_t mem_sz;
138 bool reversed_mem_access;
139 };
140
141 struct xtensa_config {
142 enum xtensa_type core_type;
143 uint8_t aregs_num;
144 bool windowed;
145 bool coproc;
146 bool exceptions;
147 struct xtensa_irq_config irq;
148 struct xtensa_high_prio_irq_config high_irq;
149 struct xtensa_mmu_config mmu;
150 struct xtensa_mpu_config mpu;
151 struct xtensa_debug_config debug;
152 struct xtensa_tracing_config trace;
153 struct xtensa_cache_config icache;
154 struct xtensa_cache_config dcache;
155 struct xtensa_local_mem_config irom;
156 struct xtensa_local_mem_config iram;
157 struct xtensa_local_mem_config drom;
158 struct xtensa_local_mem_config dram;
159 struct xtensa_local_mem_config sram;
160 struct xtensa_local_mem_config srom;
161 };
162
163 typedef uint32_t xtensa_insn_t;
164
165 enum xtensa_stepping_isr_mode {
166 XT_STEPPING_ISR_OFF, /* interrupts are disabled during stepping */
167 XT_STEPPING_ISR_ON, /* interrupts are enabled during stepping */
168 };
169
170 /* Only supported in cores with in-CPU MMU. None of Espressif chips as of now. */
171 enum xtensa_mode {
172 XT_MODE_RING0,
173 XT_MODE_RING1,
174 XT_MODE_RING2,
175 XT_MODE_RING3,
176 XT_MODE_ANY /* special value to run algorithm in current core mode */
177 };
178
179 struct xtensa_sw_breakpoint {
180 struct breakpoint *oocd_bp;
181 /* original insn */
182 uint8_t insn[XT_ISNS_SZ_MAX];
183 /* original insn size */
184 uint8_t insn_sz; /* 2 or 3 bytes */
185 };
186
187 #define XTENSA_COMMON_MAGIC 0x54E4E555U
188
189 /**
190 * Represents a generic Xtensa core.
191 */
192 struct xtensa {
193 unsigned int common_magic;
194 struct xtensa_chip_common *xtensa_chip;
195 struct xtensa_config *core_config;
196 struct xtensa_debug_module dbg_mod;
197 struct reg_cache *core_cache;
198 unsigned int total_regs_num;
199 unsigned int core_regs_num;
200 bool regmap_contiguous;
201 unsigned int genpkt_regs_num;
202 struct xtensa_reg_desc **contiguous_regs_desc;
203 struct reg **contiguous_regs_list;
204 /* Per-config Xtensa registers as specified via "xtreg" in xtensa-core*.cfg */
205 struct xtensa_reg_desc *optregs;
206 unsigned int num_optregs;
207 struct reg *empty_regs;
208 char qpkt_resp[XT_QUERYPKT_RESP_MAX];
209 /* An array of pointers to buffers to backup registers' values while algo is run on target.
210 * Size is 'regs_num'. */
211 void **algo_context_backup;
212 unsigned int eps_dbglevel_idx;
213 unsigned int dbregs_num;
214 struct target *target;
215 bool reset_asserted;
216 enum xtensa_stepping_isr_mode stepping_isr_mode;
217 struct breakpoint **hw_brps;
218 struct watchpoint **hw_wps;
219 struct xtensa_sw_breakpoint *sw_brps;
220 bool trace_active;
221 bool permissive_mode; /* bypass memory checks */
222 bool suppress_dsr_errors;
223 uint32_t smp_break;
224 uint32_t spill_loc;
225 unsigned int spill_bytes;
226 uint8_t *spill_buf;
227 int8_t probe_lsddr32p;
228 /* Sometimes debug module's 'powered' bit is cleared after reset, but get set after some
229 * time.This is the number of polling periods after which core is considered to be powered
230 * off (marked as unexamined) if the bit retains to be cleared (e.g. if core is disabled by
231 * SW running on target).*/
232 uint8_t come_online_probes_num;
233 bool proc_syscall;
234 bool halt_request;
235 struct xtensa_keyval_info_s scratch_ars[XT_AR_SCRATCH_NUM];
236 bool regs_fetched; /* true after first register fetch completed successfully */
237 };
238
239 static inline struct xtensa *target_to_xtensa(struct target *target)
240 {
241 assert(target);
242 struct xtensa *xtensa = target->arch_info;
243 assert(xtensa->common_magic == XTENSA_COMMON_MAGIC);
244 return xtensa;
245 }
246
247 int xtensa_init_arch_info(struct target *target,
248 struct xtensa *xtensa,
249 const struct xtensa_debug_module_config *dm_cfg);
250 int xtensa_target_init(struct command_context *cmd_ctx, struct target *target);
251 void xtensa_target_deinit(struct target *target);
252
253 static inline bool xtensa_addr_in_mem(const struct xtensa_local_mem_config *mem, uint32_t addr)
254 {
255 for (unsigned int i = 0; i < mem->count; i++) {
256 if (addr >= mem->regions[i].base &&
257 addr < mem->regions[i].base + mem->regions[i].size)
258 return true;
259 }
260 return false;
261 }
262
263 static inline bool xtensa_data_addr_valid(struct target *target, uint32_t addr)
264 {
265 struct xtensa *xtensa = target_to_xtensa(target);
266
267 if (xtensa_addr_in_mem(&xtensa->core_config->drom, addr))
268 return true;
269 if (xtensa_addr_in_mem(&xtensa->core_config->dram, addr))
270 return true;
271 if (xtensa_addr_in_mem(&xtensa->core_config->sram, addr))
272 return true;
273 return false;
274 }
275
276 static inline int xtensa_queue_dbg_reg_read(struct xtensa *xtensa, enum xtensa_dm_reg reg, uint8_t *data)
277 {
278 struct xtensa_debug_module *dm = &xtensa->dbg_mod;
279
280 if (!xtensa->core_config->trace.enabled &&
281 (reg <= XDMREG_MEMADDREND || (reg >= XDMREG_PMG && reg <= XDMREG_PMSTAT7))) {
282 LOG_ERROR("Can not access %u reg when Trace Port option disabled!", reg);
283 return ERROR_FAIL;
284 }
285 return dm->dbg_ops->queue_reg_read(dm, reg, data);
286 }
287
288 static inline int xtensa_queue_dbg_reg_write(struct xtensa *xtensa, enum xtensa_dm_reg reg, uint32_t data)
289 {
290 struct xtensa_debug_module *dm = &xtensa->dbg_mod;
291
292 if (!xtensa->core_config->trace.enabled &&
293 (reg <= XDMREG_MEMADDREND || (reg >= XDMREG_PMG && reg <= XDMREG_PMSTAT7))) {
294 LOG_ERROR("Can not access %u reg when Trace Port option disabled!", reg);
295 return ERROR_FAIL;
296 }
297 return dm->dbg_ops->queue_reg_write(dm, reg, data);
298 }
299
300 static inline int xtensa_core_status_clear(struct target *target, uint32_t bits)
301 {
302 struct xtensa *xtensa = target_to_xtensa(target);
303 return xtensa_dm_core_status_clear(&xtensa->dbg_mod, bits);
304 }
305
306 int xtensa_core_status_check(struct target *target);
307
308 int xtensa_examine(struct target *target);
309 int xtensa_wakeup(struct target *target);
310 int xtensa_smpbreak_set(struct target *target, uint32_t set);
311 int xtensa_smpbreak_get(struct target *target, uint32_t *val);
312 int xtensa_smpbreak_write(struct xtensa *xtensa, uint32_t set);
313 int xtensa_smpbreak_read(struct xtensa *xtensa, uint32_t *val);
314 xtensa_reg_val_t xtensa_reg_get(struct target *target, enum xtensa_reg_id reg_id);
315 void xtensa_reg_set(struct target *target, enum xtensa_reg_id reg_id, xtensa_reg_val_t value);
316 void xtensa_reg_set_deep_relgen(struct target *target, enum xtensa_reg_id a_idx, xtensa_reg_val_t value);
317 int xtensa_fetch_all_regs(struct target *target);
318 int xtensa_get_gdb_reg_list(struct target *target,
319 struct reg **reg_list[],
320 int *reg_list_size,
321 enum target_register_class reg_class);
322 uint32_t xtensa_cause_get(struct target *target);
323 void xtensa_cause_clear(struct target *target);
324 void xtensa_cause_reset(struct target *target);
325 int xtensa_poll(struct target *target);
326 void xtensa_on_poll(struct target *target);
327 int xtensa_halt(struct target *target);
328 int xtensa_resume(struct target *target,
329 int current,
330 target_addr_t address,
331 int handle_breakpoints,
332 int debug_execution);
333 int xtensa_prepare_resume(struct target *target,
334 int current,
335 target_addr_t address,
336 int handle_breakpoints,
337 int debug_execution);
338 int xtensa_do_resume(struct target *target);
339 int xtensa_step(struct target *target, int current, target_addr_t address, int handle_breakpoints);
340 int xtensa_do_step(struct target *target, int current, target_addr_t address, int handle_breakpoints);
341 int xtensa_mmu_is_enabled(struct target *target, int *enabled);
342 int xtensa_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer);
343 int xtensa_read_buffer(struct target *target, target_addr_t address, uint32_t count, uint8_t *buffer);
344 int xtensa_write_memory(struct target *target,
345 target_addr_t address,
346 uint32_t size,
347 uint32_t count,
348 const uint8_t *buffer);
349 int xtensa_write_buffer(struct target *target, target_addr_t address, uint32_t count, const uint8_t *buffer);
350 int xtensa_checksum_memory(struct target *target, target_addr_t address, uint32_t count, uint32_t *checksum);
351 int xtensa_assert_reset(struct target *target);
352 int xtensa_deassert_reset(struct target *target);
353 int xtensa_soft_reset_halt(struct target *target);
354 int xtensa_breakpoint_add(struct target *target, struct breakpoint *breakpoint);
355 int xtensa_breakpoint_remove(struct target *target, struct breakpoint *breakpoint);
356 int xtensa_watchpoint_add(struct target *target, struct watchpoint *watchpoint);
357 int xtensa_watchpoint_remove(struct target *target, struct watchpoint *watchpoint);
358 void xtensa_set_permissive_mode(struct target *target, bool state);
359 const char *xtensa_get_gdb_arch(struct target *target);
360 int xtensa_gdb_query_custom(struct target *target, const char *packet, char **response_p);
361
362 COMMAND_HELPER(xtensa_cmd_xtdef_do, struct xtensa *xtensa);
363 COMMAND_HELPER(xtensa_cmd_xtopt_do, struct xtensa *xtensa);
364 COMMAND_HELPER(xtensa_cmd_xtmem_do, struct xtensa *xtensa);
365 COMMAND_HELPER(xtensa_cmd_xtmpu_do, struct xtensa *xtensa);
366 COMMAND_HELPER(xtensa_cmd_xtmmu_do, struct xtensa *xtensa);
367 COMMAND_HELPER(xtensa_cmd_xtreg_do, struct xtensa *xtensa);
368 COMMAND_HELPER(xtensa_cmd_xtregfmt_do, struct xtensa *xtensa);
369 COMMAND_HELPER(xtensa_cmd_permissive_mode_do, struct xtensa *xtensa);
370 COMMAND_HELPER(xtensa_cmd_mask_interrupts_do, struct xtensa *xtensa);
371 COMMAND_HELPER(xtensa_cmd_smpbreak_do, struct target *target);
372 COMMAND_HELPER(xtensa_cmd_perfmon_dump_do, struct xtensa *xtensa);
373 COMMAND_HELPER(xtensa_cmd_perfmon_enable_do, struct xtensa *xtensa);
374 COMMAND_HELPER(xtensa_cmd_tracestart_do, struct xtensa *xtensa);
375 COMMAND_HELPER(xtensa_cmd_tracestop_do, struct xtensa *xtensa);
376 COMMAND_HELPER(xtensa_cmd_tracedump_do, struct xtensa *xtensa, const char *fname);
377
378 extern const struct command_registration xtensa_command_handlers[];
379
380 #endif /* OPENOCD_TARGET_XTENSA_H */

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)