1 /***************************************************************************
2 * Generic Xtensa target *
3 * Copyright (C) 2019 Espressif Systems Ltd. *
4 * Author: Alexey Gerenkov <alexey@espressif.com> *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 ***************************************************************************/
20 #ifndef OPENOCD_TARGET_XTENSA_H
21 #define OPENOCD_TARGET_XTENSA_H
24 #include <target/target.h>
25 #include <target/breakpoints.h>
26 #include "xtensa_regs.h"
27 #include "xtensa_debug_module.h"
31 * Holds the interface to Xtensa cores.
34 #define XT_ISNS_SZ_MAX 3
36 #define XT_PS_RING(_v_) ((uint32_t)((_v_) & 0x3) << 6)
37 #define XT_PS_RING_MSK (0x3 << 6)
38 #define XT_PS_RING_GET(_v_) (((_v_) >> 6) & 0x3)
39 #define XT_PS_CALLINC_MSK (0x3 << 16)
40 #define XT_PS_OWB_MSK (0xF << 8)
42 #define XT_LOCAL_MEM_REGIONS_NUM_MAX 8
44 #define XT_AREGS_NUM_MAX 64
45 #define XT_USER_REGS_NUM_MAX 256
47 #define XT_MEM_ACCESS_NONE 0x0
48 #define XT_MEM_ACCESS_READ 0x1
49 #define XT_MEM_ACCESS_WRITE 0x2
51 enum xtensa_mem_err_detect {
52 XT_MEM_ERR_DETECT_NONE,
53 XT_MEM_ERR_DETECT_PARITY,
54 XT_MEM_ERR_DETECT_ECC,
57 struct xtensa_cache_config {
62 enum xtensa_mem_err_detect mem_err_check;
65 struct xtensa_local_mem_region_config {
68 enum xtensa_mem_err_detect mem_err_check;
72 struct xtensa_local_mem_config {
74 struct xtensa_local_mem_region_config regions[XT_LOCAL_MEM_REGIONS_NUM_MAX];
77 struct xtensa_mmu_config {
79 uint8_t itlb_entries_count;
80 uint8_t dtlb_entries_count;
85 struct xtensa_exception_config {
90 struct xtensa_irq_config {
95 struct xtensa_high_prio_irq_config {
101 struct xtensa_debug_config {
109 struct xtensa_tracing_config {
112 bool reversed_mem_access;
115 struct xtensa_timer_irq_config {
120 struct xtensa_config {
127 uint8_t miscregs_num;
136 uint16_t user_regs_num;
137 const struct xtensa_user_reg_desc *user_regs;
138 int (*fetch_user_regs)(struct target *target);
139 int (*queue_write_dirty_user_regs)(struct target *target);
140 struct xtensa_cache_config icache;
141 struct xtensa_cache_config dcache;
142 struct xtensa_local_mem_config irom;
143 struct xtensa_local_mem_config iram;
144 struct xtensa_local_mem_config drom;
145 struct xtensa_local_mem_config dram;
146 struct xtensa_local_mem_config uram;
147 struct xtensa_local_mem_config xlmi;
148 struct xtensa_mmu_config mmu;
149 struct xtensa_exception_config exc;
150 struct xtensa_irq_config irq;
151 struct xtensa_high_prio_irq_config high_irq;
152 struct xtensa_timer_irq_config tim_irq;
153 struct xtensa_debug_config debug;
154 struct xtensa_tracing_config trace;
155 unsigned int gdb_general_regs_num;
156 const unsigned int *gdb_regs_mapping;
159 typedef uint32_t xtensa_insn_t;
161 enum xtensa_stepping_isr_mode {
162 XT_STEPPING_ISR_OFF, /* interrupts are disabled during stepping */
163 XT_STEPPING_ISR_ON, /* interrupts are enabled during stepping */
166 /* Only supported in cores with in-CPU MMU. None of Espressif chips as of now. */
172 XT_MODE_ANY /* special value to run algorithm in current core mode */
175 struct xtensa_sw_breakpoint {
176 struct breakpoint *oocd_bp;
178 uint8_t insn[XT_ISNS_SZ_MAX];
179 /* original insn size */
180 uint8_t insn_sz; /* 2 or 3 bytes */
183 #define XTENSA_COMMON_MAGIC 0x54E4E555U
186 * Represents a generic Xtensa core.
189 unsigned int common_magic;
190 const struct xtensa_config *core_config;
191 struct xtensa_debug_module dbg_mod;
192 struct reg_cache *core_cache;
193 unsigned int regs_num;
194 /* An array of pointers to buffers to backup registers' values while algo is run on target.
195 * Size is 'regs_num'. */
196 void **algo_context_backup;
197 struct target *target;
199 enum xtensa_stepping_isr_mode stepping_isr_mode;
200 struct breakpoint **hw_brps;
201 struct watchpoint **hw_wps;
202 struct xtensa_sw_breakpoint *sw_brps;
204 bool permissive_mode; /* bypass memory checks */
205 bool suppress_dsr_errors;
207 /* Sometimes debug module's 'powered' bit is cleared after reset, but get set after some
208 * time.This is the number of polling periods after which core is considered to be powered
209 * off (marked as unexamined) if the bit retains to be cleared (e.g. if core is disabled by
210 * SW running on target).*/
211 uint8_t come_online_probes_num;
212 bool regs_fetched; /* true after first register fetch completed successfully */
215 static inline struct xtensa *target_to_xtensa(struct target *target)
218 struct xtensa *xtensa = target->arch_info;
219 assert(xtensa->common_magic == XTENSA_COMMON_MAGIC);
223 int xtensa_init_arch_info(struct target *target,
224 struct xtensa *xtensa,
225 const struct xtensa_config *cfg,
226 const struct xtensa_debug_module_config *dm_cfg);
227 int xtensa_target_init(struct command_context *cmd_ctx, struct target *target);
228 void xtensa_target_deinit(struct target *target);
230 static inline bool xtensa_addr_in_mem(const struct xtensa_local_mem_config *mem, uint32_t addr)
232 for (unsigned int i = 0; i < mem->count; i++) {
233 if (addr >= mem->regions[i].base &&
234 addr < mem->regions[i].base + mem->regions[i].size)
240 static inline bool xtensa_data_addr_valid(struct target *target, uint32_t addr)
242 struct xtensa *xtensa = target_to_xtensa(target);
244 if (xtensa_addr_in_mem(&xtensa->core_config->drom, addr))
246 if (xtensa_addr_in_mem(&xtensa->core_config->dram, addr))
248 if (xtensa_addr_in_mem(&xtensa->core_config->uram, addr))
253 int xtensa_core_status_check(struct target *target);
255 int xtensa_examine(struct target *target);
256 int xtensa_wakeup(struct target *target);
257 int xtensa_smpbreak_set(struct target *target, uint32_t set);
258 int xtensa_smpbreak_get(struct target *target, uint32_t *val);
259 int xtensa_smpbreak_write(struct xtensa *xtensa, uint32_t set);
260 int xtensa_smpbreak_read(struct xtensa *xtensa, uint32_t *val);
261 xtensa_reg_val_t xtensa_reg_get(struct target *target, enum xtensa_reg_id reg_id);
262 void xtensa_reg_set(struct target *target, enum xtensa_reg_id reg_id, xtensa_reg_val_t value);
263 int xtensa_fetch_all_regs(struct target *target);
264 int xtensa_get_gdb_reg_list(struct target *target,
265 struct reg **reg_list[],
267 enum target_register_class reg_class);
268 int xtensa_poll(struct target *target);
269 void xtensa_on_poll(struct target *target);
270 int xtensa_halt(struct target *target);
271 int xtensa_resume(struct target *target,
273 target_addr_t address,
274 int handle_breakpoints,
275 int debug_execution);
276 int xtensa_prepare_resume(struct target *target,
278 target_addr_t address,
279 int handle_breakpoints,
280 int debug_execution);
281 int xtensa_do_resume(struct target *target);
282 int xtensa_step(struct target *target, int current, target_addr_t address, int handle_breakpoints);
283 int xtensa_do_step(struct target *target, int current, target_addr_t address, int handle_breakpoints);
284 int xtensa_mmu_is_enabled(struct target *target, int *enabled);
285 int xtensa_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer);
286 int xtensa_read_buffer(struct target *target, target_addr_t address, uint32_t count, uint8_t *buffer);
287 int xtensa_write_memory(struct target *target,
288 target_addr_t address,
291 const uint8_t *buffer);
292 int xtensa_write_buffer(struct target *target, target_addr_t address, uint32_t count, const uint8_t *buffer);
293 int xtensa_checksum_memory(struct target *target, target_addr_t address, uint32_t count, uint32_t *checksum);
294 int xtensa_assert_reset(struct target *target);
295 int xtensa_deassert_reset(struct target *target);
296 int xtensa_breakpoint_add(struct target *target, struct breakpoint *breakpoint);
297 int xtensa_breakpoint_remove(struct target *target, struct breakpoint *breakpoint);
298 int xtensa_watchpoint_add(struct target *target, struct watchpoint *watchpoint);
299 int xtensa_watchpoint_remove(struct target *target, struct watchpoint *watchpoint);
300 void xtensa_set_permissive_mode(struct target *target, bool state);
301 int xtensa_fetch_user_regs_u32(struct target *target);
302 int xtensa_queue_write_dirty_user_regs_u32(struct target *target);
303 const char *xtensa_get_gdb_arch(struct target *target);
305 extern const struct reg_arch_type xtensa_user_reg_u32_type;
306 extern const struct reg_arch_type xtensa_user_reg_u128_type;
307 extern const struct command_registration xtensa_command_handlers[];
309 #endif /* OPENOCD_TARGET_XTENSA_H */