Skip to content

Commit

Permalink
target/{esp32s2,esp32s3,esp32c3}: disable SWD on reset or halt
Browse files Browse the repository at this point in the history
ESP32-S2, ESP32-S3, ESP32-C3 chips include a "Super watch-dog" module.
This is an additional watchdog which can reset the entire chip (both
digital and RTC domains). On ESP32-C3/S3 it is enabled by default at
start-up. On the ESP32-S2 it isn't enabled, but theoretically can be
enabled by the program being debugged.
To prevent SWD from resetting the chip during debugging, enable the
"auto-feed" feature. The RTC controller will keep feeding the SWD
as long as the RTC module clock (RTC_SLOW) is present.

For ESP32-S2, only need to modify esp32s2_disable_wdts function, as
esp32s2_soc_reset is implemented on OpenOCD side.

For ESP32-S3, need to modify both esp32s2_disable_wdts and the reset
stub, since the esp32s3_soc_reset is still implemented via a stub.

For ESP32-C3, there is no target-specific source file yet, so only
modify the esp32c3_wdt_disable procedure in the TCL scripts.

Closes #153.
  • Loading branch information
igrr committed May 11, 2021
1 parent f702229 commit 5d011fa
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 14 deletions.
24 changes: 24 additions & 0 deletions src/target/esp32s2.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,14 @@
#define ESP32_S2_RTCCNTL_BASE 0x3f408000
#define ESP32_S2_RTCWDT_CFG_OFF 0x94
#define ESP32_S2_RTCWDT_PROTECT_OFF 0xAC
#define ESP32_S2_SWD_CONF_OFF 0xB0
#define ESP32_S2_SWD_WPROTECT_OFF 0xB4
#define ESP32_S2_RTCWDT_CFG (ESP32_S2_RTCCNTL_BASE + ESP32_S2_RTCWDT_CFG_OFF)
#define ESP32_S2_RTCWDT_PROTECT (ESP32_S2_RTCCNTL_BASE + ESP32_S2_RTCWDT_PROTECT_OFF)
#define ESP32_S2_SWD_CONF_REG (ESP32_S2_RTCCNTL_BASE + ESP32_S2_SWD_CONF_OFF)
#define ESP32_S2_SWD_WPROTECT_REG (ESP32_S2_RTCCNTL_BASE + ESP32_S2_SWD_WPROTECT_OFF)
#define ESP32_S2_SWD_AUTO_FEED_EN_M (1U << 31)
#define ESP32_S2_SWD_WKEY_VALUE 0x8F1D312AU
#define ESP32_S2_OPTIONS0 (ESP32_S2_RTCCNTL_BASE + 0x0000)
#define ESP32_S2_SW_SYS_RST_M 0x80000000
#define ESP32_S2_SW_SYS_RST_V 0x1
Expand Down Expand Up @@ -537,6 +543,24 @@ static int esp32s2_disable_wdts(struct target *target)
LOG_ERROR("Failed to write ESP32_S2_RTCWDT_CFG (%d)!", res);
return res;
}
/* Enable SWD auto-feed */
res = target_write_u32(target, ESP32_S2_SWD_WPROTECT_REG, ESP32_S2_SWD_WKEY_VALUE);
if (res != ERROR_OK) {
LOG_ERROR("Failed to write ESP32_S2_SWD_WPROTECT_REG (%d)!", res);
return res;
}
uint32_t swd_conf_reg = 0;
res = target_read_u32(target, ESP32_S2_SWD_CONF_REG, &swd_conf_reg);
if (res != ERROR_OK) {
LOG_ERROR("Failed to read ESP32_S2_SWD_CONF_REG (%d)!", res);
return res;
}
swd_conf_reg |= ESP32_S2_SWD_AUTO_FEED_EN_M;
res = target_write_u32(target, ESP32_S2_SWD_CONF_REG, swd_conf_reg);
if (res != ERROR_OK) {
LOG_ERROR("Failed to write ESP32_S2_SWD_CONF_REG (%d)!", res);
return res;
}
return ERROR_OK;
}

Expand Down
55 changes: 41 additions & 14 deletions src/target/esp32s3.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,14 @@ implementation.
#define ESP32_S3_RTCCNTL_BASE 0x60008000
#define ESP32_S3_RTCWDT_CFG_OFF 0x94
#define ESP32_S3_RTCWDT_PROTECT_OFF 0xAC
#define ESP32_S3_SWD_CONF_OFF 0xB0
#define ESP32_S3_SWD_WPROTECT_OFF 0xB4
#define ESP32_S3_RTCWDT_CFG (ESP32_S3_RTCCNTL_BASE + ESP32_S3_RTCWDT_CFG_OFF)
#define ESP32_S3_RTCWDT_PROTECT (ESP32_S3_RTCCNTL_BASE + ESP32_S3_RTCWDT_PROTECT_OFF)
#define ESP32_S3_SWD_CONF_REG (ESP32_S3_RTCCNTL_BASE + ESP32_S3_SWD_CONF_OFF)
#define ESP32_S3_SWD_WPROTECT_REG (ESP32_S3_RTCCNTL_BASE + ESP32_S3_SWD_WPROTECT_OFF)
#define ESP32_S3_SWD_AUTO_FEED_EN_M (1U << 31)
#define ESP32_S3_SWD_WKEY_VALUE 0x8F1D312AU

