1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 /***************************************************************************
4 * ESP32-S2 target for OpenOCD *
5 * Copyright (C) 2019 Espressif Systems Ltd. *
6 ***************************************************************************/
12 #include <helper/time_support.h>
14 #include <target/target.h>
15 #include <target/target_type.h>
16 #include "esp_xtensa.h"
20 * TODO: read memory configuration from target registers */
21 #define ESP32_S2_IROM_MASK_LOW 0x40000000
22 #define ESP32_S2_IROM_MASK_HIGH 0x40020000
23 #define ESP32_S2_IRAM_LOW 0x40020000
24 #define ESP32_S2_IRAM_HIGH 0x40070000
25 #define ESP32_S2_DRAM_LOW 0x3ffb0000
26 #define ESP32_S2_DRAM_HIGH 0x40000000
27 #define ESP32_S2_RTC_IRAM_LOW 0x40070000
28 #define ESP32_S2_RTC_IRAM_HIGH 0x40072000
29 #define ESP32_S2_RTC_DRAM_LOW 0x3ff9e000
30 #define ESP32_S2_RTC_DRAM_HIGH 0x3ffa0000
31 #define ESP32_S2_RTC_DATA_LOW 0x50000000
32 #define ESP32_S2_RTC_DATA_HIGH 0x50002000
33 #define ESP32_S2_EXTRAM_DATA_LOW 0x3f500000
34 #define ESP32_S2_EXTRAM_DATA_HIGH 0x3ff80000
35 #define ESP32_S2_DR_REG_LOW 0x3f400000
36 #define ESP32_S2_DR_REG_HIGH 0x3f4d3FFC
37 #define ESP32_S2_SYS_RAM_LOW 0x60000000UL
38 #define ESP32_S2_SYS_RAM_HIGH (ESP32_S2_SYS_RAM_LOW + 0x20000000UL)
39 /* ESP32-S2 DROM mapping is not contiguous. */
40 /* IDF declares this as 0x3F000000..0x3FF80000, but there are peripheral registers mapped to
41 * 0x3f400000..0x3f4d3FFC. */
42 #define ESP32_S2_DROM0_LOW ESP32_S2_DROM_LOW
43 #define ESP32_S2_DROM0_HIGH ESP32_S2_DR_REG_LOW
44 #define ESP32_S2_DROM1_LOW ESP32_S2_DR_REG_HIGH
45 #define ESP32_S2_DROM1_HIGH ESP32_S2_DROM_HIGH
48 #define ESP32_S2_WDT_WKEY_VALUE 0x50d83aa1
49 #define ESP32_S2_TIMG0_BASE 0x3f41F000
50 #define ESP32_S2_TIMG1_BASE 0x3f420000
51 #define ESP32_S2_TIMGWDT_CFG0_OFF 0x48
52 #define ESP32_S2_TIMGWDT_PROTECT_OFF 0x64
53 #define ESP32_S2_TIMG0WDT_CFG0 (ESP32_S2_TIMG0_BASE + ESP32_S2_TIMGWDT_CFG0_OFF)
54 #define ESP32_S2_TIMG1WDT_CFG0 (ESP32_S2_TIMG1_BASE + ESP32_S2_TIMGWDT_CFG0_OFF)
55 #define ESP32_S2_TIMG0WDT_PROTECT (ESP32_S2_TIMG0_BASE + ESP32_S2_TIMGWDT_PROTECT_OFF)
56 #define ESP32_S2_TIMG1WDT_PROTECT (ESP32_S2_TIMG1_BASE + ESP32_S2_TIMGWDT_PROTECT_OFF)
57 #define ESP32_S2_RTCCNTL_BASE 0x3f408000
58 #define ESP32_S2_RTCWDT_CFG_OFF 0x94
59 #define ESP32_S2_RTCWDT_PROTECT_OFF 0xAC
60 #define ESP32_S2_SWD_CONF_OFF 0xB0
61 #define ESP32_S2_SWD_WPROTECT_OFF 0xB4
62 #define ESP32_S2_RTC_CNTL_DIG_PWC_REG_OFF 0x8C
63 #define ESP32_S2_RTC_CNTL_DIG_PWC_REG (ESP32_S2_RTCCNTL_BASE + ESP32_S2_RTC_CNTL_DIG_PWC_REG_OFF)
64 #define ESP32_S2_RTCWDT_CFG (ESP32_S2_RTCCNTL_BASE + ESP32_S2_RTCWDT_CFG_OFF)
65 #define ESP32_S2_RTCWDT_PROTECT (ESP32_S2_RTCCNTL_BASE + ESP32_S2_RTCWDT_PROTECT_OFF)
66 #define ESP32_S2_SWD_CONF_REG (ESP32_S2_RTCCNTL_BASE + ESP32_S2_SWD_CONF_OFF)
67 #define ESP32_S2_SWD_WPROTECT_REG (ESP32_S2_RTCCNTL_BASE + ESP32_S2_SWD_WPROTECT_OFF)
68 #define ESP32_S2_SWD_AUTO_FEED_EN_M BIT(31)
69 #define ESP32_S2_SWD_WKEY_VALUE 0x8F1D312AU
70 #define ESP32_S2_OPTIONS0 (ESP32_S2_RTCCNTL_BASE + 0x0000)
71 #define ESP32_S2_SW_SYS_RST_M 0x80000000
72 #define ESP32_S2_SW_SYS_RST_V 0x1
73 #define ESP32_S2_SW_SYS_RST_S 31
74 #define ESP32_S2_SW_STALL_PROCPU_C0_M ((ESP32_S2_SW_STALL_PROCPU_C0_V) << (ESP32_S2_SW_STALL_PROCPU_C0_S))
75 #define ESP32_S2_SW_STALL_PROCPU_C0_V 0x3
76 #define ESP32_S2_SW_STALL_PROCPU_C0_S 2
77 #define ESP32_S2_SW_CPU_STALL (ESP32_S2_RTCCNTL_BASE + 0x00B8)
78 #define ESP32_S2_SW_STALL_PROCPU_C1_M ((ESP32_S2_SW_STALL_PROCPU_C1_V) << (ESP32_S2_SW_STALL_PROCPU_C1_S))
79 #define ESP32_S2_SW_STALL_PROCPU_C1_V 0x3FU
80 #define ESP32_S2_SW_STALL_PROCPU_C1_S 26
81 #define ESP32_S2_CLK_CONF (ESP32_S2_RTCCNTL_BASE + 0x0074)
82 #define ESP32_S2_CLK_CONF_DEF 0x1583218
83 #define ESP32_S2_STORE4 (ESP32_S2_RTCCNTL_BASE + 0x00BC)
84 #define ESP32_S2_STORE5 (ESP32_S2_RTCCNTL_BASE + 0x00C0)
85 #define ESP32_S2_DPORT_PMS_OCCUPY_3 0x3F4C10E0
87 #define ESP32_S2_TRACEMEM_BLOCK_SZ 0x4000
89 #define ESP32_S2_DR_REG_UART_BASE 0x3f400000
90 #define ESP32_S2_REG_UART_BASE(i) (ESP32_S2_DR_REG_UART_BASE + (i) * 0x10000)
91 #define ESP32_S2_UART_DATE_REG(i) (ESP32_S2_REG_UART_BASE(i) + 0x74)
93 /* this should map local reg IDs to GDB reg mapping as defined in xtensa-config.c 'rmap' in
95 static const unsigned int esp32s2_gdb_regs_mapping[ESP32_S2_NUM_REGS] = {
97 XT_REG_IDX_AR0, XT_REG_IDX_AR1, XT_REG_IDX_AR2, XT_REG_IDX_AR3,
98 XT_REG_IDX_AR4, XT_REG_IDX_AR5, XT_REG_IDX_AR6, XT_REG_IDX_AR7,
99 XT_REG_IDX_AR8, XT_REG_IDX_AR9, XT_REG_IDX_AR10, XT_REG_IDX_AR11,
100 XT_REG_IDX_AR12, XT_REG_IDX_AR13, XT_REG_IDX_AR14, XT_REG_IDX_AR15,
101 XT_REG_IDX_AR16, XT_REG_IDX_AR17, XT_REG_IDX_AR18, XT_REG_IDX_AR19,
102 XT_REG_IDX_AR20, XT_REG_IDX_AR21, XT_REG_IDX_AR22, XT_REG_IDX_AR23,
103 XT_REG_IDX_AR24, XT_REG_IDX_AR25, XT_REG_IDX_AR26, XT_REG_IDX_AR27,
104 XT_REG_IDX_AR28, XT_REG_IDX_AR29, XT_REG_IDX_AR30, XT_REG_IDX_AR31,
105 XT_REG_IDX_AR32, XT_REG_IDX_AR33, XT_REG_IDX_AR34, XT_REG_IDX_AR35,
106 XT_REG_IDX_AR36, XT_REG_IDX_AR37, XT_REG_IDX_AR38, XT_REG_IDX_AR39,
107 XT_REG_IDX_AR40, XT_REG_IDX_AR41, XT_REG_IDX_AR42, XT_REG_IDX_AR43,
108 XT_REG_IDX_AR44, XT_REG_IDX_AR45, XT_REG_IDX_AR46, XT_REG_IDX_AR47,
109 XT_REG_IDX_AR48, XT_REG_IDX_AR49, XT_REG_IDX_AR50, XT_REG_IDX_AR51,
110 XT_REG_IDX_AR52, XT_REG_IDX_AR53, XT_REG_IDX_AR54, XT_REG_IDX_AR55,
111 XT_REG_IDX_AR56, XT_REG_IDX_AR57, XT_REG_IDX_AR58, XT_REG_IDX_AR59,
112 XT_REG_IDX_AR60, XT_REG_IDX_AR61, XT_REG_IDX_AR62, XT_REG_IDX_AR63,
114 XT_REG_IDX_WINDOWBASE, XT_REG_IDX_WINDOWSTART, XT_REG_IDX_CONFIGID0, XT_REG_IDX_CONFIGID1,
115 XT_REG_IDX_PS, XT_REG_IDX_THREADPTR,
116 ESP32_S2_REG_IDX_GPIOOUT,
117 XT_REG_IDX_MMID, XT_REG_IDX_IBREAKENABLE, XT_REG_IDX_OCD_DDR,
118 XT_REG_IDX_IBREAKA0, XT_REG_IDX_IBREAKA1, XT_REG_IDX_DBREAKA0, XT_REG_IDX_DBREAKA1,
119 XT_REG_IDX_DBREAKC0, XT_REG_IDX_DBREAKC1,
120 XT_REG_IDX_EPC1, XT_REG_IDX_EPC2, XT_REG_IDX_EPC3, XT_REG_IDX_EPC4,
121 XT_REG_IDX_EPC5, XT_REG_IDX_EPC6, XT_REG_IDX_EPC7, XT_REG_IDX_DEPC,
122 XT_REG_IDX_EPS2, XT_REG_IDX_EPS3, XT_REG_IDX_EPS4, XT_REG_IDX_EPS5,
123 XT_REG_IDX_EPS6, XT_REG_IDX_EPS7,
124 XT_REG_IDX_EXCSAVE1, XT_REG_IDX_EXCSAVE2, XT_REG_IDX_EXCSAVE3, XT_REG_IDX_EXCSAVE4,
125 XT_REG_IDX_EXCSAVE5, XT_REG_IDX_EXCSAVE6, XT_REG_IDX_EXCSAVE7, XT_REG_IDX_CPENABLE,
126 XT_REG_IDX_INTERRUPT, XT_REG_IDX_INTSET, XT_REG_IDX_INTCLEAR, XT_REG_IDX_INTENABLE,
127 XT_REG_IDX_VECBASE, XT_REG_IDX_EXCCAUSE, XT_REG_IDX_DEBUGCAUSE, XT_REG_IDX_CCOUNT,
128 XT_REG_IDX_PRID, XT_REG_IDX_ICOUNT, XT_REG_IDX_ICOUNTLEVEL, XT_REG_IDX_EXCVADDR,
129 XT_REG_IDX_CCOMPARE0, XT_REG_IDX_CCOMPARE1, XT_REG_IDX_CCOMPARE2,
130 XT_REG_IDX_MISC0, XT_REG_IDX_MISC1, XT_REG_IDX_MISC2, XT_REG_IDX_MISC3,
131 XT_REG_IDX_A0, XT_REG_IDX_A1, XT_REG_IDX_A2, XT_REG_IDX_A3,
132 XT_REG_IDX_A4, XT_REG_IDX_A5, XT_REG_IDX_A6, XT_REG_IDX_A7,
133 XT_REG_IDX_A8, XT_REG_IDX_A9, XT_REG_IDX_A10, XT_REG_IDX_A11,
134 XT_REG_IDX_A12, XT_REG_IDX_A13, XT_REG_IDX_A14, XT_REG_IDX_A15,
135 XT_REG_IDX_PWRCTL, XT_REG_IDX_PWRSTAT, XT_REG_IDX_ERISTAT,
136 XT_REG_IDX_CS_ITCTRL, XT_REG_IDX_CS_CLAIMSET, XT_REG_IDX_CS_CLAIMCLR,
137 XT_REG_IDX_CS_LOCKACCESS, XT_REG_IDX_CS_LOCKSTATUS, XT_REG_IDX_CS_AUTHSTATUS,
138 XT_REG_IDX_FAULT_INFO,
139 XT_REG_IDX_TRAX_ID, XT_REG_IDX_TRAX_CTRL, XT_REG_IDX_TRAX_STAT,
140 XT_REG_IDX_TRAX_DATA, XT_REG_IDX_TRAX_ADDR, XT_REG_IDX_TRAX_PCTRIGGER,
141 XT_REG_IDX_TRAX_PCMATCH, XT_REG_IDX_TRAX_DELAY, XT_REG_IDX_TRAX_MEMSTART,
142 XT_REG_IDX_TRAX_MEMEND,
143 XT_REG_IDX_PMG, XT_REG_IDX_PMPC, XT_REG_IDX_PM0, XT_REG_IDX_PM1,
144 XT_REG_IDX_PMCTRL0, XT_REG_IDX_PMCTRL1, XT_REG_IDX_PMSTAT0, XT_REG_IDX_PMSTAT1,
145 XT_REG_IDX_OCD_ID, XT_REG_IDX_OCD_DCRCLR, XT_REG_IDX_OCD_DCRSET, XT_REG_IDX_OCD_DSR,
148 static const struct xtensa_user_reg_desc esp32s2_user_regs[ESP32_S2_NUM_REGS - XT_NUM_REGS] = {
149 { "gpio_out", 0x00, 0, 32, &xtensa_user_reg_u32_type },
152 static const struct xtensa_config esp32s2_xtensa_cfg = {
154 .aregs_num = XT_AREGS_NUM_MAX,
161 .user_regs_num = ARRAY_SIZE(esp32s2_user_regs),
162 .user_regs = esp32s2_user_regs,
163 .fetch_user_regs = xtensa_fetch_user_regs_u32,
164 .queue_write_dirty_user_regs = xtensa_queue_write_dirty_user_regs_u32,
165 .gdb_general_regs_num = ESP32_S2_NUM_REGS_G_COMMAND,
166 .gdb_regs_mapping = esp32s2_gdb_regs_mapping,
171 .base = ESP32_S2_IROM_LOW,
172 .size = ESP32_S2_IROM_HIGH - ESP32_S2_IROM_LOW,
173 .access = XT_MEM_ACCESS_READ,
176 .base = ESP32_S2_IROM_MASK_LOW,
177 .size = ESP32_S2_IROM_MASK_HIGH - ESP32_S2_IROM_MASK_LOW,
178 .access = XT_MEM_ACCESS_READ,
186 .base = ESP32_S2_IRAM_LOW,
187 .size = ESP32_S2_IRAM_HIGH - ESP32_S2_IRAM_LOW,
188 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
191 .base = ESP32_S2_RTC_IRAM_LOW,
192 .size = ESP32_S2_RTC_IRAM_HIGH - ESP32_S2_RTC_IRAM_LOW,
193 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
201 .base = ESP32_S2_DROM0_LOW,
202 .size = ESP32_S2_DROM0_HIGH - ESP32_S2_DROM0_LOW,
203 .access = XT_MEM_ACCESS_READ,
206 .base = ESP32_S2_DROM1_LOW,
207 .size = ESP32_S2_DROM1_HIGH - ESP32_S2_DROM1_LOW,
208 .access = XT_MEM_ACCESS_READ,
216 .base = ESP32_S2_DRAM_LOW,
217 .size = ESP32_S2_DRAM_HIGH - ESP32_S2_DRAM_LOW,
218 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
221 .base = ESP32_S2_RTC_DRAM_LOW,
222 .size = ESP32_S2_RTC_DRAM_HIGH - ESP32_S2_RTC_DRAM_LOW,
223 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
226 .base = ESP32_S2_RTC_DATA_LOW,
227 .size = ESP32_S2_RTC_DATA_HIGH - ESP32_S2_RTC_DATA_LOW,
228 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
231 .base = ESP32_S2_EXTRAM_DATA_LOW,
232 .size = ESP32_S2_EXTRAM_DATA_HIGH - ESP32_S2_EXTRAM_DATA_LOW,
233 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
236 .base = ESP32_S2_DR_REG_LOW,
237 .size = ESP32_S2_DR_REG_HIGH - ESP32_S2_DR_REG_LOW,
238 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
241 .base = ESP32_S2_SYS_RAM_LOW,
242 .size = ESP32_S2_SYS_RAM_HIGH - ESP32_S2_SYS_RAM_LOW,
243 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
272 .mem_sz = ESP32_S2_TRACEMEM_BLOCK_SZ,
276 struct esp32s2_common {
277 struct esp_xtensa_common esp_xtensa;
280 static int esp32s2_soc_reset(struct target *target);
281 static int esp32s2_disable_wdts(struct target *target);
283 static int esp32s2_assert_reset(struct target *target)
288 static int esp32s2_deassert_reset(struct target *target)
290 struct xtensa *xtensa = target_to_xtensa(target);
292 LOG_TARGET_DEBUG(target, "begin");
294 int res = xtensa_deassert_reset(target);
298 /* restore configured value
299 esp32s2_soc_reset() modified it, but can not restore just after SW reset for some reason (???) */
300 res = xtensa_smpbreak_write(xtensa, xtensa->smp_break);
301 if (res != ERROR_OK) {
302 LOG_ERROR("Failed to restore smpbreak (%d)!", res);
308 int esp32s2_soft_reset_halt(struct target *target)
310 LOG_TARGET_DEBUG(target, "begin");
312 /* Reset the SoC first */
313 int res = esp32s2_soc_reset(target);
316 return xtensa_assert_reset(target);
319 static int esp32s2_set_peri_reg_mask(struct target *target,
325 int res = target_read_u32(target, addr, ®_val);
328 reg_val = (reg_val & (~mask)) | val;
329 res = target_write_u32(target, addr, reg_val);
336 static int esp32s2_stall_set(struct target *target, bool stall)
338 LOG_TARGET_DEBUG(target, "begin");
340 int res = esp32s2_set_peri_reg_mask(target,
341 ESP32_S2_SW_CPU_STALL,
342 ESP32_S2_SW_STALL_PROCPU_C1_M,
343 stall ? 0x21U << ESP32_S2_SW_STALL_PROCPU_C1_S : 0);
344 if (res != ERROR_OK) {
345 LOG_ERROR("Failed to write ESP32_S2_SW_CPU_STALL (%d)!", res);
348 res = esp32s2_set_peri_reg_mask(target,
350 ESP32_S2_SW_STALL_PROCPU_C0_M,
351 stall ? 0x2 << ESP32_S2_SW_STALL_PROCPU_C0_S : 0);
352 if (res != ERROR_OK) {
353 LOG_ERROR("Failed to write ESP32_S2_OPTIONS0 (%d)!", res);
359 static inline int esp32s2_stall(struct target *target)
361 return esp32s2_stall_set(target, true);
364 static inline int esp32s2_unstall(struct target *target)
366 return esp32s2_stall_set(target, false);
369 /* Reset ESP32-S2's peripherals.
370 Postconditions: all peripherals except RTC_CNTL are reset, CPU's PC is undefined, PRO CPU is halted, APP CPU is in reset
372 0. make sure target is halted; if not, try to halt it; if that fails, try to reset it (via OCD) and then halt
373 1. Resets clock related registers
375 3. trigger SoC reset using RTC_CNTL_SW_SYS_RST bit
376 4. CPU is reset and stalled at the first reset vector instruction
377 5. wait for the OCD to be reset
380 8. Disables WDTs and trace memory mapping
382 static int esp32s2_soc_reset(struct target *target)
385 struct xtensa *xtensa = target_to_xtensa(target);
389 /* In order to write to peripheral registers, target must be halted first */
390 if (target->state != TARGET_HALTED) {
391 LOG_TARGET_DEBUG(target, "Target not halted before SoC reset, trying to halt it first");
393 res = target_wait_state(target, TARGET_HALTED, 1000);
394 if (res != ERROR_OK) {
395 LOG_TARGET_DEBUG(target, "Couldn't halt target before SoC reset, trying to do reset-halt");
396 res = xtensa_assert_reset(target);
397 if (res != ERROR_OK) {
400 "Couldn't halt target before SoC reset! (xtensa_assert_reset returned %d)",
406 int reset_halt_save = target->reset_halt;
407 target->reset_halt = 1;
408 res = xtensa_deassert_reset(target);
409 target->reset_halt = reset_halt_save;
410 if (res != ERROR_OK) {
413 "Couldn't halt target before SoC reset! (xtensa_deassert_reset returned %d)",
420 res = target_wait_state(target, TARGET_HALTED, 1000);
421 if (res != ERROR_OK) {
422 LOG_TARGET_ERROR(target, "Couldn't halt target before SoC reset");
428 assert(target->state == TARGET_HALTED);
430 /* Set some clock-related RTC registers to the default values */
431 res = target_write_u32(target, ESP32_S2_STORE4, 0);
432 if (res != ERROR_OK) {
433 LOG_ERROR("Failed to write ESP32_S2_STORE4 (%d)!", res);
436 res = target_write_u32(target, ESP32_S2_STORE5, 0);
437 if (res != ERROR_OK) {
438 LOG_ERROR("Failed to write ESP32_S2_STORE5 (%d)!", res);
441 res = target_write_u32(target, ESP32_S2_RTC_CNTL_DIG_PWC_REG, 0);
442 if (res != ERROR_OK) {
443 LOG_ERROR("Failed to write ESP32_S2_RTC_CNTL_DIG_PWC_REG (%d)!", res);
446 res = target_write_u32(target, ESP32_S2_CLK_CONF, ESP32_S2_CLK_CONF_DEF);
447 if (res != ERROR_OK) {
448 LOG_ERROR("Failed to write ESP32_S2_CLK_CONF (%d)!", res);
452 res = esp32s2_stall(target);
456 res = xtensa_smpbreak_write(xtensa, OCDDCR_RUNSTALLINEN);
457 if (res != ERROR_OK) {
458 LOG_ERROR("Failed to set smpbreak (%d)!", res);
462 xtensa->suppress_dsr_errors = true;
463 res = esp32s2_set_peri_reg_mask(target,
465 ESP32_S2_SW_SYS_RST_M,
466 BIT(ESP32_S2_SW_SYS_RST_S));
467 xtensa->suppress_dsr_errors = false;
468 if (res != ERROR_OK) {
469 LOG_ERROR("Failed to write ESP32_S2_OPTIONS0 (%d)!", res);
472 /* Wait for SoC to reset */
474 int64_t timeout = timeval_ms() + 100;
475 while (target->state != TARGET_RESET && target->state != TARGET_RUNNING) {
478 if (timeval_ms() >= timeout) {
479 LOG_TARGET_ERROR(target, "Timed out waiting for CPU to be reset, target state=%d", target->state);
480 return ERROR_TARGET_TIMEOUT;
485 res = target_wait_state(target, TARGET_HALTED, 1000);
486 if (res != ERROR_OK) {
487 LOG_TARGET_ERROR(target, "Couldn't halt target before SoC reset");
491 res = esp32s2_unstall(target);
495 res = esp32s2_disable_wdts(target);
498 /* Disable trace memory mapping */
499 res = target_write_u32(target, ESP32_S2_DPORT_PMS_OCCUPY_3, 0);
500 if (res != ERROR_OK) {
501 LOG_ERROR("Failed to write ESP32_S2_DPORT_PMS_OCCUPY_3 (%d)!", res);
507 static int esp32s2_disable_wdts(struct target *target)
510 int res = target_write_u32(target, ESP32_S2_TIMG0WDT_PROTECT, ESP32_S2_WDT_WKEY_VALUE);
511 if (res != ERROR_OK) {
512 LOG_ERROR("Failed to write ESP32_S2_TIMG0WDT_PROTECT (%d)!", res);
515 res = target_write_u32(target, ESP32_S2_TIMG0WDT_CFG0, 0);
516 if (res != ERROR_OK) {
517 LOG_ERROR("Failed to write ESP32_S2_TIMG0WDT_CFG0 (%d)!", res);
521 res = target_write_u32(target, ESP32_S2_TIMG1WDT_PROTECT, ESP32_S2_WDT_WKEY_VALUE);
522 if (res != ERROR_OK) {
523 LOG_ERROR("Failed to write ESP32_S2_TIMG1WDT_PROTECT (%d)!", res);
526 res = target_write_u32(target, ESP32_S2_TIMG1WDT_CFG0, 0);
527 if (res != ERROR_OK) {
528 LOG_ERROR("Failed to write ESP32_S2_TIMG1WDT_CFG0 (%d)!", res);
532 res = target_write_u32(target, ESP32_S2_RTCWDT_PROTECT, ESP32_S2_WDT_WKEY_VALUE);
533 if (res != ERROR_OK) {
534 LOG_ERROR("Failed to write ESP32_S2_RTCWDT_PROTECT (%d)!", res);
537 res = target_write_u32(target, ESP32_S2_RTCWDT_CFG, 0);
538 if (res != ERROR_OK) {
539 LOG_ERROR("Failed to write ESP32_S2_RTCWDT_CFG (%d)!", res);
542 /* Enable SWD auto-feed */
543 res = target_write_u32(target, ESP32_S2_SWD_WPROTECT_REG, ESP32_S2_SWD_WKEY_VALUE);
544 if (res != ERROR_OK) {
545 LOG_ERROR("Failed to write ESP32_S2_SWD_WPROTECT_REG (%d)!", res);
548 uint32_t swd_conf_reg = 0;
549 res = target_read_u32(target, ESP32_S2_SWD_CONF_REG, &swd_conf_reg);
550 if (res != ERROR_OK) {
551 LOG_ERROR("Failed to read ESP32_S2_SWD_CONF_REG (%d)!", res);
554 swd_conf_reg |= ESP32_S2_SWD_AUTO_FEED_EN_M;
555 res = target_write_u32(target, ESP32_S2_SWD_CONF_REG, swd_conf_reg);
556 if (res != ERROR_OK) {
557 LOG_ERROR("Failed to write ESP32_S2_SWD_CONF_REG (%d)!", res);
563 static int esp32s2_arch_state(struct target *target)
568 static int esp32s2_on_halt(struct target *target)
570 return esp32s2_disable_wdts(target);
573 static int esp32s2_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)
575 int ret = xtensa_step(target, current, address, handle_breakpoints);
576 if (ret == ERROR_OK) {
577 esp32s2_on_halt(target);
578 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
583 static int esp32s2_poll(struct target *target)
585 enum target_state old_state = target->state;
586 int ret = esp_xtensa_poll(target);
588 if (old_state != TARGET_HALTED && target->state == TARGET_HALTED) {
589 /* Call any event callbacks that are applicable */
590 if (old_state == TARGET_DEBUG_RUNNING) {
591 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
593 esp32s2_on_halt(target);
594 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
601 static int esp32s2_virt2phys(struct target *target,
602 target_addr_t virtual, target_addr_t *physical)
608 static int esp32s2_target_init(struct command_context *cmd_ctx, struct target *target)
610 return esp_xtensa_target_init(cmd_ctx, target);
613 static const struct xtensa_debug_ops esp32s2_dbg_ops = {
614 .queue_enable = xtensa_dm_queue_enable,
615 .queue_reg_read = xtensa_dm_queue_reg_read,
616 .queue_reg_write = xtensa_dm_queue_reg_write
619 static const struct xtensa_power_ops esp32s2_pwr_ops = {
620 .queue_reg_read = xtensa_dm_queue_pwr_reg_read,
621 .queue_reg_write = xtensa_dm_queue_pwr_reg_write
624 static int esp32s2_target_create(struct target *target, Jim_Interp *interp)
626 struct xtensa_debug_module_config esp32s2_dm_cfg = {
627 .dbg_ops = &esp32s2_dbg_ops,
628 .pwr_ops = &esp32s2_pwr_ops,
630 .queue_tdi_idle = NULL,
631 .queue_tdi_idle_arg = NULL
634 /* creates xtensa object */
635 struct esp32s2_common *esp32 = calloc(1, sizeof(*esp32));
637 LOG_ERROR("Failed to alloc memory for arch info!");
641 int ret = esp_xtensa_init_arch_info(target, &esp32->esp_xtensa, &esp32s2_xtensa_cfg, &esp32s2_dm_cfg);
642 if (ret != ERROR_OK) {
643 LOG_ERROR("Failed to init arch info!");
648 /* Assume running target. If different, the first poll will fix this */
649 target->state = TARGET_RUNNING;
650 target->debug_reason = DBG_REASON_NOTHALTED;
654 static const struct command_registration esp32s2_command_handlers[] = {
658 .help = "Xtensa commands group",
660 .chain = xtensa_command_handlers,
662 COMMAND_REGISTRATION_DONE
665 /* Holds methods for Xtensa targets. */
666 struct target_type esp32s2_target = {
669 .poll = esp32s2_poll,
670 .arch_state = esp32s2_arch_state,
673 .resume = xtensa_resume,
674 .step = esp32s2_step,
676 .assert_reset = esp32s2_assert_reset,
677 .deassert_reset = esp32s2_deassert_reset,
678 .soft_reset_halt = esp32s2_soft_reset_halt,
680 .virt2phys = esp32s2_virt2phys,
681 .mmu = xtensa_mmu_is_enabled,
682 .read_memory = xtensa_read_memory,
683 .write_memory = xtensa_write_memory,
685 .read_buffer = xtensa_read_buffer,
686 .write_buffer = xtensa_write_buffer,
688 .checksum_memory = xtensa_checksum_memory,
690 .get_gdb_arch = xtensa_get_gdb_arch,
691 .get_gdb_reg_list = xtensa_get_gdb_reg_list,
693 .add_breakpoint = esp_xtensa_breakpoint_add,
694 .remove_breakpoint = esp_xtensa_breakpoint_remove,
696 .add_watchpoint = xtensa_watchpoint_add,
697 .remove_watchpoint = xtensa_watchpoint_remove,
699 .target_create = esp32s2_target_create,
700 .init_target = esp32s2_target_init,
701 .examine = xtensa_examine,
702 .deinit_target = esp_xtensa_target_deinit,
704 .commands = esp32s2_command_handlers,