1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 /***************************************************************************
4 * ESP32-S2 target for OpenOCD *
5 * Copyright (C) 2019 Espressif Systems Ltd. *
6 ***************************************************************************/
12 #include <helper/time_support.h>
14 #include <target/target.h>
15 #include <target/target_type.h>
16 #include "esp_xtensa.h"
19 * TODO: read memory configuration from target registers */
20 #define ESP32_S2_IROM_MASK_LOW 0x40000000
21 #define ESP32_S2_IROM_MASK_HIGH 0x40020000
22 #define ESP32_S2_IRAM_LOW 0x40020000
23 #define ESP32_S2_IRAM_HIGH 0x40070000
24 #define ESP32_S2_DRAM_LOW 0x3ffb0000
25 #define ESP32_S2_DRAM_HIGH 0x40000000
26 #define ESP32_S2_RTC_IRAM_LOW 0x40070000
27 #define ESP32_S2_RTC_IRAM_HIGH 0x40072000
28 #define ESP32_S2_RTC_DRAM_LOW 0x3ff9e000
29 #define ESP32_S2_RTC_DRAM_HIGH 0x3ffa0000
30 #define ESP32_S2_RTC_DATA_LOW 0x50000000
31 #define ESP32_S2_RTC_DATA_HIGH 0x50002000
32 #define ESP32_S2_EXTRAM_DATA_LOW 0x3f500000
33 #define ESP32_S2_EXTRAM_DATA_HIGH 0x3ff80000
34 #define ESP32_S2_DR_REG_LOW 0x3f400000
35 #define ESP32_S2_DR_REG_HIGH 0x3f4d3FFC
36 #define ESP32_S2_SYS_RAM_LOW 0x60000000UL
37 #define ESP32_S2_SYS_RAM_HIGH (ESP32_S2_SYS_RAM_LOW + 0x20000000UL)
38 /* ESP32-S2 DROM mapping is not contiguous. */
39 /* IDF declares this as 0x3F000000..0x3FF80000, but there are peripheral registers mapped to
40 * 0x3f400000..0x3f4d3FFC. */
41 #define ESP32_S2_DROM0_LOW ESP32_S2_DROM_LOW
42 #define ESP32_S2_DROM0_HIGH ESP32_S2_DR_REG_LOW
43 #define ESP32_S2_DROM1_LOW ESP32_S2_DR_REG_HIGH
44 #define ESP32_S2_DROM1_HIGH ESP32_S2_DROM_HIGH
47 #define ESP32_S2_WDT_WKEY_VALUE 0x50d83aa1
48 #define ESP32_S2_TIMG0_BASE 0x3f41F000
49 #define ESP32_S2_TIMG1_BASE 0x3f420000
50 #define ESP32_S2_TIMGWDT_CFG0_OFF 0x48
51 #define ESP32_S2_TIMGWDT_PROTECT_OFF 0x64
52 #define ESP32_S2_TIMG0WDT_CFG0 (ESP32_S2_TIMG0_BASE + ESP32_S2_TIMGWDT_CFG0_OFF)
53 #define ESP32_S2_TIMG1WDT_CFG0 (ESP32_S2_TIMG1_BASE + ESP32_S2_TIMGWDT_CFG0_OFF)
54 #define ESP32_S2_TIMG0WDT_PROTECT (ESP32_S2_TIMG0_BASE + ESP32_S2_TIMGWDT_PROTECT_OFF)
55 #define ESP32_S2_TIMG1WDT_PROTECT (ESP32_S2_TIMG1_BASE + ESP32_S2_TIMGWDT_PROTECT_OFF)
56 #define ESP32_S2_RTCCNTL_BASE 0x3f408000
57 #define ESP32_S2_RTCWDT_CFG_OFF 0x94
58 #define ESP32_S2_RTCWDT_PROTECT_OFF 0xAC
59 #define ESP32_S2_SWD_CONF_OFF 0xB0
60 #define ESP32_S2_SWD_WPROTECT_OFF 0xB4
61 #define ESP32_S2_RTC_CNTL_DIG_PWC_REG_OFF 0x8C
62 #define ESP32_S2_RTC_CNTL_DIG_PWC_REG (ESP32_S2_RTCCNTL_BASE + ESP32_S2_RTC_CNTL_DIG_PWC_REG_OFF)
63 #define ESP32_S2_RTCWDT_CFG (ESP32_S2_RTCCNTL_BASE + ESP32_S2_RTCWDT_CFG_OFF)
64 #define ESP32_S2_RTCWDT_PROTECT (ESP32_S2_RTCCNTL_BASE + ESP32_S2_RTCWDT_PROTECT_OFF)
65 #define ESP32_S2_SWD_CONF_REG (ESP32_S2_RTCCNTL_BASE + ESP32_S2_SWD_CONF_OFF)
66 #define ESP32_S2_SWD_WPROTECT_REG (ESP32_S2_RTCCNTL_BASE + ESP32_S2_SWD_WPROTECT_OFF)
67 #define ESP32_S2_SWD_AUTO_FEED_EN_M BIT(31)
68 #define ESP32_S2_SWD_WKEY_VALUE 0x8F1D312AU
69 #define ESP32_S2_OPTIONS0 (ESP32_S2_RTCCNTL_BASE + 0x0000)
70 #define ESP32_S2_SW_SYS_RST_M 0x80000000
71 #define ESP32_S2_SW_SYS_RST_V 0x1
72 #define ESP32_S2_SW_SYS_RST_S 31
73 #define ESP32_S2_SW_STALL_PROCPU_C0_M ((ESP32_S2_SW_STALL_PROCPU_C0_V) << (ESP32_S2_SW_STALL_PROCPU_C0_S))
74 #define ESP32_S2_SW_STALL_PROCPU_C0_V 0x3
75 #define ESP32_S2_SW_STALL_PROCPU_C0_S 2
76 #define ESP32_S2_SW_CPU_STALL (ESP32_S2_RTCCNTL_BASE + 0x00B8)
77 #define ESP32_S2_SW_STALL_PROCPU_C1_M ((ESP32_S2_SW_STALL_PROCPU_C1_V) << (ESP32_S2_SW_STALL_PROCPU_C1_S))
78 #define ESP32_S2_SW_STALL_PROCPU_C1_V 0x3FU
79 #define ESP32_S2_SW_STALL_PROCPU_C1_S 26
80 #define ESP32_S2_CLK_CONF (ESP32_S2_RTCCNTL_BASE + 0x0074)
81 #define ESP32_S2_CLK_CONF_DEF 0x1583218
82 #define ESP32_S2_STORE4 (ESP32_S2_RTCCNTL_BASE + 0x00BC)
83 #define ESP32_S2_STORE5 (ESP32_S2_RTCCNTL_BASE + 0x00C0)
84 #define ESP32_S2_DPORT_PMS_OCCUPY_3 0x3F4C10E0
86 #define ESP32_S2_TRACEMEM_BLOCK_SZ 0x4000
88 #define ESP32_S2_DR_REG_UART_BASE 0x3f400000
89 #define ESP32_S2_REG_UART_BASE(i) (ESP32_S2_DR_REG_UART_BASE + (i) * 0x10000)
90 #define ESP32_S2_UART_DATE_REG(i) (ESP32_S2_REG_UART_BASE(i) + 0x74)
91 struct esp32s2_common {
92 struct esp_xtensa_common esp_xtensa;
95 static int esp32s2_soc_reset(struct target *target);
96 static int esp32s2_disable_wdts(struct target *target);
98 static int esp32s2_assert_reset(struct target *target)
103 static int esp32s2_deassert_reset(struct target *target)
105 struct xtensa *xtensa = target_to_xtensa(target);
107 LOG_TARGET_DEBUG(target, "begin");
109 int res = xtensa_deassert_reset(target);
113 /* restore configured value
114 esp32s2_soc_reset() modified it, but can not restore just after SW reset for some reason (???) */
115 res = xtensa_smpbreak_write(xtensa, xtensa->smp_break);
116 if (res != ERROR_OK) {
117 LOG_ERROR("Failed to restore smpbreak (%d)!", res);
123 int esp32s2_soft_reset_halt(struct target *target)
125 LOG_TARGET_DEBUG(target, "begin");
127 /* Reset the SoC first */
128 int res = esp32s2_soc_reset(target);
131 return xtensa_soft_reset_halt(target);
134 static int esp32s2_set_peri_reg_mask(struct target *target,
140 int res = target_read_u32(target, addr, ®_val);
143 reg_val = (reg_val & (~mask)) | val;
144 res = target_write_u32(target, addr, reg_val);
151 static int esp32s2_stall_set(struct target *target, bool stall)
153 LOG_TARGET_DEBUG(target, "begin");
155 int res = esp32s2_set_peri_reg_mask(target,
156 ESP32_S2_SW_CPU_STALL,
157 ESP32_S2_SW_STALL_PROCPU_C1_M,
158 stall ? 0x21U << ESP32_S2_SW_STALL_PROCPU_C1_S : 0);
159 if (res != ERROR_OK) {
160 LOG_ERROR("Failed to write ESP32_S2_SW_CPU_STALL (%d)!", res);
163 res = esp32s2_set_peri_reg_mask(target,
165 ESP32_S2_SW_STALL_PROCPU_C0_M,
166 stall ? 0x2 << ESP32_S2_SW_STALL_PROCPU_C0_S : 0);
167 if (res != ERROR_OK) {
168 LOG_ERROR("Failed to write ESP32_S2_OPTIONS0 (%d)!", res);
174 static inline int esp32s2_stall(struct target *target)
176 return esp32s2_stall_set(target, true);
179 static inline int esp32s2_unstall(struct target *target)
181 return esp32s2_stall_set(target, false);
184 /* Reset ESP32-S2's peripherals.
185 Postconditions: all peripherals except RTC_CNTL are reset, CPU's PC is undefined, PRO CPU is halted, APP CPU is in reset
187 0. make sure target is halted; if not, try to halt it; if that fails, try to reset it (via OCD) and then halt
188 1. Resets clock related registers
190 3. trigger SoC reset using RTC_CNTL_SW_SYS_RST bit
191 4. CPU is reset and stalled at the first reset vector instruction
192 5. wait for the OCD to be reset
195 8. Disables WDTs and trace memory mapping
197 static int esp32s2_soc_reset(struct target *target)
200 struct xtensa *xtensa = target_to_xtensa(target);
204 /* In order to write to peripheral registers, target must be halted first */
205 if (target->state != TARGET_HALTED) {
206 LOG_TARGET_DEBUG(target, "Target not halted before SoC reset, trying to halt it first");
208 res = target_wait_state(target, TARGET_HALTED, 1000);
209 if (res != ERROR_OK) {
210 LOG_TARGET_DEBUG(target, "Couldn't halt target before SoC reset, trying to do reset-halt");
211 res = xtensa_assert_reset(target);
212 if (res != ERROR_OK) {
215 "Couldn't halt target before SoC reset! (xtensa_assert_reset returned %d)",
221 int reset_halt_save = target->reset_halt;
222 target->reset_halt = 1;
223 res = xtensa_deassert_reset(target);
224 target->reset_halt = reset_halt_save;
225 if (res != ERROR_OK) {
228 "Couldn't halt target before SoC reset! (xtensa_deassert_reset returned %d)",
235 res = target_wait_state(target, TARGET_HALTED, 1000);
236 if (res != ERROR_OK) {
237 LOG_TARGET_ERROR(target, "Couldn't halt target before SoC reset");
243 assert(target->state == TARGET_HALTED);
245 /* Set some clock-related RTC registers to the default values */
246 res = target_write_u32(target, ESP32_S2_STORE4, 0);
247 if (res != ERROR_OK) {
248 LOG_ERROR("Failed to write ESP32_S2_STORE4 (%d)!", res);
251 res = target_write_u32(target, ESP32_S2_STORE5, 0);
252 if (res != ERROR_OK) {
253 LOG_ERROR("Failed to write ESP32_S2_STORE5 (%d)!", res);
256 res = target_write_u32(target, ESP32_S2_RTC_CNTL_DIG_PWC_REG, 0);
257 if (res != ERROR_OK) {
258 LOG_ERROR("Failed to write ESP32_S2_RTC_CNTL_DIG_PWC_REG (%d)!", res);
261 res = target_write_u32(target, ESP32_S2_CLK_CONF, ESP32_S2_CLK_CONF_DEF);
262 if (res != ERROR_OK) {
263 LOG_ERROR("Failed to write ESP32_S2_CLK_CONF (%d)!", res);
267 res = esp32s2_stall(target);
271 res = xtensa_smpbreak_write(xtensa, OCDDCR_RUNSTALLINEN);
272 if (res != ERROR_OK) {
273 LOG_ERROR("Failed to set smpbreak (%d)!", res);
277 xtensa->suppress_dsr_errors = true;
278 res = esp32s2_set_peri_reg_mask(target,
280 ESP32_S2_SW_SYS_RST_M,
281 BIT(ESP32_S2_SW_SYS_RST_S));
282 xtensa->suppress_dsr_errors = false;
283 if (res != ERROR_OK) {
284 LOG_ERROR("Failed to write ESP32_S2_OPTIONS0 (%d)!", res);
287 /* Wait for SoC to reset */
289 int64_t timeout = timeval_ms() + 100;
290 while (target->state != TARGET_RESET && target->state != TARGET_RUNNING) {
293 if (timeval_ms() >= timeout) {
294 LOG_TARGET_ERROR(target, "Timed out waiting for CPU to be reset, target state=%d",
296 return ERROR_TARGET_TIMEOUT;
301 res = target_wait_state(target, TARGET_HALTED, 1000);
302 if (res != ERROR_OK) {
303 LOG_TARGET_ERROR(target, "Couldn't halt target before SoC reset");
307 res = esp32s2_unstall(target);
311 res = esp32s2_disable_wdts(target);
314 /* Disable trace memory mapping */
315 res = target_write_u32(target, ESP32_S2_DPORT_PMS_OCCUPY_3, 0);
316 if (res != ERROR_OK) {
317 LOG_ERROR("Failed to write ESP32_S2_DPORT_PMS_OCCUPY_3 (%d)!", res);
323 static int esp32s2_disable_wdts(struct target *target)
326 int res = target_write_u32(target, ESP32_S2_TIMG0WDT_PROTECT, ESP32_S2_WDT_WKEY_VALUE);
327 if (res != ERROR_OK) {
328 LOG_ERROR("Failed to write ESP32_S2_TIMG0WDT_PROTECT (%d)!", res);
331 res = target_write_u32(target, ESP32_S2_TIMG0WDT_CFG0, 0);
332 if (res != ERROR_OK) {
333 LOG_ERROR("Failed to write ESP32_S2_TIMG0WDT_CFG0 (%d)!", res);
337 res = target_write_u32(target, ESP32_S2_TIMG1WDT_PROTECT, ESP32_S2_WDT_WKEY_VALUE);
338 if (res != ERROR_OK) {
339 LOG_ERROR("Failed to write ESP32_S2_TIMG1WDT_PROTECT (%d)!", res);
342 res = target_write_u32(target, ESP32_S2_TIMG1WDT_CFG0, 0);
343 if (res != ERROR_OK) {
344 LOG_ERROR("Failed to write ESP32_S2_TIMG1WDT_CFG0 (%d)!", res);
348 res = target_write_u32(target, ESP32_S2_RTCWDT_PROTECT, ESP32_S2_WDT_WKEY_VALUE);
349 if (res != ERROR_OK) {
350 LOG_ERROR("Failed to write ESP32_S2_RTCWDT_PROTECT (%d)!", res);
353 res = target_write_u32(target, ESP32_S2_RTCWDT_CFG, 0);
354 if (res != ERROR_OK) {
355 LOG_ERROR("Failed to write ESP32_S2_RTCWDT_CFG (%d)!", res);
358 /* Enable SWD auto-feed */
359 res = target_write_u32(target, ESP32_S2_SWD_WPROTECT_REG, ESP32_S2_SWD_WKEY_VALUE);
360 if (res != ERROR_OK) {
361 LOG_ERROR("Failed to write ESP32_S2_SWD_WPROTECT_REG (%d)!", res);
364 uint32_t swd_conf_reg = 0;
365 res = target_read_u32(target, ESP32_S2_SWD_CONF_REG, &swd_conf_reg);
366 if (res != ERROR_OK) {
367 LOG_ERROR("Failed to read ESP32_S2_SWD_CONF_REG (%d)!", res);
370 swd_conf_reg |= ESP32_S2_SWD_AUTO_FEED_EN_M;
371 res = target_write_u32(target, ESP32_S2_SWD_CONF_REG, swd_conf_reg);
372 if (res != ERROR_OK) {
373 LOG_ERROR("Failed to write ESP32_S2_SWD_CONF_REG (%d)!", res);
379 static int esp32s2_arch_state(struct target *target)
384 static int esp32s2_on_halt(struct target *target)
386 return esp32s2_disable_wdts(target);
389 static int esp32s2_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)
391 int ret = xtensa_step(target, current, address, handle_breakpoints);
392 if (ret == ERROR_OK) {
393 esp32s2_on_halt(target);
394 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
399 static int esp32s2_poll(struct target *target)
401 enum target_state old_state = target->state;
402 int ret = esp_xtensa_poll(target);
404 if (old_state != TARGET_HALTED && target->state == TARGET_HALTED) {
405 /* Call any event callbacks that are applicable */
406 if (old_state == TARGET_DEBUG_RUNNING) {
407 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
409 esp32s2_on_halt(target);
410 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
417 static int esp32s2_virt2phys(struct target *target,
418 target_addr_t virtual, target_addr_t *physical)
424 static int esp32s2_target_init(struct command_context *cmd_ctx, struct target *target)
426 return esp_xtensa_target_init(cmd_ctx, target);
429 static const struct xtensa_debug_ops esp32s2_dbg_ops = {
430 .queue_enable = xtensa_dm_queue_enable,
431 .queue_reg_read = xtensa_dm_queue_reg_read,
432 .queue_reg_write = xtensa_dm_queue_reg_write
435 static const struct xtensa_power_ops esp32s2_pwr_ops = {
436 .queue_reg_read = xtensa_dm_queue_pwr_reg_read,
437 .queue_reg_write = xtensa_dm_queue_pwr_reg_write
440 static int esp32s2_target_create(struct target *target, Jim_Interp *interp)
442 struct xtensa_debug_module_config esp32s2_dm_cfg = {
443 .dbg_ops = &esp32s2_dbg_ops,
444 .pwr_ops = &esp32s2_pwr_ops,
446 .queue_tdi_idle = NULL,
447 .queue_tdi_idle_arg = NULL
450 /* creates xtensa object */
451 struct esp32s2_common *esp32 = calloc(1, sizeof(*esp32));
453 LOG_ERROR("Failed to alloc memory for arch info!");
457 int ret = esp_xtensa_init_arch_info(target, &esp32->esp_xtensa, &esp32s2_dm_cfg);
458 if (ret != ERROR_OK) {
459 LOG_ERROR("Failed to init arch info!");
464 /* Assume running target. If different, the first poll will fix this */
465 target->state = TARGET_RUNNING;
466 target->debug_reason = DBG_REASON_NOTHALTED;
470 static const struct command_registration esp32s2_command_handlers[] = {
472 .chain = xtensa_command_handlers,
474 COMMAND_REGISTRATION_DONE
477 /* Holds methods for Xtensa targets. */
478 struct target_type esp32s2_target = {
481 .poll = esp32s2_poll,
482 .arch_state = esp32s2_arch_state,
485 .resume = xtensa_resume,
486 .step = esp32s2_step,
488 .assert_reset = esp32s2_assert_reset,
489 .deassert_reset = esp32s2_deassert_reset,
490 .soft_reset_halt = esp32s2_soft_reset_halt,
492 .virt2phys = esp32s2_virt2phys,
493 .mmu = xtensa_mmu_is_enabled,
494 .read_memory = xtensa_read_memory,
495 .write_memory = xtensa_write_memory,
497 .read_buffer = xtensa_read_buffer,
498 .write_buffer = xtensa_write_buffer,
500 .checksum_memory = xtensa_checksum_memory,
502 .get_gdb_arch = xtensa_get_gdb_arch,
503 .get_gdb_reg_list = xtensa_get_gdb_reg_list,
505 .add_breakpoint = esp_xtensa_breakpoint_add,
506 .remove_breakpoint = esp_xtensa_breakpoint_remove,
508 .add_watchpoint = xtensa_watchpoint_add,
509 .remove_watchpoint = xtensa_watchpoint_remove,
511 .target_create = esp32s2_target_create,
512 .init_target = esp32s2_target_init,
513 .examine = xtensa_examine,
514 .deinit_target = esp_xtensa_target_deinit,
516 .commands = esp32s2_command_handlers,