bbf7ff5afaecde75461af49b1cee27148e4be498
[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  ***************************************************************************/
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #include <helper/time_support.h>
13 #include "assert.h"
14 #include <target/target.h>
15 #include <target/target_type.h>
16 #include "esp_xtensa.h"
17 #include "esp32s2.h"
18
19 /* Overall memory map
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
46
47 /* ESP32 WDT */
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
86
87 #define ESP32_S2_TRACEMEM_BLOCK_SZ      0x4000
88
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)
92
93 /* this should map local reg IDs to GDB reg mapping as defined in xtensa-config.c 'rmap' in
94  * xtensa-overlay */
95 static const unsigned int esp32s2_gdb_regs_mapping[ESP32_S2_NUM_REGS] = {
96         XT_REG_IDX_PC,
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,
113         XT_REG_IDX_SAR,
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,
146 };
147
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 },
150 };
151
152 static const struct xtensa_config esp32s2_xtensa_cfg = {
153         .density = true,
154         .aregs_num = XT_AREGS_NUM_MAX,
155         .windowed = true,
156         .coproc = true,
157         .miscregs_num = 4,
158         .reloc_vec = true,
159         .proc_id = true,
160         .threadptr = true,
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,
167         .irom = {
168                 .count = 2,
169                 .regions = {
170                         {
171                                 .base = ESP32_S2_IROM_LOW,
172                                 .size = ESP32_S2_IROM_HIGH - ESP32_S2_IROM_LOW,
173                                 .access = XT_MEM_ACCESS_READ,
174                         },
175                         {
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,
179                         },
180                 }
181         },
182         .iram = {
183                 .count = 2,
184                 .regions = {
185                         {
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,
189                         },
190                         {
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,
194                         },
195                 }
196         },
197         .drom = {
198                 .count = 2,
199                 .regions = {
200                         {
201                                 .base = ESP32_S2_DROM0_LOW,
202                                 .size = ESP32_S2_DROM0_HIGH - ESP32_S2_DROM0_LOW,
203                                 .access = XT_MEM_ACCESS_READ,
204                         },
205                         {
206                                 .base = ESP32_S2_DROM1_LOW,
207                                 .size = ESP32_S2_DROM1_HIGH - ESP32_S2_DROM1_LOW,
208                                 .access = XT_MEM_ACCESS_READ,
209                         },
210                 }
211         },
212         .dram = {
213                 .count = 6,
214                 .regions = {
215                         {
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,
219                         },
220                         {
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,
224                         },
225                         {
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,
229                         },
230                         {
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,
234                         },
235                         {
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,
239                         },
240                         {
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,
244                         },
245                 }
246         },
247         .exc = {
248                 .enabled = true,
249         },
250         .irq = {
251                 .enabled = true,
252                 .irq_num = 32,
253         },
254         .high_irq = {
255                 .enabled = true,
256                 .excm_level = 3,
257                 .nmi_num = 1,
258         },
259         .tim_irq = {
260                 .enabled = true,
261                 .comp_num = 3,
262         },
263         .debug = {
264                 .enabled = true,
265                 .irq_level = 6,
266                 .ibreaks_num = 2,
267                 .dbreaks_num = 2,
268                 .icount_sz = 32,
269         },
270         .trace = {
271                 .enabled = true,
272                 .mem_sz = ESP32_S2_TRACEMEM_BLOCK_SZ,
273         },
274 };
275
276 struct esp32s2_common {
277         struct esp_xtensa_common esp_xtensa;
278 };
279
280 static int esp32s2_soc_reset(struct target *target);
281 static int esp32s2_disable_wdts(struct target *target);
282
283 static int esp32s2_assert_reset(struct target *target)
284 {
285         return ERROR_OK;
286 }
287
288 static int esp32s2_deassert_reset(struct target *target)
289 {
290         struct xtensa *xtensa = target_to_xtensa(target);
291
292         LOG_TARGET_DEBUG(target, "begin");
293
294         int res = xtensa_deassert_reset(target);
295         if (res != ERROR_OK)
296                 return res;
297
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);
303                 return res;
304         }
305         return ERROR_OK;
306 }
307
308 int esp32s2_soft_reset_halt(struct target *target)
309 {
310         LOG_TARGET_DEBUG(target, "begin");
311
312         /* Reset the SoC first */
313         int res = esp32s2_soc_reset(target);
314         if (res != ERROR_OK)
315                 return res;
316         return xtensa_assert_reset(target);
317 }
318
319 static int esp32s2_set_peri_reg_mask(struct target *target,
320         target_addr_t addr,
321         uint32_t mask,
322         uint32_t val)
323 {
324         uint32_t reg_val;
325         int res = target_read_u32(target, addr, &reg_val);
326         if (res != ERROR_OK)
327                 return res;
328         reg_val = (reg_val & (~mask)) | val;
329         res = target_write_u32(target, addr, reg_val);
330         if (res != ERROR_OK)
331                 return res;
332
333         return ERROR_OK;
334 }
335
336 static int esp32s2_stall_set(struct target *target, bool stall)
337 {
338         LOG_TARGET_DEBUG(target, "begin");
339
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);
346                 return res;
347         }
348         res = esp32s2_set_peri_reg_mask(target,
349                 ESP32_S2_OPTIONS0,
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);
354                 return res;
355         }
356         return ERROR_OK;
357 }
358
359 static inline int esp32s2_stall(struct target *target)
360 {
361         return esp32s2_stall_set(target, true);
362 }
363
364 static inline int esp32s2_unstall(struct target *target)
365 {
366         return esp32s2_stall_set(target, false);
367 }
368
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
371 How this works:
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
374 2. Stalls CPU
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
378 6. halt the target
379 7. Unstalls CPU
380 8. Disables WDTs and trace memory mapping
381 */
382 static int esp32s2_soc_reset(struct target *target)
383 {
384         int res;
385         struct xtensa *xtensa = target_to_xtensa(target);
386
387         LOG_DEBUG("start");
388
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");
392                 xtensa_halt(target);
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) {
398                                 LOG_TARGET_ERROR(
399                                         target,
400                                         "Couldn't halt target before SoC reset! (xtensa_assert_reset returned %d)",
401                                         res);
402                                 return res;
403                         }
404                         alive_sleep(10);
405                         xtensa_poll(target);
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) {
411                                 LOG_TARGET_ERROR(
412                                         target,
413                                         "Couldn't halt target before SoC reset! (xtensa_deassert_reset returned %d)",
414                                         res);
415                                 return res;
416                         }
417                         alive_sleep(10);
418                         xtensa_poll(target);
419                         xtensa_halt(target);
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");
423                                 return res;
424                         }
425                 }
426         }
427
428         assert(target->state == TARGET_HALTED);
429
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);
434                 return res;
435         }
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);
439                 return res;
440         }
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);
444                 return res;
445         }
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);
449                 return res;
450         }
451         /* Stall CPU */
452         res = esp32s2_stall(target);
453         if (res != ERROR_OK)
454                 return res;
455         /* enable stall */
456         res = xtensa_smpbreak_write(xtensa, OCDDCR_RUNSTALLINEN);
457         if (res != ERROR_OK) {
458                 LOG_ERROR("Failed to set smpbreak (%d)!", res);
459                 return res;
460         }
461         /* Reset CPU */
462         xtensa->suppress_dsr_errors = true;
463         res = esp32s2_set_peri_reg_mask(target,
464                 ESP32_S2_OPTIONS0,
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);
470                 return res;
471         }
472         /* Wait for SoC to reset */
473         alive_sleep(100);
474         int64_t timeout = timeval_ms() + 100;
475         while (target->state != TARGET_RESET && target->state != TARGET_RUNNING) {
476                 alive_sleep(10);
477                 xtensa_poll(target);
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;
481                 }
482         }
483
484         xtensa_halt(target);
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");
488                 return res;
489         }
490         /* Unstall CPU */
491         res = esp32s2_unstall(target);
492         if (res != ERROR_OK)
493                 return res;
494         /* Disable WDTs */
495         res = esp32s2_disable_wdts(target);
496         if (res != ERROR_OK)
497                 return res;
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);
502                 return res;
503         }
504         return ERROR_OK;
505 }
506
507 static int esp32s2_disable_wdts(struct target *target)
508 {
509         /* TIMG1 WDT */
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);
513                 return res;
514         }
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);
518                 return res;
519         }
520         /* TIMG2 WDT */
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);
524                 return res;
525         }
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);
529                 return res;
530         }
531         /* RTC WDT */
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);
535                 return res;
536         }
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);
540                 return res;
541         }
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);
546                 return res;
547         }
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);
552                 return res;
553         }
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);
558                 return res;
559         }
560         return ERROR_OK;
561 }
562
563 static int esp32s2_arch_state(struct target *target)
564 {
565         return ERROR_OK;
566 }
567
568 static int esp32s2_on_halt(struct target *target)
569 {
570         return esp32s2_disable_wdts(target);
571 }
572
573 static int esp32s2_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)
574 {
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);
579         }
580         return ret;
581 }
582
583 static int esp32s2_poll(struct target *target)
584 {
585         enum target_state old_state = target->state;
586         int ret = esp_xtensa_poll(target);
587
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);
592                 } else {
593                         esp32s2_on_halt(target);
594                         target_call_event_callbacks(target, TARGET_EVENT_HALTED);
595                 }
596         }
597
598         return ret;
599 }
600
601 static int esp32s2_virt2phys(struct target *target,
602         target_addr_t virtual, target_addr_t *physical)
603 {
604         *physical = virtual;
605         return ERROR_OK;
606 }
607
608 static int esp32s2_target_init(struct command_context *cmd_ctx, struct target *target)
609 {
610         return esp_xtensa_target_init(cmd_ctx, target);
611 }
612
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
617 };
618
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
622 };
623
624 static int esp32s2_target_create(struct target *target, Jim_Interp *interp)
625 {
626         struct xtensa_debug_module_config esp32s2_dm_cfg = {
627                 .dbg_ops = &esp32s2_dbg_ops,
628                 .pwr_ops = &esp32s2_pwr_ops,
629                 .tap = target->tap,
630                 .queue_tdi_idle = NULL,
631                 .queue_tdi_idle_arg = NULL
632         };
633
634         /* creates xtensa object */
635         struct esp32s2_common *esp32 = calloc(1, sizeof(*esp32));
636         if (!esp32) {
637                 LOG_ERROR("Failed to alloc memory for arch info!");
638                 return ERROR_FAIL;
639         }
640
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!");
644                 free(esp32);
645                 return ret;
646         }
647
648         /* Assume running target. If different, the first poll will fix this */
649         target->state = TARGET_RUNNING;
650         target->debug_reason = DBG_REASON_NOTHALTED;
651         return ERROR_OK;
652 }
653
654 static const struct command_registration esp32s2_command_handlers[] = {
655         {
656                 .name = "xtensa",
657                 .mode = COMMAND_ANY,
658                 .help = "Xtensa commands group",
659                 .usage = "",
660                 .chain = xtensa_command_handlers,
661         },
662         COMMAND_REGISTRATION_DONE
663 };
664
665 /* Holds methods for Xtensa targets. */
666 struct target_type esp32s2_target = {
667         .name = "esp32s2",
668
669         .poll = esp32s2_poll,
670         .arch_state = esp32s2_arch_state,
671
672         .halt = xtensa_halt,
673         .resume = xtensa_resume,
674         .step = esp32s2_step,
675
676         .assert_reset = esp32s2_assert_reset,
677         .deassert_reset = esp32s2_deassert_reset,
678         .soft_reset_halt = esp32s2_soft_reset_halt,
679
680         .virt2phys = esp32s2_virt2phys,
681         .mmu = xtensa_mmu_is_enabled,
682         .read_memory = xtensa_read_memory,
683         .write_memory = xtensa_write_memory,
684
685         .read_buffer = xtensa_read_buffer,
686         .write_buffer = xtensa_write_buffer,
687
688         .checksum_memory = xtensa_checksum_memory,
689
690         .get_gdb_arch = xtensa_get_gdb_arch,
691         .get_gdb_reg_list = xtensa_get_gdb_reg_list,
692
693         .add_breakpoint = esp_xtensa_breakpoint_add,
694         .remove_breakpoint = esp_xtensa_breakpoint_remove,
695
696         .add_watchpoint = xtensa_watchpoint_add,
697         .remove_watchpoint = xtensa_watchpoint_remove,
698
699         .target_create = esp32s2_target_create,
700         .init_target = esp32s2_target_init,
701         .examine = xtensa_examine,
702         .deinit_target = esp_xtensa_target_deinit,
703
704         .commands = esp32s2_command_handlers,
705 };