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