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