target/semihosting: export semihosting_common_handlers[] from header file
[openocd.git] / src / target / espressif / esp32.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /***************************************************************************
4 * ESP32 target API for OpenOCD *
5 * Copyright (C) 2016-2019 Espressif Systems Ltd. *
6 * Author: Dmitry Yakovlev <dmitry@espressif.com> *
7 * Author: Alexey Gerenkov <alexey@espressif.com> *
8 ***************************************************************************/
9
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif
13
14 #include <helper/time_support.h>
15 #include <target/target.h>
16 #include <target/target_type.h>
17 #include <target/smp.h>
18 #include "assert.h"
19 #include "esp32.h"
20 #include "esp_xtensa_smp.h"
21
22 /*
23 This is a JTAG driver for the ESP32, the are two Tensilica cores inside
24 the ESP32 chip. For more information please have a look into ESP32 target
25 implementation.
26 */
27
28 /* ESP32 memory map */
29 #define ESP32_DRAM_LOW 0x3ffae000
30 #define ESP32_DRAM_HIGH 0x40000000
31 #define ESP32_IROM_MASK_LOW 0x40000000
32 #define ESP32_IROM_MASK_HIGH 0x40064f00
33 #define ESP32_IRAM_LOW 0x40070000
34 #define ESP32_IRAM_HIGH 0x400a0000
35 #define ESP32_RTC_IRAM_LOW 0x400c0000
36 #define ESP32_RTC_IRAM_HIGH 0x400c2000
37 #define ESP32_RTC_DRAM_LOW 0x3ff80000
38 #define ESP32_RTC_DRAM_HIGH 0x3ff82000
39 #define ESP32_RTC_DATA_LOW 0x50000000
40 #define ESP32_RTC_DATA_HIGH 0x50002000
41 #define ESP32_EXTRAM_DATA_LOW 0x3f800000
42 #define ESP32_EXTRAM_DATA_HIGH 0x3fc00000
43 #define ESP32_DR_REG_LOW 0x3ff00000
44 #define ESP32_DR_REG_HIGH 0x3ff71000
45 #define ESP32_SYS_RAM_LOW 0x60000000UL
46 #define ESP32_SYS_RAM_HIGH (ESP32_SYS_RAM_LOW + 0x20000000UL)
47 #define ESP32_RTC_SLOW_MEM_BASE ESP32_RTC_DATA_LOW
48
49 /* ESP32 WDT */
50 #define ESP32_WDT_WKEY_VALUE 0x50d83aa1
51 #define ESP32_TIMG0_BASE 0x3ff5f000
52 #define ESP32_TIMG1_BASE 0x3ff60000
53 #define ESP32_TIMGWDT_CFG0_OFF 0x48
54 #define ESP32_TIMGWDT_PROTECT_OFF 0x64
55 #define ESP32_TIMG0WDT_CFG0 (ESP32_TIMG0_BASE + ESP32_TIMGWDT_CFG0_OFF)
56 #define ESP32_TIMG1WDT_CFG0 (ESP32_TIMG1_BASE + ESP32_TIMGWDT_CFG0_OFF)
57 #define ESP32_TIMG0WDT_PROTECT (ESP32_TIMG0_BASE + ESP32_TIMGWDT_PROTECT_OFF)
58 #define ESP32_TIMG1WDT_PROTECT (ESP32_TIMG1_BASE + ESP32_TIMGWDT_PROTECT_OFF)
59 #define ESP32_RTCCNTL_BASE 0x3ff48000
60 #define ESP32_RTCWDT_CFG_OFF 0x8C
61 #define ESP32_RTCWDT_PROTECT_OFF 0xA4
62 #define ESP32_RTCWDT_CFG (ESP32_RTCCNTL_BASE + ESP32_RTCWDT_CFG_OFF)
63 #define ESP32_RTCWDT_PROTECT (ESP32_RTCCNTL_BASE + ESP32_RTCWDT_PROTECT_OFF)
64
65 #define ESP32_TRACEMEM_BLOCK_SZ 0x4000
66
67 /* ESP32 dport regs */
68 #define ESP32_DR_REG_DPORT_BASE ESP32_DR_REG_LOW
69 #define ESP32_DPORT_APPCPU_CTRL_B_REG (ESP32_DR_REG_DPORT_BASE + 0x030)
70 #define ESP32_DPORT_APPCPU_CLKGATE_EN BIT(0)
71 /* ESP32 RTC regs */
72 #define ESP32_RTC_CNTL_SW_CPU_STALL_REG (ESP32_RTCCNTL_BASE + 0xac)
73 #define ESP32_RTC_CNTL_SW_CPU_STALL_DEF 0x0
74
75
76 /* this should map local reg IDs to GDB reg mapping as defined in xtensa-config.c 'rmap' in
77 *xtensa-overlay */
78 static const unsigned int esp32_gdb_regs_mapping[ESP32_NUM_REGS] = {
79 XT_REG_IDX_PC,
80 XT_REG_IDX_AR0, XT_REG_IDX_AR1, XT_REG_IDX_AR2, XT_REG_IDX_AR3,
81 XT_REG_IDX_AR4, XT_REG_IDX_AR5, XT_REG_IDX_AR6, XT_REG_IDX_AR7,
82 XT_REG_IDX_AR8, XT_REG_IDX_AR9, XT_REG_IDX_AR10, XT_REG_IDX_AR11,
83 XT_REG_IDX_AR12, XT_REG_IDX_AR13, XT_REG_IDX_AR14, XT_REG_IDX_AR15,
84 XT_REG_IDX_AR16, XT_REG_IDX_AR17, XT_REG_IDX_AR18, XT_REG_IDX_AR19,
85 XT_REG_IDX_AR20, XT_REG_IDX_AR21, XT_REG_IDX_AR22, XT_REG_IDX_AR23,
86 XT_REG_IDX_AR24, XT_REG_IDX_AR25, XT_REG_IDX_AR26, XT_REG_IDX_AR27,
87 XT_REG_IDX_AR28, XT_REG_IDX_AR29, XT_REG_IDX_AR30, XT_REG_IDX_AR31,
88 XT_REG_IDX_AR32, XT_REG_IDX_AR33, XT_REG_IDX_AR34, XT_REG_IDX_AR35,
89 XT_REG_IDX_AR36, XT_REG_IDX_AR37, XT_REG_IDX_AR38, XT_REG_IDX_AR39,
90 XT_REG_IDX_AR40, XT_REG_IDX_AR41, XT_REG_IDX_AR42, XT_REG_IDX_AR43,
91 XT_REG_IDX_AR44, XT_REG_IDX_AR45, XT_REG_IDX_AR46, XT_REG_IDX_AR47,
92 XT_REG_IDX_AR48, XT_REG_IDX_AR49, XT_REG_IDX_AR50, XT_REG_IDX_AR51,
93 XT_REG_IDX_AR52, XT_REG_IDX_AR53, XT_REG_IDX_AR54, XT_REG_IDX_AR55,
94 XT_REG_IDX_AR56, XT_REG_IDX_AR57, XT_REG_IDX_AR58, XT_REG_IDX_AR59,
95 XT_REG_IDX_AR60, XT_REG_IDX_AR61, XT_REG_IDX_AR62, XT_REG_IDX_AR63,
96 XT_REG_IDX_LBEG, XT_REG_IDX_LEND, XT_REG_IDX_LCOUNT, XT_REG_IDX_SAR,
97 XT_REG_IDX_WINDOWBASE, XT_REG_IDX_WINDOWSTART, XT_REG_IDX_CONFIGID0, XT_REG_IDX_CONFIGID1,
98 XT_REG_IDX_PS, XT_REG_IDX_THREADPTR, XT_REG_IDX_BR, XT_REG_IDX_SCOMPARE1,
99 XT_REG_IDX_ACCLO, XT_REG_IDX_ACCHI,
100 XT_REG_IDX_M0, XT_REG_IDX_M1, XT_REG_IDX_M2, XT_REG_IDX_M3,
101 ESP32_REG_IDX_EXPSTATE,
102 ESP32_REG_IDX_F64R_LO,
103 ESP32_REG_IDX_F64R_HI,
104 ESP32_REG_IDX_F64S,
105 XT_REG_IDX_F0, XT_REG_IDX_F1, XT_REG_IDX_F2, XT_REG_IDX_F3,
106 XT_REG_IDX_F4, XT_REG_IDX_F5, XT_REG_IDX_F6, XT_REG_IDX_F7,
107 XT_REG_IDX_F8, XT_REG_IDX_F9, XT_REG_IDX_F10, XT_REG_IDX_F11,
108 XT_REG_IDX_F12, XT_REG_IDX_F13, XT_REG_IDX_F14, XT_REG_IDX_F15,
109 XT_REG_IDX_FCR, XT_REG_IDX_FSR, XT_REG_IDX_MMID, XT_REG_IDX_IBREAKENABLE,
110 XT_REG_IDX_MEMCTL, XT_REG_IDX_ATOMCTL, XT_REG_IDX_OCD_DDR,
111 XT_REG_IDX_IBREAKA0, XT_REG_IDX_IBREAKA1, XT_REG_IDX_DBREAKA0, XT_REG_IDX_DBREAKA1,
112 XT_REG_IDX_DBREAKC0, XT_REG_IDX_DBREAKC1,
113 XT_REG_IDX_EPC1, XT_REG_IDX_EPC2, XT_REG_IDX_EPC3, XT_REG_IDX_EPC4,
114 XT_REG_IDX_EPC5, XT_REG_IDX_EPC6, XT_REG_IDX_EPC7, XT_REG_IDX_DEPC,
115 XT_REG_IDX_EPS2, XT_REG_IDX_EPS3, XT_REG_IDX_EPS4, XT_REG_IDX_EPS5,
116 XT_REG_IDX_EPS6, XT_REG_IDX_EPS7,
117 XT_REG_IDX_EXCSAVE1, XT_REG_IDX_EXCSAVE2, XT_REG_IDX_EXCSAVE3, XT_REG_IDX_EXCSAVE4,
118 XT_REG_IDX_EXCSAVE5, XT_REG_IDX_EXCSAVE6, XT_REG_IDX_EXCSAVE7, XT_REG_IDX_CPENABLE,
119 XT_REG_IDX_INTERRUPT, XT_REG_IDX_INTSET, XT_REG_IDX_INTCLEAR, XT_REG_IDX_INTENABLE,
120 XT_REG_IDX_VECBASE, XT_REG_IDX_EXCCAUSE, XT_REG_IDX_DEBUGCAUSE, XT_REG_IDX_CCOUNT,
121 XT_REG_IDX_PRID, XT_REG_IDX_ICOUNT, XT_REG_IDX_ICOUNTLEVEL, XT_REG_IDX_EXCVADDR,
122 XT_REG_IDX_CCOMPARE0, XT_REG_IDX_CCOMPARE1, XT_REG_IDX_CCOMPARE2,
123 XT_REG_IDX_MISC0, XT_REG_IDX_MISC1, XT_REG_IDX_MISC2, XT_REG_IDX_MISC3,
124 XT_REG_IDX_A0, XT_REG_IDX_A1, XT_REG_IDX_A2, XT_REG_IDX_A3,
125 XT_REG_IDX_A4, XT_REG_IDX_A5, XT_REG_IDX_A6, XT_REG_IDX_A7,
126 XT_REG_IDX_A8, XT_REG_IDX_A9, XT_REG_IDX_A10, XT_REG_IDX_A11,
127 XT_REG_IDX_A12, XT_REG_IDX_A13, XT_REG_IDX_A14, XT_REG_IDX_A15,
128 XT_REG_IDX_PWRCTL, XT_REG_IDX_PWRSTAT, XT_REG_IDX_ERISTAT,
129 XT_REG_IDX_CS_ITCTRL, XT_REG_IDX_CS_CLAIMSET, XT_REG_IDX_CS_CLAIMCLR,
130 XT_REG_IDX_CS_LOCKACCESS, XT_REG_IDX_CS_LOCKSTATUS, XT_REG_IDX_CS_AUTHSTATUS,
131 XT_REG_IDX_FAULT_INFO,
132 XT_REG_IDX_TRAX_ID, XT_REG_IDX_TRAX_CTRL, XT_REG_IDX_TRAX_STAT,
133 XT_REG_IDX_TRAX_DATA, XT_REG_IDX_TRAX_ADDR, XT_REG_IDX_TRAX_PCTRIGGER,
134 XT_REG_IDX_TRAX_PCMATCH, XT_REG_IDX_TRAX_DELAY, XT_REG_IDX_TRAX_MEMSTART,
135 XT_REG_IDX_TRAX_MEMEND,
136 XT_REG_IDX_PMG, XT_REG_IDX_PMPC, XT_REG_IDX_PM0, XT_REG_IDX_PM1,
137 XT_REG_IDX_PMCTRL0, XT_REG_IDX_PMCTRL1, XT_REG_IDX_PMSTAT0, XT_REG_IDX_PMSTAT1,
138 XT_REG_IDX_OCD_ID, XT_REG_IDX_OCD_DCRCLR, XT_REG_IDX_OCD_DCRSET, XT_REG_IDX_OCD_DSR,
139 };
140
141 static const struct xtensa_user_reg_desc esp32_user_regs[ESP32_NUM_REGS - XT_NUM_REGS] = {
142 { "expstate", 0xE6, 0, 32, &xtensa_user_reg_u32_type },
143 { "f64r_lo", 0xEA, 0, 32, &xtensa_user_reg_u32_type },
144 { "f64r_hi", 0xEB, 0, 32, &xtensa_user_reg_u32_type },
145 { "f64s", 0xEC, 0, 32, &xtensa_user_reg_u32_type },
146 };
147
148 static const struct xtensa_config esp32_xtensa_cfg = {
149 .density = true,
150 .aregs_num = XT_AREGS_NUM_MAX,
151 .windowed = true,
152 .coproc = true,
153 .fp_coproc = true,
154 .loop = true,
155 .miscregs_num = 4,
156 .threadptr = true,
157 .boolean = true,
158 .reloc_vec = true,
159 .proc_id = true,
160 .cond_store = true,
161 .mac16 = true,
162 .user_regs_num = ARRAY_SIZE(esp32_user_regs),
163 .user_regs = esp32_user_regs,
164 .fetch_user_regs = xtensa_fetch_user_regs_u32,
165 .queue_write_dirty_user_regs = xtensa_queue_write_dirty_user_regs_u32,
166 .gdb_general_regs_num = ESP32_NUM_REGS_G_COMMAND,
167 .gdb_regs_mapping = esp32_gdb_regs_mapping,
168 .irom = {
169 .count = 2,
170 .regions = {
171 {
172 .base = ESP32_IROM_LOW,
173 .size = ESP32_IROM_HIGH - ESP32_IROM_LOW,
174 .access = XT_MEM_ACCESS_READ,
175 },
176 {
177 .base = ESP32_IROM_MASK_LOW,
178 .size = ESP32_IROM_MASK_HIGH - ESP32_IROM_MASK_LOW,
179 .access = XT_MEM_ACCESS_READ,
180 },
181 }
182 },
183 .iram = {
184 .count = 2,
185 .regions = {
186 {
187 .base = ESP32_IRAM_LOW,
188 .size = ESP32_IRAM_HIGH - ESP32_IRAM_LOW,
189 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
190 },
191 {
192 .base = ESP32_RTC_IRAM_LOW,
193 .size = ESP32_RTC_IRAM_HIGH - ESP32_RTC_IRAM_LOW,
194 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
195 },
196 }
197 },
198 .drom = {
199 .count = 1,
200 .regions = {
201 {
202 .base = ESP32_DROM_LOW,
203 .size = ESP32_DROM_HIGH - ESP32_DROM_LOW,
204 .access = XT_MEM_ACCESS_READ,
205 },
206 }
207 },
208 .dram = {
209 .count = 6,
210 .regions = {
211 {
212 .base = ESP32_DRAM_LOW,
213 .size = ESP32_DRAM_HIGH - ESP32_DRAM_LOW,
214 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
215 },
216 {
217 .base = ESP32_RTC_DRAM_LOW,
218 .size = ESP32_RTC_DRAM_HIGH - ESP32_RTC_DRAM_LOW,
219 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
220 },
221 {
222 .base = ESP32_RTC_DATA_LOW,
223 .size = ESP32_RTC_DATA_HIGH - ESP32_RTC_DATA_LOW,
224 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
225 },
226 {
227 .base = ESP32_EXTRAM_DATA_LOW,
228 .size = ESP32_EXTRAM_DATA_HIGH - ESP32_EXTRAM_DATA_LOW,
229 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
230 },
231 {
232 .base = ESP32_DR_REG_LOW,
233 .size = ESP32_DR_REG_HIGH - ESP32_DR_REG_LOW,
234 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
235 },
236 {
237 .base = ESP32_SYS_RAM_LOW,
238 .size = ESP32_SYS_RAM_HIGH - ESP32_SYS_RAM_LOW,
239 .access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE,
240 },
241 }
242 },
243 .exc = {
244 .enabled = true,
245 },
246 .irq = {
247 .enabled = true,
248 .irq_num = 32,
249 },
250 .high_irq = {
251 .enabled = true,
252 .excm_level = 3,
253 .nmi_num = 1,
254 },
255 .tim_irq = {
256 .enabled = true,
257 .comp_num = 3,
258 },
259 .debug = {
260 .enabled = true,
261 .irq_level = 6,
262 .ibreaks_num = 2,
263 .dbreaks_num = 2,
264 .icount_sz = 32,
265 },
266 .trace = {
267 .enabled = true,
268 .mem_sz = ESP32_TRACEMEM_BLOCK_SZ,
269 .reversed_mem_access = true,
270 },
271 };
272
273 /* 0 - don't care, 1 - TMS low, 2 - TMS high */
274 enum esp32_flash_bootstrap {
275 FBS_DONTCARE = 0,
276 FBS_TMSLOW,
277 FBS_TMSHIGH,
278 };
279
280 struct esp32_common {
281 struct esp_xtensa_smp_common esp_xtensa_smp;
282 enum esp32_flash_bootstrap flash_bootstrap;
283 };
284
285 static inline struct esp32_common *target_to_esp32(struct target *target)
286 {
287 return container_of(target->arch_info, struct esp32_common, esp_xtensa_smp);
288 }
289
290 /* Reset ESP32 peripherals.
291 * Postconditions: all peripherals except RTC_CNTL are reset, CPU's PC is undefined, PRO CPU is halted,
292 * APP CPU is in reset
293 * How this works:
294 * 0. make sure target is halted; if not, try to halt it; if that fails, try to reset it (via OCD) and then halt
295 * 1. set CPU initial PC to 0x50000000 (ESP32_SMP_RTC_DATA_LOW) by clearing RTC_CNTL_{PRO,APP}CPU_STAT_VECTOR_SEL
296 * 2. load stub code into ESP32_SMP_RTC_DATA_LOW; once executed, stub code will disable watchdogs and
297 * make CPU spin in an idle loop.
298 * 3. trigger SoC reset using RTC_CNTL_SW_SYS_RST bit
299 * 4. wait for the OCD to be reset
300 * 5. halt the target and wait for it to be halted (at this point CPU is in the idle loop)
301 * 6. restore initial PC and the contents of ESP32_SMP_RTC_DATA_LOW
302 * TODO: some state of RTC_CNTL is not reset during SW_SYS_RST. Need to reset that manually. */
303
304 const uint8_t esp32_reset_stub_code[] = {
305 #include "../../../contrib/loaders/reset/espressif/esp32/cpu_reset_handler_code.inc"
306 };
307
308 static int esp32_soc_reset(struct target *target)
309 {
310 int res;
311 struct target_list *head;
312 struct xtensa *xtensa;
313
314 LOG_DEBUG("start");
315 /* In order to write to peripheral registers, target must be halted first */
316 if (target->state != TARGET_HALTED) {
317 LOG_DEBUG("Target not halted before SoC reset, trying to halt it first");
318 xtensa_halt(target);
319 res = target_wait_state(target, TARGET_HALTED, 1000);
320 if (res != ERROR_OK) {
321 LOG_DEBUG("Couldn't halt target before SoC reset, trying to do reset-halt");
322 res = xtensa_assert_reset(target);
323 if (res != ERROR_OK) {
324 LOG_ERROR(
325 "Couldn't halt target before SoC reset! (xtensa_assert_reset returned %d)",
326 res);
327 return res;
328 }
329 alive_sleep(10);
330 xtensa_poll(target);
331 bool reset_halt_save = target->reset_halt;
332 target->reset_halt = true;
333 res = xtensa_deassert_reset(target);
334 target->reset_halt = reset_halt_save;
335 if (res != ERROR_OK) {
336 LOG_ERROR(
337 "Couldn't halt target before SoC reset! (xtensa_deassert_reset returned %d)",
338 res);
339 return res;
340 }
341 alive_sleep(10);
342 xtensa_poll(target);
343 xtensa_halt(target);
344 res = target_wait_state(target, TARGET_HALTED, 1000);
345 if (res != ERROR_OK) {
346 LOG_ERROR("Couldn't halt target before SoC reset");
347 return res;
348 }
349 }
350 }
351
352 if (target->smp) {
353 foreach_smp_target(head, target->smp_targets) {
354 xtensa = target_to_xtensa(head->target);
355 /* if any of the cores is stalled unstall them */
356 if (xtensa_dm_core_is_stalled(&xtensa->dbg_mod)) {
357 LOG_TARGET_DEBUG(head->target, "Unstall CPUs before SW reset!");
358 res = target_write_u32(target,
359 ESP32_RTC_CNTL_SW_CPU_STALL_REG,
360 ESP32_RTC_CNTL_SW_CPU_STALL_DEF);
361 if (res != ERROR_OK) {
362 LOG_TARGET_ERROR(head->target, "Failed to unstall CPUs before SW reset!");
363 return res;
364 }
365 break; /* both cores are unstalled now, so exit the loop */
366 }
367 }
368 }
369
370 LOG_DEBUG("Loading stub code into RTC RAM");
371 uint8_t slow_mem_save[sizeof(esp32_reset_stub_code)];
372
373 /* Save contents of RTC_SLOW_MEM which we are about to overwrite */
374 res = target_read_buffer(target, ESP32_RTC_SLOW_MEM_BASE, sizeof(slow_mem_save), slow_mem_save);
375 if (res != ERROR_OK) {
376 LOG_ERROR("Failed to save contents of RTC_SLOW_MEM (%d)!", res);
377 return res;
378 }
379
380 /* Write stub code into RTC_SLOW_MEM */
381 res = target_write_buffer(target, ESP32_RTC_SLOW_MEM_BASE, sizeof(esp32_reset_stub_code), esp32_reset_stub_code);
382 if (res != ERROR_OK) {
383 LOG_ERROR("Failed to write stub (%d)!", res);
384 return res;
385 }
386
387 LOG_DEBUG("Resuming the target");
388 xtensa = target_to_xtensa(target);
389 xtensa->suppress_dsr_errors = true;
390 res = xtensa_resume(target, 0, ESP32_RTC_SLOW_MEM_BASE + 4, 0, 0);
391 xtensa->suppress_dsr_errors = false;
392 if (res != ERROR_OK) {
393 LOG_ERROR("Failed to run stub (%d)!", res);
394 return res;
395 }
396 LOG_DEBUG("resume done, waiting for the target to come alive");
397
398 /* Wait for SoC to reset */
399 alive_sleep(100);
400 int64_t timeout = timeval_ms() + 100;
401 bool get_timeout = false;
402 while (target->state != TARGET_RESET && target->state != TARGET_RUNNING) {
403 alive_sleep(10);
404 xtensa_poll(target);
405 if (timeval_ms() >= timeout) {
406 LOG_TARGET_ERROR(target, "Timed out waiting for CPU to be reset, target state=%d", target->state);
407 get_timeout = true;
408 break;
409 }
410 }
411
412 /* Halt the CPU again */
413 LOG_DEBUG("halting the target");
414 xtensa_halt(target);
415 res = target_wait_state(target, TARGET_HALTED, 1000);
416 if (res == ERROR_OK) {
417 LOG_DEBUG("restoring RTC_SLOW_MEM");
418 res = target_write_buffer(target, ESP32_RTC_SLOW_MEM_BASE, sizeof(slow_mem_save), slow_mem_save);
419 if (res != ERROR_OK)
420 LOG_TARGET_ERROR(target, "Failed to restore contents of RTC_SLOW_MEM (%d)!", res);
421 } else {
422 LOG_TARGET_ERROR(target, "Timed out waiting for CPU to be halted after SoC reset");
423 }
424
425 return get_timeout ? ERROR_TARGET_TIMEOUT : res;
426 }
427
428 static int esp32_disable_wdts(struct target *target)
429 {
430 /* TIMG1 WDT */
431 int res = target_write_u32(target, ESP32_TIMG0WDT_PROTECT, ESP32_WDT_WKEY_VALUE);
432 if (res != ERROR_OK) {
433 LOG_ERROR("Failed to write ESP32_TIMG0WDT_PROTECT (%d)!", res);
434 return res;
435 }
436 res = target_write_u32(target, ESP32_TIMG0WDT_CFG0, 0);
437 if (res != ERROR_OK) {
438 LOG_ERROR("Failed to write ESP32_TIMG0WDT_CFG0 (%d)!", res);
439 return res;
440 }
441 /* TIMG2 WDT */
442 res = target_write_u32(target, ESP32_TIMG1WDT_PROTECT, ESP32_WDT_WKEY_VALUE);
443 if (res != ERROR_OK) {
444 LOG_ERROR("Failed to write ESP32_TIMG1WDT_PROTECT (%d)!", res);
445 return res;
446 }
447 res = target_write_u32(target, ESP32_TIMG1WDT_CFG0, 0);
448 if (res != ERROR_OK) {
449 LOG_ERROR("Failed to write ESP32_TIMG1WDT_CFG0 (%d)!", res);
450 return res;
451 }
452 /* RTC WDT */
453 res = target_write_u32(target, ESP32_RTCWDT_PROTECT, ESP32_WDT_WKEY_VALUE);
454 if (res != ERROR_OK) {
455 LOG_ERROR("Failed to write ESP32_RTCWDT_PROTECT (%d)!", res);
456 return res;
457 }
458 res = target_write_u32(target, ESP32_RTCWDT_CFG, 0);
459 if (res != ERROR_OK) {
460 LOG_ERROR("Failed to write ESP32_RTCWDT_CFG (%d)!", res);
461 return res;
462 }
463 return ERROR_OK;
464 }
465
466 static int esp32_on_halt(struct target *target)
467 {
468 return esp32_disable_wdts(target);
469 }
470
471 static int esp32_arch_state(struct target *target)
472 {
473 return ERROR_OK;
474 }
475
476 static int esp32_virt2phys(struct target *target,
477 target_addr_t virtual, target_addr_t *physical)
478 {
479 if (physical) {
480 *physical = virtual;
481 return ERROR_OK;
482 }
483 return ERROR_FAIL;
484 }
485
486
487 /* The TDI pin is also used as a flash Vcc bootstrap pin. If we reset the CPU externally, the last state of the TDI pin
488 * can allow the power to an 1.8V flash chip to be raised to 3.3V, or the other way around. Users can use the
489 * esp32 flashbootstrap command to set a level, and this routine will make sure the tdi line will return to
490 * that when the jtag port is idle. */
491
492 static void esp32_queue_tdi_idle(struct target *target)
493 {
494 struct esp32_common *esp32 = target_to_esp32(target);
495 static uint32_t value;
496 uint8_t t[4] = { 0, 0, 0, 0 };
497
498 if (esp32->flash_bootstrap == FBS_TMSLOW)
499 /* Make sure tdi is 0 at the exit of queue execution */
500 value = 0;
501 else if (esp32->flash_bootstrap == FBS_TMSHIGH)
502 /* Make sure tdi is 1 at the exit of queue execution */
503 value = 1;
504 else
505 return;
506
507 /* Scan out 1 bit, do not move from IRPAUSE after we're done. */
508 buf_set_u32(t, 0, 1, value);
509 jtag_add_plain_ir_scan(1, t, NULL, TAP_IRPAUSE);
510 }
511
512 static int esp32_target_init(struct command_context *cmd_ctx, struct target *target)
513 {
514 return esp_xtensa_smp_target_init(cmd_ctx, target);
515 }
516
517 static const struct xtensa_debug_ops esp32_dbg_ops = {
518 .queue_enable = xtensa_dm_queue_enable,
519 .queue_reg_read = xtensa_dm_queue_reg_read,
520 .queue_reg_write = xtensa_dm_queue_reg_write
521 };
522
523 static const struct xtensa_power_ops esp32_pwr_ops = {
524 .queue_reg_read = xtensa_dm_queue_pwr_reg_read,
525 .queue_reg_write = xtensa_dm_queue_pwr_reg_write
526 };
527
528 static const struct esp_xtensa_smp_chip_ops esp32_chip_ops = {
529 .reset = esp32_soc_reset,
530 .on_halt = esp32_on_halt
531 };
532
533 static int esp32_target_create(struct target *target, Jim_Interp *interp)
534 {
535 struct xtensa_debug_module_config esp32_dm_cfg = {
536 .dbg_ops = &esp32_dbg_ops,
537 .pwr_ops = &esp32_pwr_ops,
538 .tap = target->tap,
539 .queue_tdi_idle = esp32_queue_tdi_idle,
540 .queue_tdi_idle_arg = target
541 };
542
543 struct esp32_common *esp32 = calloc(1, sizeof(struct esp32_common));
544 if (!esp32) {
545 LOG_ERROR("Failed to alloc memory for arch info!");
546 return ERROR_FAIL;
547 }
548
549 int ret = esp_xtensa_smp_init_arch_info(target, &esp32->esp_xtensa_smp, &esp32_xtensa_cfg,
550 &esp32_dm_cfg, &esp32_chip_ops);
551 if (ret != ERROR_OK) {
552 LOG_ERROR("Failed to init arch info!");
553 free(esp32);
554 return ret;
555 }
556 esp32->flash_bootstrap = FBS_DONTCARE;
557
558 /* Assume running target. If different, the first poll will fix this. */
559 target->state = TARGET_RUNNING;
560 target->debug_reason = DBG_REASON_NOTHALTED;
561 return ERROR_OK;
562 }
563
564 COMMAND_HELPER(esp32_cmd_flashbootstrap_do, struct esp32_common *esp32)
565 {
566 int state = -1;
567
568 if (CMD_ARGC < 1) {
569 const char *st;
570 state = esp32->flash_bootstrap;
571 if (state == FBS_DONTCARE)
572 st = "Don't care";
573 else if (state == FBS_TMSLOW)
574 st = "Low (3.3V)";
575 else if (state == FBS_TMSHIGH)
576 st = "High (1.8V)";
577 else
578 st = "None";
579 command_print(CMD, "Current idle tms state: %s", st);
580 return ERROR_OK;
581 }
582
583 if (!strcasecmp(CMD_ARGV[0], "none"))
584 state = FBS_DONTCARE;
585 else if (!strcasecmp(CMD_ARGV[0], "1.8"))
586 state = FBS_TMSHIGH;
587 else if (!strcasecmp(CMD_ARGV[0], "3.3"))
588 state = FBS_TMSLOW;
589 else if (!strcasecmp(CMD_ARGV[0], "high"))
590 state = FBS_TMSHIGH;
591 else if (!strcasecmp(CMD_ARGV[0], "low"))
592 state = FBS_TMSLOW;
593
594 if (state == -1) {
595 command_print(CMD,
596 "Argument unknown. Please pick one of none, high, low, 1.8 or 3.3");
597 return ERROR_FAIL;
598 }
599 esp32->flash_bootstrap = state;
600 return ERROR_OK;
601 }
602
603 COMMAND_HANDLER(esp32_cmd_flashbootstrap)
604 {
605 struct target *target = get_current_target(CMD_CTX);
606
607 if (target->smp) {
608 struct target_list *head;
609 struct target *curr;
610 foreach_smp_target(head, target->smp_targets) {
611 curr = head->target;
612 int ret = CALL_COMMAND_HANDLER(esp32_cmd_flashbootstrap_do,
613 target_to_esp32(curr));
614 if (ret != ERROR_OK)
615 return ret;
616 }
617 return ERROR_OK;
618 }
619 return CALL_COMMAND_HANDLER(esp32_cmd_flashbootstrap_do,
620 target_to_esp32(target));
621 }
622
623 static const struct command_registration esp32_any_command_handlers[] = {
624 {
625 .name = "flashbootstrap",
626 .handler = esp32_cmd_flashbootstrap,
627 .mode = COMMAND_ANY,
628 .help =
629 "Set the idle state of the TMS pin, which at reset also is the voltage selector for the flash chip.",
630 .usage = "none|1.8|3.3|high|low",
631 },
632 COMMAND_REGISTRATION_DONE
633 };
634
635 static const struct command_registration esp32_command_handlers[] = {
636 {
637 .chain = esp_xtensa_smp_command_handlers,
638 },
639 {
640 .name = "esp32",
641 .usage = "",
642 .chain = smp_command_handlers,
643 },
644 {
645 .name = "esp32",
646 .usage = "",
647 .chain = esp32_any_command_handlers,
648 },
649 COMMAND_REGISTRATION_DONE
650 };
651
652 /** Holds methods for Xtensa targets. */
653 struct target_type esp32_target = {
654 .name = "esp32",
655
656 .poll = esp_xtensa_smp_poll,
657 .arch_state = esp32_arch_state,
658
659 .halt = xtensa_halt,
660 .resume = esp_xtensa_smp_resume,
661 .step = esp_xtensa_smp_step,
662
663 .assert_reset = esp_xtensa_smp_assert_reset,
664 .deassert_reset = esp_xtensa_smp_deassert_reset,
665 .soft_reset_halt = esp_xtensa_smp_soft_reset_halt,
666
667 .virt2phys = esp32_virt2phys,
668 .mmu = xtensa_mmu_is_enabled,
669 .read_memory = xtensa_read_memory,
670 .write_memory = xtensa_write_memory,
671
672 .read_buffer = xtensa_read_buffer,
673 .write_buffer = xtensa_write_buffer,
674
675 .checksum_memory = xtensa_checksum_memory,
676
677 .get_gdb_arch = xtensa_get_gdb_arch,
678 .get_gdb_reg_list = xtensa_get_gdb_reg_list,
679
680 .add_breakpoint = esp_xtensa_breakpoint_add,
681 .remove_breakpoint = esp_xtensa_breakpoint_remove,
682
683 .add_watchpoint = esp_xtensa_smp_watchpoint_add,
684 .remove_watchpoint = esp_xtensa_smp_watchpoint_remove,
685
686 .target_create = esp32_target_create,
687 .init_target = esp32_target_init,
688 .examine = xtensa_examine,
689 .deinit_target = esp_xtensa_target_deinit,
690
691 .commands = esp32_command_handlers,
692 };

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)