openocd: src/target: replace the GPL-2.0-or-later license tag
[fw/openocd] / src / target / espressif / esp32s2.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /***************************************************************************
4  *   ESP32-S2 target for OpenOCD                                           *
5  *   Copyright (C) 2019 Espressif Systems Ltd.                             *
6  *   Author: Alexey Gerenkov <alexey@espressif.com>                        *
7  ***************************************************************************/
8
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12
13 #include <helper/time_support.h>
14 #include "assert.h"
15 #include <target/target.h>
16 #include <target/target_type.h>
17 #include "esp_xtensa.h"
18 #include "esp32s2.h"
19
20 /* Overall memory map
21  * TODO: read memory configuration from target registers */
22 #define ESP32_S2_IROM_MASK_LOW          0x40000000
23 #define ESP32_S2_IROM_MASK_HIGH         0x40020000
24 #define ESP32_S2_IRAM_LOW               0x40020000
25 #define ESP32_S2_IRAM_HIGH              0x40070000
26 #define ESP32_S2_DRAM_LOW               0x3ffb0000
27 #define ESP32_S2_DRAM_HIGH              0x40000000
28 #define ESP32_S2_RTC_IRAM_LOW           0x40070000
29 #define ESP32_S2_RTC_IRAM_HIGH          0x40072000
30 #define ESP32_S2_RTC_DRAM_LOW           0x3ff9e000
31 #define ESP32_S2_RTC_DRAM_HIGH          0x3ffa0000
32 #define ESP32_S2_RTC_DATA_LOW           0x50000000
33 #define ESP32_S2_RTC_DATA_HIGH          0x50002000
34 #define ESP32_S2_EXTRAM_DATA_LOW        0x3f500000
35 #define ESP32_S2_EXTRAM_DATA_HIGH       0x3ff80000
36 #define ESP32_S2_DR_REG_LOW             0x3f400000
37 #define ESP32_S2_DR_REG_HIGH            0x3f4d3FFC
38 #define ESP32_S2_SYS_RAM_LOW            0x60000000UL
39 #define ESP32_S2_SYS_RAM_HIGH           (ESP32_S2_SYS_RAM_LOW + 0x20000000UL)
40 /* ESP32-S2 DROM mapping is not contiguous. */
41 /* IDF declares this as 0x3F000000..0x3FF80000, but there are peripheral registers mapped to
42  * 0x3f400000..0x3f4d3FFC. */
43 #define ESP32_S2_DROM0_LOW              ESP32_S2_DROM_LOW
44 #define ESP32_S2_DROM0_HIGH             ESP32_S2_DR_REG_LOW
45 #define ESP32_S2_DROM1_LOW              ESP32_S2_DR_REG_HIGH
46 #define ESP32_S2_DROM1_HIGH             ESP32_S2_DROM_HIGH
47
48 /* ESP32 WDT */
49 #define ESP32_S2_WDT_WKEY_VALUE         0x50d83aa1
50 #define ESP32_S2_TIMG0_BASE             0x3f41F000
51 #define ESP32_S2_TIMG1_BASE             0x3f420000
52 #define ESP32_S2_TIMGWDT_CFG0_OFF       0x48
53 #define ESP32_S2_TIMGWDT_PROTECT_OFF    0x64
54 #define ESP32_S2_TIMG0WDT_CFG0          (ESP32_S2_TIMG0_BASE + ESP32_S2_TIMGWDT_CFG0_OFF)
55 #define ESP32_S2_TIMG1WDT_CFG0          (ESP32_S2_TIMG1_BASE + ESP32_S2_TIMGWDT_CFG0_OFF)
56 #define ESP32_S2_TIMG0WDT_PROTECT       (ESP32_S2_TIMG0_BASE + ESP32_S2_TIMGWDT_PROTECT_OFF)
57 #define ESP32_S2_TIMG1WDT_PROTECT       (ESP32_S2_TIMG1_BASE + ESP32_S2_TIMGWDT_PROTECT_OFF)
58 #define ESP32_S2_RTCCNTL_BASE           0x3f408000
59 #define ESP32_S2_RTCWDT_CFG_OFF         0x94
60 #define ESP32_S2_RTCWDT_PROTECT_OFF     0xAC
61 #define ESP32_S2_SWD_CONF_OFF           0xB0
62 #define ESP32_S2_SWD_WPROTECT_OFF       0xB4
63 #define ESP32_S2_RTC_CNTL_DIG_PWC_REG_OFF      0x8C
64 #define ESP32_S2_RTC_CNTL_DIG_PWC_REG   (ESP32_S2_RTCCNTL_BASE + ESP32_S2_RTC_CNTL_DIG_PWC_REG_OFF)
65 #define ESP32_S2_RTCWDT_CFG             (ESP32_S2_RTCCNTL_BASE + ESP32_S2_RTCWDT_CFG_OFF)
66 #define ESP32_S2_RTCWDT_PROTECT         (ESP32_S2_RTCCNTL_BASE + ESP32_S2_RTCWDT_PROTECT_OFF)
67 #define ESP32_S2_SWD_CONF_REG           (ESP32_S2_RTCCNTL_BASE + ESP32_S2_SWD_CONF_OFF)
68 #define ESP32_S2_SWD_WPROTECT_REG       (ESP32_S2_RTCCNTL_BASE + ESP32_S2_SWD_WPROTECT_OFF)
69 #define ESP32_S2_SWD_AUTO_FEED_EN_M     BIT(31)
70 #define ESP32_S2_SWD_WKEY_VALUE         0x8F1D312AU
71 #define ESP32_S2_OPTIONS0               (ESP32_S2_RTCCNTL_BASE + 0x0000)
72 #define ESP32_S2_SW_SYS_RST_M           0x80000000
73 #define ESP32_S2_SW_SYS_RST_V           0x1
74 #define ESP32_S2_SW_SYS_RST_S           31
75 #define ESP32_S2_SW_STALL_PROCPU_C0_M   ((ESP32_S2_SW_STALL_PROCPU_C0_V) << (ESP32_S2_SW_STALL_PROCPU_C0_S))
76 #define ESP32_S2_SW_STALL_PROCPU_C0_V   0x3
77 #define ESP32_S2_SW_STALL_PROCPU_C0_S   2
78 #define ESP32_S2_SW_CPU_STALL           (ESP32_S2_RTCCNTL_BASE + 0x00B8)
79 #define ESP32_S2_SW_STALL_PROCPU_C1_M   ((ESP32_S2_SW_STALL_PROCPU_C1_V) << (ESP32_S2_SW_STALL_PROCPU_C1_S))
80 #define ESP32_S2_SW_STALL_PROCPU_C1_V   0x3FU
81 #define ESP32_S2_SW_STALL_PROCPU_C1_S   26
82 #define ESP32_S2_CLK_CONF               (ESP32_S2_RTCCNTL_BASE + 0x0074)
83 #define ESP32_S2_CLK_CONF_DEF           0x1583218
84 #define ESP32_S2_STORE4                 (ESP32_S2_RTCCNTL_BASE + 0x00BC)
85 #define ESP32_S2_STORE5                 (ESP32_S2_RTCCNTL_BASE + 0x00C0)
86 #define ESP32_S2_DPORT_PMS_OCCUPY_3     0x3F4C10E0
87
88 #define ESP32_S2_TRACEMEM_BLOCK_SZ      0x4000
89
90 #define ESP32_S2_DR_REG_UART_BASE       0x3f400000
91 #define ESP32_S2_REG_UART_BASE(i)       (ESP32_S2_DR_REG_UART_BASE + (i) * 0x10000)
92 #define ESP32_S2_UART_DATE_REG(i)       (ESP32_S2_REG_UART_BASE(i) + 0x74)
93
94 /* this should map local reg IDs to GDB reg mapping as defined in xtensa-config.c 'rmap' in
95  * xtensa-overlay */
96 static const unsigned int esp32s2_gdb_regs_mapping[ESP32_S2_NUM_REGS] = {
97         XT_REG_IDX_PC,
98         XT_REG_IDX_AR0, XT_REG_IDX_AR1, XT_REG_IDX_AR2, XT_REG_IDX_AR3,
99         XT_REG_IDX_AR4, XT_REG_IDX_AR5, XT_REG_IDX_AR6, XT_REG_IDX_AR7,
100         XT_REG_IDX_AR8, XT_REG_IDX_AR9, XT_REG_IDX_AR10, XT_REG_IDX_AR11,
101         XT_REG_IDX_AR12, XT_REG_IDX_AR13, XT_REG_IDX_AR14, XT_REG_IDX_AR15,
102         XT_REG_IDX_AR16, XT_REG_IDX_AR17, XT_REG_IDX_AR18, XT_REG_IDX_AR19,
103         XT_REG_IDX_AR20, XT_REG_IDX_AR21, XT_REG_IDX_AR22, XT_REG_IDX_AR23,
104         XT_REG_IDX_AR24, XT_REG_IDX_AR25, XT_REG_IDX_AR26, XT_REG_IDX_AR27,
105         XT_REG_IDX_AR28, XT_REG_IDX_AR29, XT_REG_IDX_AR30, XT_REG_IDX_AR31,
106         XT_REG_IDX_AR32, XT_REG_IDX_AR33, XT_REG_IDX_AR34, XT_REG_IDX_AR35,
107         XT_REG_IDX_AR36, XT_REG_IDX_AR37, XT_REG_IDX_AR38, XT_REG_IDX_AR39,
108         XT_REG_IDX_AR40, XT_REG_IDX_AR41, XT_REG_IDX_AR42, XT_REG_IDX_AR43,
109         XT_REG_IDX_AR44, XT_REG_IDX_AR45, XT_REG_IDX_AR46, XT_REG_IDX_AR47,
110         XT_REG_IDX_AR48, XT_REG_IDX_AR49, XT_REG_IDX_AR50, XT_REG_IDX_AR51,
111         XT_REG_IDX_AR52, XT_REG_IDX_AR53, XT_REG_IDX_AR54, XT_REG_IDX_AR55,
112         XT_REG_IDX_AR56, XT_REG_IDX_AR57, XT_REG_IDX_AR58, XT_REG_IDX_AR59,
113         XT_REG_IDX_AR60, XT_REG_IDX_AR61, XT_REG_IDX_AR62, XT_REG_IDX_AR63,
114         XT_REG_IDX_SAR,
115         XT_REG_IDX_WINDOWBASE, XT_REG_IDX_WINDOWSTART, XT_REG_IDX_CONFIGID0, XT_REG_IDX_CONFIGID1,
116         XT_REG_IDX_PS, XT_REG_IDX_THREADPTR,
117         ESP32_S2_REG_IDX_GPIOOUT,
118         XT_REG_IDX_MMID, XT_REG_IDX_IBREAKENABLE, XT_REG_IDX_OCD_DDR,
119         XT_REG_IDX_IBREAKA0, XT_REG_IDX_IBREAKA1, XT_REG_IDX_DBREAKA0, XT_REG_IDX_DBREAKA1,
120         XT_REG_IDX_DBREAKC0, XT_REG_IDX_DBREAKC1,
121         XT_REG_IDX_EPC1, XT_REG_IDX_EPC2, XT_REG_IDX_EPC3, XT_REG_IDX_EPC4,
122         XT_REG_IDX_EPC5, XT_REG_IDX_EPC6, XT_REG_IDX_EPC7, XT_REG_IDX_DEPC,
123         XT_REG_IDX_EPS2, XT_REG_IDX_EPS3, XT_REG_IDX_EPS4, XT_REG_IDX_EPS5,
124         XT_REG_IDX_EPS6, XT_REG_IDX_EPS7,
125         XT_REG_IDX_EXCSAVE1, XT_REG_IDX_EXCSAVE2, XT_REG_IDX_EXCSAVE3, XT_REG_IDX_EXCSAVE4,
126         XT_REG_IDX_EXCSAVE5, XT_REG_IDX_EXCSAVE6, XT_REG_IDX_EXCSAVE7, XT_REG_IDX_CPENABLE,
127         XT_REG_IDX_INTERRUPT, XT_REG_IDX_INTSET, XT_REG_IDX_INTCLEAR, XT_REG_IDX_INTENABLE,
128         XT_REG_IDX_VECBASE, XT_REG_IDX_EXCCAUSE, XT_REG_IDX_DEBUGCAUSE, XT_REG_IDX_CCOUNT,
129         XT_REG_IDX_PRID, XT_REG_IDX_ICOUNT, XT_REG_IDX_ICOUNTLEVEL, XT_REG_IDX_EXCVADDR,
130         XT_REG_IDX_CCOMPARE0, XT_REG_IDX_CCOMPARE1, XT_REG_IDX_CCOMPARE2,
131         XT_REG_IDX_MISC0, XT_REG_IDX_MISC1, XT_REG_IDX_MISC2, XT_REG_IDX_MISC3,
132         XT_REG_IDX_A0, XT_REG_IDX_A1, XT_REG_IDX_A2, XT_REG_IDX_A3,
133         XT_REG_IDX_A4, XT_REG_IDX_A5, XT_REG_IDX_A6, XT_REG_IDX_A7,
134         XT_REG_IDX_A8, XT_REG_IDX_A9, XT_REG_IDX_A10, XT_REG_IDX_A11,
135         XT_REG_IDX_A12, XT_REG_IDX_A13, XT_REG_IDX_A14, XT_REG_IDX_A15,
136         XT_REG_IDX_PWRCTL, XT_REG_IDX_PWRSTAT, XT_REG_IDX_ERISTAT,
137         XT_REG_IDX_CS_ITCTRL, XT_REG_IDX_CS_CLAIMSET, XT_REG_IDX_CS_CLAIMCLR,
138         XT_REG_IDX_CS_LOCKACCESS, XT_REG_IDX_CS_LOCKSTATUS, XT_REG_IDX_CS_AUTHSTATUS,
139         XT_REG_IDX_FAULT_INFO,
140         XT_REG_IDX_TRAX_ID, XT_REG_IDX_TRAX_CTRL, XT_REG_IDX_TRAX_STAT,
141         XT_REG_IDX_TRAX_DATA, XT_REG_IDX_TRAX_ADDR, XT_REG_IDX_TRAX_PCTRIGGER,
142         XT_REG_IDX_TRAX_PCMATCH, XT_REG_IDX_TRAX_DELAY, XT_REG_IDX_TRAX_MEMSTART,
143         XT_REG_IDX_TRAX_MEMEND,
144         XT_REG_IDX_PMG, XT_REG_IDX_PMPC, XT_REG_IDX_PM0, XT_REG_IDX_PM1,
145         XT_REG_IDX_PMCTRL0, XT_REG_IDX_PMCTRL1, XT_REG_IDX_PMSTAT0, XT_REG_IDX_PMSTAT1,
146         XT_REG_IDX_OCD_ID, XT_REG_IDX_OCD_DCRCLR, XT_REG_IDX_OCD_DCRSET, XT_REG_IDX_OCD_DSR,
147 };
148
149 static const struct xtensa_user_reg_desc esp32s2_user_regs[ESP32_S2_NUM_REGS - XT_NUM_REGS] = {
150         { "gpio_out", 0x00, 0, 32, &xtensa_user_reg_u32_type },
151 };
152
153 static const struct xtensa_config esp32s2_xtensa_cfg = {
154         .density = true,
155         .aregs_num = XT_AREGS_NUM_MAX,
156         .windowed = true,
157         .coproc = true,
158         .miscregs_num = 4,
159         .reloc_vec = true,
160         .proc_id = true,
161         .threadptr = true,
162         .user_regs_num = ARRAY_SIZE(esp32s2_user_regs),
163         .user_regs = esp32s2_user_regs,
164         .fetch_user_regs = xtensa_fetch_user_regs_u32,
165         .queue_write_dirty_user_regs = xtensa_queue_write_dirty_user_regs_u32,
166         .gdb_general_regs_num = ESP32_S2_NUM_REGS_G_COMMAND,
167         .gdb_regs_mapping = esp32s2_gdb_regs_mapping,
168         .irom = {
169                 .count = 2,
170                 .regions = {
171                         {
172                                 .base = ESP32_S2_IROM_LOW,
173                                 .size = ESP32_S2_IROM_HIGH - ESP32_S2_IROM_LOW,
174                                 .access = XT_MEM_ACCESS_READ,
175                         },
176                         {
177                                 .base = ESP32_S2_IROM_MASK_LOW,
178                                 .size = ESP32_S2_IROM_MASK_HIGH - ESP32_S2_IROM_MASK_LOW,
179                                 .access = XT_MEM_ACCESS_READ,
180                         },
181                 }
182         },
183         .iram = {
184                 .count = 2,
185                 .regions = {
186                         {
187                                 .base = ESP32_S2_IRAM_LOW,
188                                 .size = ESP32_S2_IRAM_HIGH - ESP32_S2_IRAM_LOW,
189                                 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
190                         },
191                         {
192                                 .base = ESP32_S2_RTC_IRAM_LOW,
193                                 .size = ESP32_S2_RTC_IRAM_HIGH - ESP32_S2_RTC_IRAM_LOW,
194                                 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
195                         },
196                 }
197         },
198         .drom = {
199                 .count = 2,
200                 .regions = {
201                         {
202                                 .base = ESP32_S2_DROM0_LOW,
203                                 .size = ESP32_S2_DROM0_HIGH - ESP32_S2_DROM0_LOW,
204                                 .access = XT_MEM_ACCESS_READ,
205                         },
206                         {
207                                 .base = ESP32_S2_DROM1_LOW,
208                                 .size = ESP32_S2_DROM1_HIGH - ESP32_S2_DROM1_LOW,
209                                 .access = XT_MEM_ACCESS_READ,
210                         },
211                 }
212         },
213         .dram = {
214                 .count = 6,
215                 .regions = {
216                         {
217                                 .base = ESP32_S2_DRAM_LOW,
218                                 .size = ESP32_S2_DRAM_HIGH - ESP32_S2_DRAM_LOW,
219                                 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
220                         },
221                         {
222                                 .base = ESP32_S2_RTC_DRAM_LOW,
223                                 .size = ESP32_S2_RTC_DRAM_HIGH - ESP32_S2_RTC_DRAM_LOW,
224                                 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
225                         },
226                         {
227                                 .base = ESP32_S2_RTC_DATA_LOW,
228                                 .size = ESP32_S2_RTC_DATA_HIGH - ESP32_S2_RTC_DATA_LOW,
229                                 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
230                         },
231                         {
232                                 .base = ESP32_S2_EXTRAM_DATA_LOW,
233                                 .size = ESP32_S2_EXTRAM_DATA_HIGH - ESP32_S2_EXTRAM_DATA_LOW,
234                                 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
235                         },
236                         {
237                                 .base = ESP32_S2_DR_REG_LOW,
238                                 .size = ESP32_S2_DR_REG_HIGH - ESP32_S2_DR_REG_LOW,
239                                 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
240                         },
241                         {
242                                 .base = ESP32_S2_SYS_RAM_LOW,
243                                 .size = ESP32_S2_SYS_RAM_HIGH - ESP32_S2_SYS_RAM_LOW,
244                                 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
245                         },
246                 }
247         },
248         .exc = {
249                 .enabled = true,
250         },
251         .irq = {
252                 .enabled = true,
253                 .irq_num = 32,
254         },
255         .high_irq = {
256                 .enabled = true,
257                 .excm_level = 3,
258                 .nmi_num = 1,
259         },
260         .tim_irq = {
261                 .enabled = true,
262                 .comp_num = 3,
263         },
264         .debug = {
265                 .enabled = true,
266                 .irq_level = 6,
267                 .ibreaks_num = 2,
268                 .dbreaks_num = 2,
269                 .icount_sz = 32,
270         },
271         .trace = {
272                 .enabled = true,
273                 .mem_sz = ESP32_S2_TRACEMEM_BLOCK_SZ,
274         },
275 };
276
277 struct esp32s2_common {
278         struct esp_xtensa_common esp_xtensa;
279 };
280
281 static int esp32s2_soc_reset(struct target *target);
282 static int esp32s2_disable_wdts(struct target *target);
283
284 static int esp32s2_assert_reset(struct target *target)
285 {
286         return ERROR_OK;
287 }
288
289 static int esp32s2_deassert_reset(struct target *target)
290 {
291         struct xtensa *xtensa = target_to_xtensa(target);
292
293         LOG_TARGET_DEBUG(target, "begin");
294
295         int res = xtensa_deassert_reset(target);
296         if (res != ERROR_OK)
297                 return res;
298
299         /* restore configured value
300            esp32s2_soc_reset() modified it, but can not restore just after SW reset for some reason (???) */
301         res = xtensa_smpbreak_write(xtensa, xtensa->smp_break);
302         if (res != ERROR_OK) {
303                 LOG_ERROR("Failed to restore smpbreak (%d)!", res);
304                 return res;
305         }
306         return ERROR_OK;
307 }
308
309 int esp32s2_soft_reset_halt(struct target *target)
310 {
311         LOG_TARGET_DEBUG(target, "begin");
312
313         /* Reset the SoC first */
314         int res = esp32s2_soc_reset(target);
315         if (res != ERROR_OK)
316                 return res;
317         return xtensa_assert_reset(target);
318 }
319
320 static int esp32s2_set_peri_reg_mask(struct target *target,
321         target_addr_t addr,
322         uint32_t mask,
323         uint32_t val)
324 {
325         uint32_t reg_val;
326         int res = target_read_u32(target, addr, &reg_val);
327         if (res != ERROR_OK)
328                 return res;
329         reg_val = (reg_val & (~mask)) | val;
330         res = target_write_u32(target, addr, reg_val);
331         if (res != ERROR_OK)
332                 return res;
333
334         return ERROR_OK;
335 }
336
337 static int esp32s2_stall_set(struct target *target, bool stall)
338 {
339         LOG_TARGET_DEBUG(target, "begin");
340
341         int res = esp32s2_set_peri_reg_mask(target,
342                 ESP32_S2_SW_CPU_STALL,
343                 ESP32_S2_SW_STALL_PROCPU_C1_M,
344                 stall ? 0x21U << ESP32_S2_SW_STALL_PROCPU_C1_S : 0);
345         if (res != ERROR_OK) {
346                 LOG_ERROR("Failed to write ESP32_S2_SW_CPU_STALL (%d)!", res);
347                 return res;
348         }
349         res = esp32s2_set_peri_reg_mask(target,
350                 ESP32_S2_OPTIONS0,
351                 ESP32_S2_SW_STALL_PROCPU_C0_M,
352                 stall ? 0x2 << ESP32_S2_SW_STALL_PROCPU_C0_S : 0);
353         if (res != ERROR_OK) {
354                 LOG_ERROR("Failed to write ESP32_S2_OPTIONS0 (%d)!", res);
355                 return res;
356         }
357         return ERROR_OK;
358 }
359
360 static inline int esp32s2_stall(struct target *target)
361 {
362         return esp32s2_stall_set(target, true);
363 }
364
365 static inline int esp32s2_unstall(struct target *target)
366 {
367         return esp32s2_stall_set(target, false);
368 }
369
370 /* Reset ESP32-S2's peripherals.
371 Postconditions: all peripherals except RTC_CNTL are reset, CPU's PC is undefined, PRO CPU is halted, APP CPU is in reset
372 How this works:
373 0. make sure target is halted; if not, try to halt it; if that fails, try to reset it (via OCD) and then halt
374 1. Resets clock related registers
375 2. Stalls CPU
376 3. trigger SoC reset using RTC_CNTL_SW_SYS_RST bit
377 4. CPU is reset and stalled at the first reset vector instruction
378 5. wait for the OCD to be reset
379 6. halt the target
380 7. Unstalls CPU
381 8. Disables WDTs and trace memory mapping
382 */
383 static int esp32s2_soc_reset(struct target *target)
384 {
385         int res;
386         struct xtensa *xtensa = target_to_xtensa(target);
387
388         LOG_DEBUG("start");
389
390         /* In order to write to peripheral registers, target must be halted first */
391         if (target->state != TARGET_HALTED) {
392                 LOG_TARGET_DEBUG(target, "Target not halted before SoC reset, trying to halt it first");
393                 xtensa_halt(target);
394                 res = target_wait_state(target, TARGET_HALTED, 1000);
395                 if (res != ERROR_OK) {
396                         LOG_TARGET_DEBUG(target, "Couldn't halt target before SoC reset, trying to do reset-halt");
397                         res = xtensa_assert_reset(target);
398                         if (res != ERROR_OK) {
399                                 LOG_TARGET_ERROR(
400                                         target,
401                                         "Couldn't halt target before SoC reset! (xtensa_assert_reset returned %d)",
402                                         res);
403                                 return res;
404                         }
405                         alive_sleep(10);
406                         xtensa_poll(target);
407                         int reset_halt_save = target->reset_halt;
408                         target->reset_halt = 1;
409                         res = xtensa_deassert_reset(target);
410                         target->reset_halt = reset_halt_save;
411                         if (res != ERROR_OK) {
412                                 LOG_TARGET_ERROR(
413                                         target,
414                                         "Couldn't halt target before SoC reset! (xtensa_deassert_reset returned %d)",
415                                         res);
416                                 return res;
417                         }
418                         alive_sleep(10);
419                         xtensa_poll(target);
420                         xtensa_halt(target);
421                         res = target_wait_state(target, TARGET_HALTED, 1000);
422                         if (res != ERROR_OK) {
423                                 LOG_TARGET_ERROR(target, "Couldn't halt target before SoC reset");
424                                 return res;
425                         }
426                 }
427         }
428
429         assert(target->state == TARGET_HALTED);
430
431         /* Set some clock-related RTC registers to the default values */
432         res = target_write_u32(target, ESP32_S2_STORE4, 0);
433         if (res != ERROR_OK) {
434                 LOG_ERROR("Failed to write ESP32_S2_STORE4 (%d)!", res);
435                 return res;
436         }
437         res = target_write_u32(target, ESP32_S2_STORE5, 0);
438         if (res != ERROR_OK) {
439                 LOG_ERROR("Failed to write ESP32_S2_STORE5 (%d)!", res);
440                 return res;
441         }
442         res = target_write_u32(target, ESP32_S2_RTC_CNTL_DIG_PWC_REG, 0);
443         if (res != ERROR_OK) {
444                 LOG_ERROR("Failed to write ESP32_S2_RTC_CNTL_DIG_PWC_REG (%d)!", res);
445                 return res;
446         }
447         res = target_write_u32(target, ESP32_S2_CLK_CONF, ESP32_S2_CLK_CONF_DEF);
448         if (res != ERROR_OK) {
449                 LOG_ERROR("Failed to write ESP32_S2_CLK_CONF (%d)!", res);
450                 return res;
451         }
452         /* Stall CPU */
453         res = esp32s2_stall(target);
454         if (res != ERROR_OK)
455                 return res;
456         /* enable stall */
457         res = xtensa_smpbreak_write(xtensa, OCDDCR_RUNSTALLINEN);
458         if (res != ERROR_OK) {
459                 LOG_ERROR("Failed to set smpbreak (%d)!", res);
460                 return res;
461         }
462         /* Reset CPU */
463         xtensa->suppress_dsr_errors = true;
464         res = esp32s2_set_peri_reg_mask(target,
465                 ESP32_S2_OPTIONS0,
466                 ESP32_S2_SW_SYS_RST_M,
467                 BIT(ESP32_S2_SW_SYS_RST_S));
468         xtensa->suppress_dsr_errors = false;
469         if (res != ERROR_OK) {
470                 LOG_ERROR("Failed to write ESP32_S2_OPTIONS0 (%d)!", res);
471                 return res;
472         }
473         /* Wait for SoC to reset */
474         alive_sleep(100);
475         int64_t timeout = timeval_ms() + 100;
476         while (target->state != TARGET_RESET && target->state != TARGET_RUNNING) {
477                 alive_sleep(10);
478                 xtensa_poll(target);
479                 if (timeval_ms() >= timeout) {
480                         LOG_TARGET_ERROR(target, "Timed out waiting for CPU to be reset, target state=%d", target->state);
481                         return ERROR_TARGET_TIMEOUT;
482                 }
483         }
484
485         xtensa_halt(target);
486         res = target_wait_state(target, TARGET_HALTED, 1000);
487         if (res != ERROR_OK) {
488                 LOG_TARGET_ERROR(target, "Couldn't halt target before SoC reset");
489                 return res;
490         }
491         /* Unstall CPU */
492         res = esp32s2_unstall(target);
493         if (res != ERROR_OK)
494                 return res;
495         /* Disable WDTs */
496         res = esp32s2_disable_wdts(target);
497         if (res != ERROR_OK)
498                 return res;
499         /* Disable trace memory mapping */
500         res = target_write_u32(target, ESP32_S2_DPORT_PMS_OCCUPY_3, 0);
501         if (res != ERROR_OK) {
502                 LOG_ERROR("Failed to write ESP32_S2_DPORT_PMS_OCCUPY_3 (%d)!", res);
503                 return res;
504         }
505         return ERROR_OK;
506 }
507
508 static int esp32s2_disable_wdts(struct target *target)
509 {
510         /* TIMG1 WDT */
511         int res = target_write_u32(target, ESP32_S2_TIMG0WDT_PROTECT, ESP32_S2_WDT_WKEY_VALUE);
512         if (res != ERROR_OK) {
513                 LOG_ERROR("Failed to write ESP32_S2_TIMG0WDT_PROTECT (%d)!", res);
514                 return res;
515         }
516         res = target_write_u32(target, ESP32_S2_TIMG0WDT_CFG0, 0);
517         if (res != ERROR_OK) {
518                 LOG_ERROR("Failed to write ESP32_S2_TIMG0WDT_CFG0 (%d)!", res);
519                 return res;
520         }
521         /* TIMG2 WDT */
522         res = target_write_u32(target, ESP32_S2_TIMG1WDT_PROTECT, ESP32_S2_WDT_WKEY_VALUE);
523         if (res != ERROR_OK) {
524                 LOG_ERROR("Failed to write ESP32_S2_TIMG1WDT_PROTECT (%d)!", res);
525                 return res;
526         }
527         res = target_write_u32(target, ESP32_S2_TIMG1WDT_CFG0, 0);
528         if (res != ERROR_OK) {
529                 LOG_ERROR("Failed to write ESP32_S2_TIMG1WDT_CFG0 (%d)!", res);
530                 return res;
531         }
532         /* RTC WDT */
533         res = target_write_u32(target, ESP32_S2_RTCWDT_PROTECT, ESP32_S2_WDT_WKEY_VALUE);
534         if (res != ERROR_OK) {
535                 LOG_ERROR("Failed to write ESP32_S2_RTCWDT_PROTECT (%d)!", res);
536                 return res;
537         }
538         res = target_write_u32(target, ESP32_S2_RTCWDT_CFG, 0);
539         if (res != ERROR_OK) {
540                 LOG_ERROR("Failed to write ESP32_S2_RTCWDT_CFG (%d)!", res);
541                 return res;
542         }
543         /* Enable SWD auto-feed */
544         res = target_write_u32(target, ESP32_S2_SWD_WPROTECT_REG, ESP32_S2_SWD_WKEY_VALUE);
545         if (res != ERROR_OK) {
546                 LOG_ERROR("Failed to write ESP32_S2_SWD_WPROTECT_REG (%d)!", res);
547                 return res;
548         }
549         uint32_t swd_conf_reg = 0;
550         res = target_read_u32(target, ESP32_S2_SWD_CONF_REG, &swd_conf_reg);
551         if (res != ERROR_OK) {
552                 LOG_ERROR("Failed to read ESP32_S2_SWD_CONF_REG (%d)!", res);
553                 return res;
554         }
555         swd_conf_reg |= ESP32_S2_SWD_AUTO_FEED_EN_M;
556         res = target_write_u32(target, ESP32_S2_SWD_CONF_REG, swd_conf_reg);
557         if (res != ERROR_OK) {
558                 LOG_ERROR("Failed to write ESP32_S2_SWD_CONF_REG (%d)!", res);
559                 return res;
560         }
561         return ERROR_OK;
562 }
563
564 static int esp32s2_arch_state(struct target *target)
565 {
566         return ERROR_OK;
567 }
568
569 static int esp32s2_on_halt(struct target *target)
570 {
571         return esp32s2_disable_wdts(target);
572 }
573
574 static int esp32s2_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)
575 {
576         int ret = xtensa_step(target, current, address, handle_breakpoints);
577         if (ret == ERROR_OK) {
578                 esp32s2_on_halt(target);
579                 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
580         }
581         return ret;
582 }
583
584 static int esp32s2_poll(struct target *target)
585 {
586         enum target_state old_state = target->state;
587         int ret = esp_xtensa_poll(target);
588
589         if (old_state != TARGET_HALTED && target->state == TARGET_HALTED) {
590                 /* Call any event callbacks that are applicable */
591                 if (old_state == TARGET_DEBUG_RUNNING) {
592                         target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
593                 } else {
594                         esp32s2_on_halt(target);
595                         target_call_event_callbacks(target, TARGET_EVENT_HALTED);
596                 }
597         }
598
599         return ret;
600 }
601
602 static int esp32s2_virt2phys(struct target *target,
603         target_addr_t virtual, target_addr_t *physical)
604 {
605         *physical = virtual;
606         return ERROR_OK;
607 }
608
609 static int esp32s2_target_init(struct command_context *cmd_ctx, struct target *target)
610 {
611         return esp_xtensa_target_init(cmd_ctx, target);
612 }
613
614 static const struct xtensa_debug_ops esp32s2_dbg_ops = {
615         .queue_enable = xtensa_dm_queue_enable,
616         .queue_reg_read = xtensa_dm_queue_reg_read,
617         .queue_reg_write = xtensa_dm_queue_reg_write
618 };
619
620 static const struct xtensa_power_ops esp32s2_pwr_ops = {
621         .queue_reg_read = xtensa_dm_queue_pwr_reg_read,
622         .queue_reg_write = xtensa_dm_queue_pwr_reg_write
623 };
624
625 static int esp32s2_target_create(struct target *target, Jim_Interp *interp)
626 {
627         struct xtensa_debug_module_config esp32s2_dm_cfg = {
628                 .dbg_ops = &esp32s2_dbg_ops,
629                 .pwr_ops = &esp32s2_pwr_ops,
630                 .tap = target->tap,
631                 .queue_tdi_idle = NULL,
632                 .queue_tdi_idle_arg = NULL
633         };
634
635         /* creates xtensa object */
636         struct esp32s2_common *esp32 = calloc(1, sizeof(*esp32));
637         if (!esp32) {
638                 LOG_ERROR("Failed to alloc memory for arch info!");
639                 return ERROR_FAIL;
640         }
641
642         int ret = esp_xtensa_init_arch_info(target, &esp32->esp_xtensa, &esp32s2_xtensa_cfg, &esp32s2_dm_cfg);
643         if (ret != ERROR_OK) {
644                 LOG_ERROR("Failed to init arch info!");
645                 free(esp32);
646                 return ret;
647         }
648
649         /* Assume running target. If different, the first poll will fix this */
650         target->state = TARGET_RUNNING;
651         target->debug_reason = DBG_REASON_NOTHALTED;
652         return ERROR_OK;
653 }
654
655 static const struct command_registration esp32s2_command_handlers[] = {
656         {
657                 .name = "xtensa",
658                 .mode = COMMAND_ANY,
659                 .help = "Xtensa commands group",
660                 .usage = "",
661                 .chain = xtensa_command_handlers,
662         },
663         COMMAND_REGISTRATION_DONE
664 };
665
666 /* Holds methods for Xtensa targets. */
667 struct target_type esp32s2_target = {
668         .name = "esp32s2",
669
670         .poll = esp32s2_poll,
671         .arch_state = esp32s2_arch_state,
672
673         .halt = xtensa_halt,
674         .resume = xtensa_resume,
675         .step = esp32s2_step,
676
677         .assert_reset = esp32s2_assert_reset,
678         .deassert_reset = esp32s2_deassert_reset,
679         .soft_reset_halt = esp32s2_soft_reset_halt,
680
681         .virt2phys = esp32s2_virt2phys,
682         .mmu = xtensa_mmu_is_enabled,
683         .read_memory = xtensa_read_memory,
684         .write_memory = xtensa_write_memory,
685
686         .read_buffer = xtensa_read_buffer,
687         .write_buffer = xtensa_write_buffer,
688
689         .checksum_memory = xtensa_checksum_memory,
690
691         .get_gdb_arch = xtensa_get_gdb_arch,
692         .get_gdb_reg_list = xtensa_get_gdb_reg_list,
693
694         .add_breakpoint = esp_xtensa_breakpoint_add,
695         .remove_breakpoint = esp_xtensa_breakpoint_remove,
696
697         .add_watchpoint = xtensa_watchpoint_add,
698         .remove_watchpoint = xtensa_watchpoint_remove,
699
700         .target_create = esp32s2_target_create,
701         .init_target = esp32s2_target_init,
702         .examine = xtensa_examine,
703         .deinit_target = esp_xtensa_target_deinit,
704
705         .commands = esp32s2_command_handlers,
706 };