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

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)