esp32s2: convert counted timeout to timeval_ms
[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 <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 };

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)