#define ESP32_S3_TRACEMEM_BLOCK_SZ 0x4000

Expand Down Expand Up @@ -371,24 +377,27 @@ static int esp32s3_soc_reset(struct target *target)
dependency on xtensa-esp32s3-elf toolchain is not introduced.
*/
const uint8_t esp32s3_reset_stub_code[] = {
0x06, 0x1d, 0x00, 0x00, 0x06, 0x13, 0x00, 0x00, 0x38, 0x80, 0x00, 0x60,
0x06, 0x21, 0x00, 0x00, 0x06, 0x17, 0x00, 0x00, 0x38, 0x80, 0x00, 0x60,
0xbc, 0x80, 0x00, 0x60, 0xc0, 0x80, 0x00, 0x60, 0x74, 0x80, 0x00, 0x60,
0x18, 0x32, 0x58, 0x01, 0x00, 0xa0, 0x00, 0x9c, 0x00, 0x80, 0x00, 0x60,
0xa1, 0x3a, 0xd8, 0x50, 0xac, 0x80, 0x00, 0x60, 0x64, 0xf0, 0x01, 0x60,
0x64, 0x00, 0x02, 0x60, 0x94, 0x80, 0x00, 0x60, 0x48, 0xf0, 0x01, 0x60,
0x48, 0x00, 0x02, 0x60, 0x18, 0x00, 0x0c, 0x60, 0x14, 0x00, 0x0c, 0x60,
0x14, 0x00, 0x0c, 0x60, 0x38, 0x80, 0x00, 0x60, 0x00, 0x30, 0x00, 0x00,
0x50, 0x55, 0x30, 0x41, 0xec, 0xff, 0x59, 0x04, 0x41, 0xec, 0xff, 0x59,
0x04, 0x41, 0xeb, 0xff, 0x59, 0x04, 0x41, 0xeb, 0xff, 0x31, 0xeb, 0xff,
0x39, 0x04, 0x31, 0xeb, 0xff, 0x41, 0xeb, 0xff, 0x39, 0x04, 0x00, 0x00,
0x60, 0xeb, 0x03, 0x60, 0x61, 0x04, 0xfc, 0xf6, 0x50, 0x55, 0x30, 0x31,
0xe8, 0xff, 0x41, 0xe8, 0xff, 0x39, 0x04, 0x41, 0xe8, 0xff, 0x39, 0x04,
0x41, 0xe8, 0xff, 0x39, 0x04, 0x41, 0xe7, 0xff, 0x59, 0x04, 0x41, 0xe7,
0xff, 0x59, 0x04, 0x41, 0xe7, 0xff, 0x59, 0x04, 0x41, 0xe7, 0xff, 0x59,
0x04, 0x41, 0xe6, 0xff, 0x0c, 0x23, 0x39, 0x04, 0x41, 0xe6, 0xff, 0x0c,
0x43, 0x39, 0x04, 0x59, 0x04, 0x41, 0xe4, 0xff, 0x31, 0xe5, 0xff, 0x39,
0x04, 0x00, 0x70, 0x00, 0x46, 0xfe, 0xff
};
0x48, 0x00, 0x02, 0x60, 0xb4, 0x80, 0x00, 0x60, 0x2a, 0x31, 0x1d, 0x8f,
0xb0, 0x80, 0x00, 0x60, 0x00, 0x00, 0xb0, 0x84, 0x18, 0x00, 0x0c, 0x60,
0x14, 0x00, 0x0c, 0x60, 0x14, 0x00, 0x0c, 0x60, 0x38, 0x80, 0x00, 0x60,
0x00, 0x30, 0x00, 0x00, 0x50, 0x55, 0x30, 0x41, 0xe8, 0xff, 0x59, 0x04,
0x41, 0xe8, 0xff, 0x59, 0x04, 0x41, 0xe7, 0xff, 0x59, 0x04, 0x41, 0xe7,
0xff, 0x31, 0xe7, 0xff, 0x39, 0x04, 0x31, 0xe7, 0xff, 0x41, 0xe7, 0xff,
0x39, 0x04, 0x00, 0x00, 0x60, 0xeb, 0x03, 0x60, 0x61, 0x04, 0x56, 0x26,
0x05, 0x50, 0x55, 0x30, 0x31, 0xe4, 0xff, 0x41, 0xe4, 0xff, 0x39, 0x04,
0x41, 0xe4, 0xff, 0x39, 0x04, 0x41, 0xe3, 0xff, 0x39, 0x04, 0x41, 0xe3,
0xff, 0x59, 0x04, 0x41, 0xe3, 0xff, 0x59, 0x04, 0x41, 0xe3, 0xff, 0x59,
0x04, 0x41, 0xe2, 0xff, 0x31, 0xe3, 0xff, 0x39, 0x04, 0x41, 0xe2, 0xff,
0x31, 0xe3, 0xff, 0x39, 0x04, 0x41, 0xe2, 0xff, 0x59, 0x04, 0x41, 0xe2,
0xff, 0x0c, 0x23, 0x39, 0x04, 0x41, 0xe1, 0xff, 0x0c, 0x43, 0x39, 0x04,
0x52, 0x64, 0x00, 0x41, 0xe0, 0xff, 0x31, 0xe0, 0xff, 0x32, 0x64, 0x00,
0x00, 0x70, 0x00, 0x46, 0xfe, 0xff
};

