1 /***************************************************************************
2 * ESP32-S2 target for OpenOCD *
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 ***************************************************************************/
24 #include <helper/time_support.h>
26 #include <target/target.h>
27 #include <target/target_type.h>
28 #include "esp_xtensa.h"
32 * TODO: read memory configuration from target registers */
33 #define ESP32_S2_IROM_MASK_LOW 0x40000000
34 #define ESP32_S2_IROM_MASK_HIGH 0x40020000
35 #define ESP32_S2_IRAM_LOW 0x40020000
36 #define ESP32_S2_IRAM_HIGH 0x40070000
37 #define ESP32_S2_DRAM_LOW 0x3ffb0000
38 #define ESP32_S2_DRAM_HIGH 0x40000000
39 #define ESP32_S2_RTC_IRAM_LOW 0x40070000
40 #define ESP32_S2_RTC_IRAM_HIGH 0x40072000
41 #define ESP32_S2_RTC_DRAM_LOW 0x3ff9e000
42 #define ESP32_S2_RTC_DRAM_HIGH 0x3ffa0000
43 #define ESP32_S2_RTC_DATA_LOW 0x50000000
44 #define ESP32_S2_RTC_DATA_HIGH 0x50002000
45 #define ESP32_S2_EXTRAM_DATA_LOW 0x3f500000
46 #define ESP32_S2_EXTRAM_DATA_HIGH 0x3ff80000
47 #define ESP32_S2_DR_REG_LOW 0x3f400000
48 #define ESP32_S2_DR_REG_HIGH 0x3f4d3FFC
49 #define ESP32_S2_SYS_RAM_LOW 0x60000000UL
50 #define ESP32_S2_SYS_RAM_HIGH (ESP32_S2_SYS_RAM_LOW + 0x20000000UL)
51 /* ESP32-S2 DROM mapping is not contiguous. */
52 /* IDF declares this as 0x3F000000..0x3FF80000, but there are peripheral registers mapped to
53 * 0x3f400000..0x3f4d3FFC. */
54 #define ESP32_S2_DROM0_LOW ESP32_S2_DROM_LOW
55 #define ESP32_S2_DROM0_HIGH ESP32_S2_DR_REG_LOW
56 #define ESP32_S2_DROM1_LOW ESP32_S2_DR_REG_HIGH
57 #define ESP32_S2_DROM1_HIGH ESP32_S2_DROM_HIGH
60 #define ESP32_S2_WDT_WKEY_VALUE 0x50d83aa1
61 #define ESP32_S2_TIMG0_BASE 0x3f41F000
62 #define ESP32_S2_TIMG1_BASE 0x3f420000
63 #define ESP32_S2_TIMGWDT_CFG0_OFF 0x48
64 #define ESP32_S2_TIMGWDT_PROTECT_OFF 0x64
65 #define ESP32_S2_TIMG0WDT_CFG0 (ESP32_S2_TIMG0_BASE + ESP32_S2_TIMGWDT_CFG0_OFF)
66 #define ESP32_S2_TIMG1WDT_CFG0 (ESP32_S2_TIMG1_BASE + ESP32_S2_TIMGWDT_CFG0_OFF)
67 #define ESP32_S2_TIMG0WDT_PROTECT (ESP32_S2_TIMG0_BASE + ESP32_S2_TIMGWDT_PROTECT_OFF)
68 #define ESP32_S2_TIMG1WDT_PROTECT (ESP32_S2_TIMG1_BASE + ESP32_S2_TIMGWDT_PROTECT_OFF)
69 #define ESP32_S2_RTCCNTL_BASE 0x3f408000
70 #define ESP32_S2_RTCWDT_CFG_OFF 0x94
71 #define ESP32_S2_RTCWDT_PROTECT_OFF 0xAC
72 #define ESP32_S2_SWD_CONF_OFF 0xB0
73 #define ESP32_S2_SWD_WPROTECT_OFF 0xB4
74 #define ESP32_S2_RTC_CNTL_DIG_PWC_REG_OFF 0x8C
75 #define ESP32_S2_RTC_CNTL_DIG_PWC_REG (ESP32_S2_RTCCNTL_BASE + ESP32_S2_RTC_CNTL_DIG_PWC_REG_OFF)
76 #define ESP32_S2_RTCWDT_CFG (ESP32_S2_RTCCNTL_BASE + ESP32_S2_RTCWDT_CFG_OFF)
77 #define ESP32_S2_RTCWDT_PROTECT (ESP32_S2_RTCCNTL_BASE + ESP32_S2_RTCWDT_PROTECT_OFF)
78 #define ESP32_S2_SWD_CONF_REG (ESP32_S2_RTCCNTL_BASE + ESP32_S2_SWD_CONF_OFF)
79 #define ESP32_S2_SWD_WPROTECT_REG (ESP32_S2_RTCCNTL_BASE + ESP32_S2_SWD_WPROTECT_OFF)
80 #define ESP32_S2_SWD_AUTO_FEED_EN_M BIT(31)
81 #define ESP32_S2_SWD_WKEY_VALUE 0x8F1D312AU
82 #define ESP32_S2_OPTIONS0 (ESP32_S2_RTCCNTL_BASE + 0x0000)
83 #define ESP32_S2_SW_SYS_RST_M 0x80000000
84 #define ESP32_S2_SW_SYS_RST_V 0x1
85 #define ESP32_S2_SW_SYS_RST_S 31
86 #define ESP32_S2_SW_STALL_PROCPU_C0_M ((ESP32_S2_SW_STALL_PROCPU_C0_V) << (ESP32_S2_SW_STALL_PROCPU_C0_S))
87 #define ESP32_S2_SW_STALL_PROCPU_C0_V 0x3
88 #define ESP32_S2_SW_STALL_PROCPU_C0_S 2
89 #define ESP32_S2_SW_CPU_STALL (ESP32_S2_RTCCNTL_BASE + 0x00B8)
90 #define ESP32_S2_SW_STALL_PROCPU_C1_M ((ESP32_S2_SW_STALL_PROCPU_C1_V) << (ESP32_S2_SW_STALL_PROCPU_C1_S))
91 #define ESP32_S2_SW_STALL_PROCPU_C1_V 0x3FU
92 #define ESP32_S2_SW_STALL_PROCPU_C1_S 26
93 #define ESP32_S2_CLK_CONF (ESP32_S2_RTCCNTL_BASE + 0x0074)
94 #define ESP32_S2_CLK_CONF_DEF 0x1583218
95 #define ESP32_S2_STORE4 (ESP32_S2_RTCCNTL_BASE + 0x00BC)
96 #define ESP32_S2_STORE5 (ESP32_S2_RTCCNTL_BASE + 0x00C0)
97 #define ESP32_S2_DPORT_PMS_OCCUPY_3 0x3F4C10E0
99 #define ESP32_S2_TRACEMEM_BLOCK_SZ 0x4000
101 #define ESP32_S2_DR_REG_UART_BASE 0x3f400000
102 #define ESP32_S2_REG_UART_BASE(i) (ESP32_S2_DR_REG_UART_BASE + (i) * 0x10000)
103 #define ESP32_S2_UART_DATE_REG(i) (ESP32_S2_REG_UART_BASE(i) + 0x74)
105 /* this should map local reg IDs to GDB reg mapping as defined in xtensa-config.c 'rmap' in
107 static const unsigned int esp32s2_gdb_regs_mapping[ESP32_S2_NUM_REGS] = {
109 XT_REG_IDX_AR0, XT_REG_IDX_AR1, XT_REG_IDX_AR2, XT_REG_IDX_AR3,
110 XT_REG_IDX_AR4, XT_REG_IDX_AR5, XT_REG_IDX_AR6, XT_REG_IDX_AR7,
111 XT_REG_IDX_AR8, XT_REG_IDX_AR9, XT_REG_IDX_AR10, XT_REG_IDX_AR11,
112 XT_REG_IDX_AR12, XT_REG_IDX_AR13, XT_REG_IDX_AR14, XT_REG_IDX_AR15,
113 XT_REG_IDX_AR16, XT_REG_IDX_AR17, XT_REG_IDX_AR18, XT_REG_IDX_AR19,
114 XT_REG_IDX_AR20, XT_REG_IDX_AR21, XT_REG_IDX_AR22, XT_REG_IDX_AR23,
115 XT_REG_IDX_AR24, XT_REG_IDX_AR25, XT_REG_IDX_AR26, XT_REG_IDX_AR27,
116 XT_REG_IDX_AR28, XT_REG_IDX_AR29, XT_REG_IDX_AR30, XT_REG_IDX_AR31,
117 XT_REG_IDX_AR32, XT_REG_IDX_AR33, XT_REG_IDX_AR34, XT_REG_IDX_AR35,
118 XT_REG_IDX_AR36, XT_REG_IDX_AR37, XT_REG_IDX_AR38, XT_REG_IDX_AR39,
119 XT_REG_IDX_AR40, XT_REG_IDX_AR41, XT_REG_IDX_AR42, XT_REG_IDX_AR43,
120 XT_REG_IDX_AR44, XT_REG_IDX_AR45, XT_REG_IDX_AR46, XT_REG_IDX_AR47,
121 XT_REG_IDX_AR48, XT_REG_IDX_AR49, XT_REG_IDX_AR50, XT_REG_IDX_AR51,
122 XT_REG_IDX_AR52, XT_REG_IDX_AR53, XT_REG_IDX_AR54, XT_REG_IDX_AR55,
123 XT_REG_IDX_AR56, XT_REG_IDX_AR57, XT_REG_IDX_AR58, XT_REG_IDX_AR59,
124 XT_REG_IDX_AR60, XT_REG_IDX_AR61, XT_REG_IDX_AR62, XT_REG_IDX_AR63,
126 XT_REG_IDX_WINDOWBASE, XT_REG_IDX_WINDOWSTART, XT_REG_IDX_CONFIGID0, XT_REG_IDX_CONFIGID1,
127 XT_REG_IDX_PS, XT_REG_IDX_THREADPTR,
128 ESP32_S2_REG_IDX_GPIOOUT,
129 XT_REG_IDX_MMID, XT_REG_IDX_IBREAKENABLE, XT_REG_IDX_OCD_DDR,
130 XT_REG_IDX_IBREAKA0, XT_REG_IDX_IBREAKA1, XT_REG_IDX_DBREAKA0, XT_REG_IDX_DBREAKA1,
131 XT_REG_IDX_DBREAKC0, XT_REG_IDX_DBREAKC1,
132 XT_REG_IDX_EPC1, XT_REG_IDX_EPC2, XT_REG_IDX_EPC3, XT_REG_IDX_EPC4,
133 XT_REG_IDX_EPC5, XT_REG_IDX_EPC6, XT_REG_IDX_EPC7, XT_REG_IDX_DEPC,
134 XT_REG_IDX_EPS2, XT_REG_IDX_EPS3, XT_REG_IDX_EPS4, XT_REG_IDX_EPS5,
135 XT_REG_IDX_EPS6, XT_REG_IDX_EPS7,
136 XT_REG_IDX_EXCSAVE1, XT_REG_IDX_EXCSAVE2, XT_REG_IDX_EXCSAVE3, XT_REG_IDX_EXCSAVE4,
137 XT_REG_IDX_EXCSAVE5, XT_REG_IDX_EXCSAVE6, XT_REG_IDX_EXCSAVE7, XT_REG_IDX_CPENABLE,
138 XT_REG_IDX_INTERRUPT, XT_REG_IDX_INTSET, XT_REG_IDX_INTCLEAR, XT_REG_IDX_INTENABLE,
139 XT_REG_IDX_VECBASE, XT_REG_IDX_EXCCAUSE, XT_REG_IDX_DEBUGCAUSE, XT_REG_IDX_CCOUNT,
140 XT_REG_IDX_PRID, XT_REG_IDX_ICOUNT, XT_REG_IDX_ICOUNTLEVEL, XT_REG_IDX_EXCVADDR,
141 XT_REG_IDX_CCOMPARE0, XT_REG_IDX_CCOMPARE1, XT_REG_IDX_CCOMPARE2,
142 XT_REG_IDX_MISC0, XT_REG_IDX_MISC1, XT_REG_IDX_MISC2, XT_REG_IDX_MISC3,
143 XT_REG_IDX_A0, XT_REG_IDX_A1, XT_REG_IDX_A2, XT_REG_IDX_A3,
144 XT_REG_IDX_A4, XT_REG_IDX_A5, XT_REG_IDX_A6, XT_REG_IDX_A7,
145 XT_REG_IDX_A8, XT_REG_IDX_A9, XT_REG_IDX_A10, XT_REG_IDX_A11,
146 XT_REG_IDX_A12, XT_REG_IDX_A13, XT_REG_IDX_A14, XT_REG_IDX_A15,
147 XT_REG_IDX_PWRCTL, XT_REG_IDX_PWRSTAT, XT_REG_IDX_ERISTAT,
148 XT_REG_IDX_CS_ITCTRL, XT_REG_IDX_CS_CLAIMSET, XT_REG_IDX_CS_CLAIMCLR,
149 XT_REG_IDX_CS_LOCKACCESS, XT_REG_IDX_CS_LOCKSTATUS, XT_REG_IDX_CS_AUTHSTATUS,
150 XT_REG_IDX_FAULT_INFO,
151 XT_REG_IDX_TRAX_ID, XT_REG_IDX_TRAX_CTRL, XT_REG_IDX_TRAX_STAT,
152 XT_REG_IDX_TRAX_DATA, XT_REG_IDX_TRAX_ADDR, XT_REG_IDX_TRAX_PCTRIGGER,
153 XT_REG_IDX_TRAX_PCMATCH, XT_REG_IDX_TRAX_DELAY, XT_REG_IDX_TRAX_MEMSTART,
154 XT_REG_IDX_TRAX_MEMEND,
155 XT_REG_IDX_PMG, XT_REG_IDX_PMPC, XT_REG_IDX_PM0, XT_REG_IDX_PM1,
156 XT_REG_IDX_PMCTRL0, XT_REG_IDX_PMCTRL1, XT_REG_IDX_PMSTAT0, XT_REG_IDX_PMSTAT1,
157 XT_REG_IDX_OCD_ID, XT_REG_IDX_OCD_DCRCLR, XT_REG_IDX_OCD_DCRSET, XT_REG_IDX_OCD_DSR,
160 static const struct xtensa_user_reg_desc esp32s2_user_regs[ESP32_S2_NUM_REGS - XT_NUM_REGS] = {
161 { "gpio_out", 0x00, 0, 32, &xtensa_user_reg_u32_type },
164 static const struct xtensa_config esp32s2_xtensa_cfg = {
166 .aregs_num = XT_AREGS_NUM_MAX,
173 .user_regs_num = ARRAY_SIZE(esp32s2_user_regs),
174 .user_regs = esp32s2_user_regs,
175 .fetch_user_regs = xtensa_fetch_user_regs_u32,
176 .queue_write_dirty_user_regs = xtensa_queue_write_dirty_user_regs_u32,
177 .gdb_general_regs_num = ESP32_S2_NUM_REGS_G_COMMAND,
178 .gdb_regs_mapping = esp32s2_gdb_regs_mapping,
183 .base = ESP32_S2_IROM_LOW,
184 .size = ESP32_S2_IROM_HIGH - ESP32_S2_IROM_LOW,
185 .access = XT_MEM_ACCESS_READ,
188 .base = ESP32_S2_IROM_MASK_LOW,
189 .size = ESP32_S2_IROM_MASK_HIGH - ESP32_S2_IROM_MASK_LOW,
190 .access = XT_MEM_ACCESS_READ,
198 .base = ESP32_S2_IRAM_LOW,
199 .size = ESP32_S2_IRAM_HIGH - ESP32_S2_IRAM_LOW,
200 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
203 .base = ESP32_S2_RTC_IRAM_LOW,
204 .size = ESP32_S2_RTC_IRAM_HIGH - ESP32_S2_RTC_IRAM_LOW,
205 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
213 .base = ESP32_S2_DROM0_LOW,
214 .size = ESP32_S2_DROM0_HIGH - ESP32_S2_DROM0_LOW,
215 .access = XT_MEM_ACCESS_READ,
218 .base = ESP32_S2_DROM1_LOW,
219 .size = ESP32_S2_DROM1_HIGH - ESP32_S2_DROM1_LOW,
220 .access = XT_MEM_ACCESS_READ,
228 .base = ESP32_S2_DRAM_LOW,
229 .size = ESP32_S2_DRAM_HIGH - ESP32_S2_DRAM_LOW,
230 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
233 .base = ESP32_S2_RTC_DRAM_LOW,
234 .size = ESP32_S2_RTC_DRAM_HIGH - ESP32_S2_RTC_DRAM_LOW,
235 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
238 .base = ESP32_S2_RTC_DATA_LOW,
239 .size = ESP32_S2_RTC_DATA_HIGH - ESP32_S2_RTC_DATA_LOW,
240 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
243 .base = ESP32_S2_EXTRAM_DATA_LOW,
244 .size = ESP32_S2_EXTRAM_DATA_HIGH - ESP32_S2_EXTRAM_DATA_LOW,
245 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
248 .base = ESP32_S2_DR_REG_LOW,
249 .size = ESP32_S2_DR_REG_HIGH - ESP32_S2_DR_REG_LOW,
250 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
253 .base = ESP32_S2_SYS_RAM_LOW,
254 .size = ESP32_S2_SYS_RAM_HIGH - ESP32_S2_SYS_RAM_LOW,
255 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
284 .mem_sz = ESP32_S2_TRACEMEM_BLOCK_SZ,
288 struct esp32s2_common {
289 struct esp_xtensa_common esp_xtensa;
292 static int esp32s2_soc_reset(struct target *target);
293 static int esp32s2_disable_wdts(struct target *target);
295 static int esp32s2_assert_reset(struct target *target)
300 static int esp32s2_deassert_reset(struct target *target)
302 struct xtensa *xtensa = target_to_xtensa(target);
304 LOG_TARGET_DEBUG(target, "begin");
306 int res = xtensa_deassert_reset(target);
310 /* restore configured value
311 esp32s2_soc_reset() modified it, but can not restore just after SW reset for some reason (???) */
312 res = xtensa_smpbreak_write(xtensa, xtensa->smp_break);
313 if (res != ERROR_OK) {
314 LOG_ERROR("Failed to restore smpbreak (%d)!", res);
320 int esp32s2_soft_reset_halt(struct target *target)
322 LOG_TARGET_DEBUG(target, "begin");
324 /* Reset the SoC first */
325 int res = esp32s2_soc_reset(target);
328 return xtensa_assert_reset(target);
331 static int esp32s2_set_peri_reg_mask(struct target *target,
337 int res = target_read_u32(target, addr, ®_val);
340 reg_val = (reg_val & (~mask)) | val;
341 res = target_write_u32(target, addr, reg_val);
348 static int esp32s2_stall_set(struct target *target, bool stall)
350 LOG_TARGET_DEBUG(target, "begin");
352 int res = esp32s2_set_peri_reg_mask(target,
353 ESP32_S2_SW_CPU_STALL,
354 ESP32_S2_SW_STALL_PROCPU_C1_M,
355 stall ? 0x21U << ESP32_S2_SW_STALL_PROCPU_C1_S : 0);
356 if (res != ERROR_OK) {
357 LOG_ERROR("Failed to write ESP32_S2_SW_CPU_STALL (%d)!", res);
360 res = esp32s2_set_peri_reg_mask(target,
362 ESP32_S2_SW_STALL_PROCPU_C0_M,
363 stall ? 0x2 << ESP32_S2_SW_STALL_PROCPU_C0_S : 0);
364 if (res != ERROR_OK) {
365 LOG_ERROR("Failed to write ESP32_S2_OPTIONS0 (%d)!", res);
371 static inline int esp32s2_stall(struct target *target)
373 return esp32s2_stall_set(target, true);
376 static inline int esp32s2_unstall(struct target *target)
378 return esp32s2_stall_set(target, false);
381 /* Reset ESP32-S2's peripherals.
382 Postconditions: all peripherals except RTC_CNTL are reset, CPU's PC is undefined, PRO CPU is halted, APP CPU is in reset
384 0. make sure target is halted; if not, try to halt it; if that fails, try to reset it (via OCD) and then halt
385 1. Resets clock related registers
387 3. trigger SoC reset using RTC_CNTL_SW_SYS_RST bit
388 4. CPU is reset and stalled at the first reset vector instruction
389 5. wait for the OCD to be reset
392 8. Disables WDTs and trace memory mapping
394 static int esp32s2_soc_reset(struct target *target)
397 struct xtensa *xtensa = target_to_xtensa(target);
401 /* In order to write to peripheral registers, target must be halted first */
402 if (target->state != TARGET_HALTED) {
403 LOG_TARGET_DEBUG(target, "Target not halted before SoC reset, trying to halt it first");
405 res = target_wait_state(target, TARGET_HALTED, 1000);
406 if (res != ERROR_OK) {
407 LOG_TARGET_DEBUG(target, "Couldn't halt target before SoC reset, trying to do reset-halt");
408 res = xtensa_assert_reset(target);
409 if (res != ERROR_OK) {
412 "Couldn't halt target before SoC reset! (xtensa_assert_reset returned %d)",
418 int reset_halt_save = target->reset_halt;
419 target->reset_halt = 1;
420 res = xtensa_deassert_reset(target);
421 target->reset_halt = reset_halt_save;
422 if (res != ERROR_OK) {
425 "Couldn't halt target before SoC reset! (xtensa_deassert_reset returned %d)",
432 res = target_wait_state(target, TARGET_HALTED, 1000);
433 if (res != ERROR_OK) {
434 LOG_TARGET_ERROR(target, "Couldn't halt target before SoC reset");
440 assert(target->state == TARGET_HALTED);
442 /* Set some clock-related RTC registers to the default values */
443 res = target_write_u32(target, ESP32_S2_STORE4, 0);
444 if (res != ERROR_OK) {
445 LOG_ERROR("Failed to write ESP32_S2_STORE4 (%d)!", res);
448 res = target_write_u32(target, ESP32_S2_STORE5, 0);
449 if (res != ERROR_OK) {
450 LOG_ERROR("Failed to write ESP32_S2_STORE5 (%d)!", res);
453 res = target_write_u32(target, ESP32_S2_RTC_CNTL_DIG_PWC_REG, 0);
454 if (res != ERROR_OK) {
455 LOG_ERROR("Failed to write ESP32_S2_RTC_CNTL_DIG_PWC_REG (%d)!", res);
458 res = target_write_u32(target, ESP32_S2_CLK_CONF, ESP32_S2_CLK_CONF_DEF);
459 if (res != ERROR_OK) {
460 LOG_ERROR("Failed to write ESP32_S2_CLK_CONF (%d)!", res);
464 res = esp32s2_stall(target);
468 res = xtensa_smpbreak_write(xtensa, OCDDCR_RUNSTALLINEN);
469 if (res != ERROR_OK) {
470 LOG_ERROR("Failed to set smpbreak (%d)!", res);
474 xtensa->suppress_dsr_errors = true;
475 res = esp32s2_set_peri_reg_mask(target,
477 ESP32_S2_SW_SYS_RST_M,
478 BIT(ESP32_S2_SW_SYS_RST_S));
479 xtensa->suppress_dsr_errors = false;
480 if (res != ERROR_OK) {
481 LOG_ERROR("Failed to write ESP32_S2_OPTIONS0 (%d)!", res);
484 /* Wait for SoC to reset */
486 int64_t timeout = timeval_ms() + 100;
487 while (target->state != TARGET_RESET && target->state != TARGET_RUNNING) {
490 if (timeval_ms() >= timeout) {
491 LOG_TARGET_ERROR(target, "Timed out waiting for CPU to be reset, target state=%d", target->state);
492 return ERROR_TARGET_TIMEOUT;
497 res = target_wait_state(target, TARGET_HALTED, 1000);
498 if (res != ERROR_OK) {
499 LOG_TARGET_ERROR(target, "Couldn't halt target before SoC reset");
503 res = esp32s2_unstall(target);
507 res = esp32s2_disable_wdts(target);
510 /* Disable trace memory mapping */
511 res = target_write_u32(target, ESP32_S2_DPORT_PMS_OCCUPY_3, 0);
512 if (res != ERROR_OK) {
513 LOG_ERROR("Failed to write ESP32_S2_DPORT_PMS_OCCUPY_3 (%d)!", res);
519 static int esp32s2_disable_wdts(struct target *target)
522 int res = target_write_u32(target, ESP32_S2_TIMG0WDT_PROTECT, ESP32_S2_WDT_WKEY_VALUE);
523 if (res != ERROR_OK) {
524 LOG_ERROR("Failed to write ESP32_S2_TIMG0WDT_PROTECT (%d)!", res);
527 res = target_write_u32(target, ESP32_S2_TIMG0WDT_CFG0, 0);
528 if (res != ERROR_OK) {
529 LOG_ERROR("Failed to write ESP32_S2_TIMG0WDT_CFG0 (%d)!", res);
533 res = target_write_u32(target, ESP32_S2_TIMG1WDT_PROTECT, ESP32_S2_WDT_WKEY_VALUE);
534 if (res != ERROR_OK) {
535 LOG_ERROR("Failed to write ESP32_S2_TIMG1WDT_PROTECT (%d)!", res);
538 res = target_write_u32(target, ESP32_S2_TIMG1WDT_CFG0, 0);
539 if (res != ERROR_OK) {
540 LOG_ERROR("Failed to write ESP32_S2_TIMG1WDT_CFG0 (%d)!", res);
544 res = target_write_u32(target, ESP32_S2_RTCWDT_PROTECT, ESP32_S2_WDT_WKEY_VALUE);
545 if (res != ERROR_OK) {
546 LOG_ERROR("Failed to write ESP32_S2_RTCWDT_PROTECT (%d)!", res);
549 res = target_write_u32(target, ESP32_S2_RTCWDT_CFG, 0);
550 if (res != ERROR_OK) {
551 LOG_ERROR("Failed to write ESP32_S2_RTCWDT_CFG (%d)!", res);
554 /* Enable SWD auto-feed */
555 res = target_write_u32(target, ESP32_S2_SWD_WPROTECT_REG, ESP32_S2_SWD_WKEY_VALUE);
556 if (res != ERROR_OK) {
557 LOG_ERROR("Failed to write ESP32_S2_SWD_WPROTECT_REG (%d)!", res);
560 uint32_t swd_conf_reg = 0;
561 res = target_read_u32(target, ESP32_S2_SWD_CONF_REG, &swd_conf_reg);
562 if (res != ERROR_OK) {
563 LOG_ERROR("Failed to read ESP32_S2_SWD_CONF_REG (%d)!", res);
566 swd_conf_reg |= ESP32_S2_SWD_AUTO_FEED_EN_M;
567 res = target_write_u32(target, ESP32_S2_SWD_CONF_REG, swd_conf_reg);
568 if (res != ERROR_OK) {
569 LOG_ERROR("Failed to write ESP32_S2_SWD_CONF_REG (%d)!", res);
575 static int esp32s2_arch_state(struct target *target)
580 static int esp32s2_on_halt(struct target *target)
582 return esp32s2_disable_wdts(target);
585 static int esp32s2_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)
587 int ret = xtensa_step(target, current, address, handle_breakpoints);
588 if (ret == ERROR_OK) {
589 esp32s2_on_halt(target);
590 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
595 static int esp32s2_poll(struct target *target)
597 enum target_state old_state = target->state;
598 int ret = esp_xtensa_poll(target);
600 if (old_state != TARGET_HALTED && target->state == TARGET_HALTED) {
601 /* Call any event callbacks that are applicable */
602 if (old_state == TARGET_DEBUG_RUNNING) {
603 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
605 esp32s2_on_halt(target);
606 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
613 static int esp32s2_virt2phys(struct target *target,
614 target_addr_t virtual, target_addr_t *physical)
620 static int esp32s2_target_init(struct command_context *cmd_ctx, struct target *target)
622 return esp_xtensa_target_init(cmd_ctx, target);
625 static const struct xtensa_debug_ops esp32s2_dbg_ops = {
626 .queue_enable = xtensa_dm_queue_enable,
627 .queue_reg_read = xtensa_dm_queue_reg_read,
628 .queue_reg_write = xtensa_dm_queue_reg_write
631 static const struct xtensa_power_ops esp32s2_pwr_ops = {
632 .queue_reg_read = xtensa_dm_queue_pwr_reg_read,
633 .queue_reg_write = xtensa_dm_queue_pwr_reg_write
636 static int esp32s2_target_create(struct target *target, Jim_Interp *interp)
638 struct xtensa_debug_module_config esp32s2_dm_cfg = {
639 .dbg_ops = &esp32s2_dbg_ops,
640 .pwr_ops = &esp32s2_pwr_ops,
642 .queue_tdi_idle = NULL,
643 .queue_tdi_idle_arg = NULL
646 /* creates xtensa object */
647 struct esp32s2_common *esp32 = calloc(1, sizeof(*esp32));
649 LOG_ERROR("Failed to alloc memory for arch info!");
653 int ret = esp_xtensa_init_arch_info(target, &esp32->esp_xtensa, &esp32s2_xtensa_cfg, &esp32s2_dm_cfg);
654 if (ret != ERROR_OK) {
655 LOG_ERROR("Failed to init arch info!");
660 /* Assume running target. If different, the first poll will fix this */
661 target->state = TARGET_RUNNING;
662 target->debug_reason = DBG_REASON_NOTHALTED;
666 static const struct command_registration esp32s2_command_handlers[] = {
670 .help = "Xtensa commands group",
672 .chain = xtensa_command_handlers,
674 COMMAND_REGISTRATION_DONE
677 /* Holds methods for Xtensa targets. */
678 struct target_type esp32s2_target = {
681 .poll = esp32s2_poll,
682 .arch_state = esp32s2_arch_state,
685 .resume = xtensa_resume,
686 .step = esp32s2_step,
688 .assert_reset = esp32s2_assert_reset,
689 .deassert_reset = esp32s2_deassert_reset,
690 .soft_reset_halt = esp32s2_soft_reset_halt,
692 .virt2phys = esp32s2_virt2phys,
693 .mmu = xtensa_mmu_is_enabled,
694 .read_memory = xtensa_read_memory,
695 .write_memory = xtensa_write_memory,
697 .read_buffer = xtensa_read_buffer,
698 .write_buffer = xtensa_write_buffer,
700 .checksum_memory = xtensa_checksum_memory,
702 .get_gdb_arch = xtensa_get_gdb_arch,
703 .get_gdb_reg_list = xtensa_get_gdb_reg_list,
705 .add_breakpoint = esp_xtensa_breakpoint_add,
706 .remove_breakpoint = esp_xtensa_breakpoint_remove,
708 .add_watchpoint = xtensa_watchpoint_add,
709 .remove_watchpoint = xtensa_watchpoint_remove,
711 .target_create = esp32s2_target_create,
712 .init_target = esp32s2_target_init,
713 .examine = xtensa_examine,
714 .deinit_target = esp_xtensa_target_deinit,
716 .commands = esp32s2_command_handlers,