212533ff8fa45b1653611695a403ba41a13a8cc3
[openocd.git] / 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 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)