1 /* SPDX-License-Identifier: GPL-2.0-or-later */
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 ***************************************************************************/
14 #include <helper/time_support.h>
15 #include <target/target.h>
16 #include <target/target_type.h>
17 #include <target/smp.h>
20 #include "esp_xtensa_smp.h"
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
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
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)
65 #define ESP32_TRACEMEM_BLOCK_SZ 0x4000
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)
72 #define ESP32_RTC_CNTL_SW_CPU_STALL_REG (ESP32_RTCCNTL_BASE + 0xac)
73 #define ESP32_RTC_CNTL_SW_CPU_STALL_DEF 0x0
76 /* this should map local reg IDs to GDB reg mapping as defined in xtensa-config.c 'rmap' in
78 static const unsigned int esp32_gdb_regs_mapping
[ESP32_NUM_REGS
] = {
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
,
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
,
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
},
148 static const struct xtensa_config esp32_xtensa_cfg
= {
150 .aregs_num
= XT_AREGS_NUM_MAX
,
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
,
172 .base
= ESP32_IROM_LOW
,
173 .size
= ESP32_IROM_HIGH
- ESP32_IROM_LOW
,
174 .access
= XT_MEM_ACCESS_READ
,
177 .base
= ESP32_IROM_MASK_LOW
,
178 .size
= ESP32_IROM_MASK_HIGH
- ESP32_IROM_MASK_LOW
,
179 .access
= XT_MEM_ACCESS_READ
,
187 .base
= ESP32_IRAM_LOW
,
188 .size
= ESP32_IRAM_HIGH
- ESP32_IRAM_LOW
,
189 .access
= XT_MEM_ACCESS_READ
| XT_MEM_ACCESS_WRITE
,
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
,
202 .base
= ESP32_DROM_LOW
,
203 .size
= ESP32_DROM_HIGH
- ESP32_DROM_LOW
,
204 .access
= XT_MEM_ACCESS_READ
,
212 .base
= ESP32_DRAM_LOW
,
213 .size
= ESP32_DRAM_HIGH
- ESP32_DRAM_LOW
,
214 .access
= XT_MEM_ACCESS_READ
| XT_MEM_ACCESS_WRITE
,
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
,
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
,
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
,
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
,
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
,
268 .mem_sz
= ESP32_TRACEMEM_BLOCK_SZ
,
269 .reversed_mem_access
= true,
273 /* 0 - don't care, 1 - TMS low, 2 - TMS high */
274 enum esp32_flash_bootstrap
{
280 struct esp32_common
{
281 struct esp_xtensa_smp_common esp_xtensa_smp
;
282 enum esp32_flash_bootstrap flash_bootstrap
;
285 static inline struct esp32_common
*target_to_esp32(struct target
*target
)
287 return container_of(target
->arch_info
, struct esp32_common
, esp_xtensa_smp
);
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
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. */
304 const uint8_t esp32_reset_stub_code
[] = {
305 #include "../../../contrib/loaders/reset/espressif/esp32/cpu_reset_handler_code.inc"
308 static int esp32_soc_reset(struct target
*target
)
311 struct target_list
*head
;
312 struct xtensa
*xtensa
;
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");
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
) {
325 "Couldn't halt target before SoC reset! (xtensa_assert_reset returned %d)",
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
) {
337 "Couldn't halt target before SoC reset! (xtensa_deassert_reset returned %d)",
344 res
= target_wait_state(target
, TARGET_HALTED
, 1000);
345 if (res
!= ERROR_OK
) {
346 LOG_ERROR("Couldn't halt target before SoC reset");
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!");
365 break; /* both cores are unstalled now, so exit the loop */
370 LOG_DEBUG("Loading stub code into RTC RAM");
371 uint8_t slow_mem_save
[sizeof(esp32_reset_stub_code
)];
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
);
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
);
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
);
396 LOG_DEBUG("resume done, waiting for the target to come alive");
398 /* Wait for SoC to reset */
400 int64_t timeout
= timeval_ms() + 100;
401 bool get_timeout
= false;
402 while (target
->state
!= TARGET_RESET
&& target
->state
!= TARGET_RUNNING
) {
405 if (timeval_ms() >= timeout
) {
406 LOG_TARGET_ERROR(target
, "Timed out waiting for CPU to be reset, target state=%d", target
->state
);
412 /* Halt the CPU again */
413 LOG_DEBUG("halting the 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
);
420 LOG_TARGET_ERROR(target
, "Failed to restore contents of RTC_SLOW_MEM (%d)!", res
);
422 LOG_TARGET_ERROR(target
, "Timed out waiting for CPU to be halted after SoC reset");
425 return get_timeout
? ERROR_TARGET_TIMEOUT
: res
;
428 static int esp32_disable_wdts(struct target
*target
)
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
);
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
);
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
);
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
);
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
);
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
);
466 static int esp32_on_halt(struct target
*target
)
468 return esp32_disable_wdts(target
);
471 static int esp32_arch_state(struct target
*target
)
476 static int esp32_virt2phys(struct target
*target
,
477 target_addr_t
virtual, target_addr_t
*physical
)
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. */
492 static void esp32_queue_tdi_idle(struct target
*target
)
494 struct esp32_common
*esp32
= target_to_esp32(target
);
495 static uint32_t value
;
496 uint8_t t
[4] = { 0, 0, 0, 0 };
498 if (esp32
->flash_bootstrap
== FBS_TMSLOW
)
499 /* Make sure tdi is 0 at the exit of queue execution */
501 else if (esp32
->flash_bootstrap
== FBS_TMSHIGH
)
502 /* Make sure tdi is 1 at the exit of queue execution */
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
);
512 static int esp32_target_init(struct command_context
*cmd_ctx
, struct target
*target
)
514 return esp_xtensa_smp_target_init(cmd_ctx
, target
);
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
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
528 static const struct esp_xtensa_smp_chip_ops esp32_chip_ops
= {
529 .reset
= esp32_soc_reset
,
530 .on_halt
= esp32_on_halt
533 static int esp32_target_create(struct target
*target
, Jim_Interp
*interp
)
535 struct xtensa_debug_module_config esp32_dm_cfg
= {
536 .dbg_ops
= &esp32_dbg_ops
,
537 .pwr_ops
= &esp32_pwr_ops
,
539 .queue_tdi_idle
= esp32_queue_tdi_idle
,
540 .queue_tdi_idle_arg
= target
543 struct esp32_common
*esp32
= calloc(1, sizeof(struct esp32_common
));
545 LOG_ERROR("Failed to alloc memory for arch info!");
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!");
556 esp32
->flash_bootstrap
= FBS_DONTCARE
;
558 /* Assume running target. If different, the first poll will fix this. */
559 target
->state
= TARGET_RUNNING
;
560 target
->debug_reason
= DBG_REASON_NOTHALTED
;
564 COMMAND_HELPER(esp32_cmd_flashbootstrap_do
, struct esp32_common
*esp32
)
570 state
= esp32
->flash_bootstrap
;
571 if (state
== FBS_DONTCARE
)
573 else if (state
== FBS_TMSLOW
)
575 else if (state
== FBS_TMSHIGH
)
579 command_print(CMD
, "Current idle tms state: %s", st
);
583 if (!strcasecmp(CMD_ARGV
[0], "none"))
584 state
= FBS_DONTCARE
;
585 else if (!strcasecmp(CMD_ARGV
[0], "1.8"))
587 else if (!strcasecmp(CMD_ARGV
[0], "3.3"))
589 else if (!strcasecmp(CMD_ARGV
[0], "high"))
591 else if (!strcasecmp(CMD_ARGV
[0], "low"))
596 "Argument unknown. Please pick one of none, high, low, 1.8 or 3.3");
599 esp32
->flash_bootstrap
= state
;
603 COMMAND_HANDLER(esp32_cmd_flashbootstrap
)
605 struct target
*target
= get_current_target(CMD_CTX
);
608 struct target_list
*head
;
610 foreach_smp_target(head
, target
->smp_targets
) {
612 int ret
= CALL_COMMAND_HANDLER(esp32_cmd_flashbootstrap_do
,
613 target_to_esp32(curr
));
619 return CALL_COMMAND_HANDLER(esp32_cmd_flashbootstrap_do
,
620 target_to_esp32(target
));
623 static const struct command_registration esp32_any_command_handlers
[] = {
625 .name
= "flashbootstrap",
626 .handler
= esp32_cmd_flashbootstrap
,
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",
632 COMMAND_REGISTRATION_DONE
635 static const struct command_registration esp32_command_handlers
[] = {
637 .chain
= esp_xtensa_smp_command_handlers
,
642 .chain
= smp_command_handlers
,
647 .chain
= esp32_any_command_handlers
,
649 COMMAND_REGISTRATION_DONE
652 /** Holds methods for Xtensa targets. */
653 struct target_type esp32_target
= {
656 .poll
= esp_xtensa_smp_poll
,
657 .arch_state
= esp32_arch_state
,
660 .resume
= esp_xtensa_smp_resume
,
661 .step
= esp_xtensa_smp_step
,
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
,
667 .virt2phys
= esp32_virt2phys
,
668 .mmu
= xtensa_mmu_is_enabled
,
669 .read_memory
= xtensa_read_memory
,
670 .write_memory
= xtensa_write_memory
,
672 .read_buffer
= xtensa_read_buffer
,
673 .write_buffer
= xtensa_write_buffer
,
675 .checksum_memory
= xtensa_checksum_memory
,
677 .get_gdb_arch
= xtensa_get_gdb_arch
,
678 .get_gdb_reg_list
= xtensa_get_gdb_reg_list
,
680 .add_breakpoint
= esp_xtensa_breakpoint_add
,
681 .remove_breakpoint
= esp_xtensa_breakpoint_remove
,
683 .add_watchpoint
= esp_xtensa_smp_watchpoint_add
,
684 .remove_watchpoint
= esp_xtensa_smp_watchpoint_remove
,
686 .target_create
= esp32_target_create
,
687 .init_target
= esp32_target_init
,
688 .examine
= xtensa_examine
,
689 .deinit_target
= esp_xtensa_target_deinit
,
691 .commands
= esp32_command_handlers
,
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)