LOG_DEBUG("Loading stub code into RTC RAM");
uint32_t slow_mem_save[sizeof(esp32s3_reset_stub_code) / sizeof(uint32_t)];
Expand Down Expand Up @@ -503,6 +512,24 @@ static int esp32s3_disable_wdts(struct target *target)
LOG_ERROR("Failed to write ESP32_S3_RTCWDT_CFG (%d)!", res);
return res;
}
/* Enable SWD auto-feed */
res = target_write_u32(target, ESP32_S3_SWD_WPROTECT_REG, ESP32_S3_SWD_WKEY_VALUE);
if (res != ERROR_OK) {
LOG_ERROR("Failed to write ESP32_S3_SWD_WPROTECT_REG (%d)!", res);
return res;
}
uint32_t swd_conf_reg = 0;
res = target_read_u32(target, ESP32_S3_SWD_CONF_REG, &swd_conf_reg);
if (res != ERROR_OK) {
LOG_ERROR("Failed to read ESP32_S3_SWD_CONF_REG (%d)!", res);
return res;
}
swd_conf_reg |= ESP32_S3_SWD_AUTO_FEED_EN_M;
res = target_write_u32(target, ESP32_S3_SWD_CONF_REG, swd_conf_reg);
if (res != ERROR_OK) {
LOG_ERROR("Failed to write ESP32_S3_SWD_CONF_REG (%d)!", res);
return res;
}
return ERROR_OK;
}

Expand Down
10 changes: 10 additions & 0 deletions src/target/esp32s3_cpu_reset_handler.S
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
#define RTC_CNTL_OPTIONS0_REG 0x60008000
#define RTC_CNTL_OPTIONS0_DEF 0x1C00A000
#define RTC_CNTL_SW_SYS_RST 0x80000000
#define RTC_CNTL_SWD_CONF_REG 0x600080B0
#define RTC_CNTL_SWD_CONF_VAL 0x84B00000
#define RTC_CNTL_SWD_WPROTECT_REG 0x600080B4
#define RTC_CNTL_SWD_WKEY_VALUE 0x8F1D312A
#define SYSTEM_CORE_1_CONTROL_0_REG 0x600C0014
#define SYSTEM_CONTROL_CORE_1_RESETING 0x4
#define SYSTEM_CONTROL_CORE_1_CLKGATE_EN 0x2
Expand Down Expand Up @@ -116,6 +120,12 @@ start:
s32i.n a5, a4, 0
movi a4, TIMG1_WDTCONFIG0_REG
s32i.n a5, a4, 0
movi a4, RTC_CNTL_SWD_WPROTECT_REG
movi a3, RTC_CNTL_SWD_WKEY_VALUE
s32i.n a3, a4, 0
movi a4, RTC_CNTL_SWD_CONF_REG
movi a3, RTC_CNTL_SWD_CONF_VAL
s32i.n a3, a4, 0
/* Clear APP_CPU boot address */
movi a4, SYSTEM_CORE_1_CONTROL_1_REG
s32i.n a5, a4, 0
Expand Down
3 changes: 3 additions & 0 deletions tcl/target/esp32c3.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ proc esp32c3_wdt_disable { } {
# RTC WDT
mww 0x600080a8 0x50D83AA1
mww 0x60008090 0
# SWD
mww 0x600080b0 0x8F1D312A
mww 0x600080ac 0x84B00000
}

proc esp32c3_soc_reset { } {
Expand Down

0 comments on commit 5d011fa

Please sign in to comment.