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

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)