1 /*
2 * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <stdbool.h>
7 #include <inttypes.h>
8 #include "soc_init.h"
9 #include <soc/soc.h>
10 #include <soc/rtc_cntl_reg.h>
11 #include "soc/system_reg.h"
12 #include "soc/assist_debug_reg.h"
13 #include "soc/reset_reasons.h"
14 #include "esp_log.h"
15
16 const static char *TAG = "soc_init";
17
ana_super_wdt_reset_config(bool enable)18 void ana_super_wdt_reset_config(bool enable)
19 {
20 REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SUPER_WDT_RST);
21
22 if (enable) {
23 REG_CLR_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_BYPASS_RST);
24 } else {
25 REG_SET_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_BYPASS_RST);
26 }
27 }
28
ana_bod_reset_config(bool enable)29 void ana_bod_reset_config(bool enable)
30 {
31 REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_BOD_RST);
32
33 if (enable) {
34 REG_SET_BIT(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_ANA_RST_EN);
35 } else {
36 REG_CLR_BIT(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_ANA_RST_EN);
37 }
38 }
39
ana_clock_glitch_reset_config(bool enable)40 void ana_clock_glitch_reset_config(bool enable)
41 {
42 REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_GLITCH_RST);
43
44 if (enable) {
45 REG_SET_BIT(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_GLITCH_RST_EN);
46 } else {
47 REG_CLR_BIT(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_GLITCH_RST_EN);
48 }
49 }
50
ana_reset_config(void)51 void ana_reset_config(void)
52 {
53 ana_super_wdt_reset_config(true);
54 ana_bod_reset_config(true);
55 ana_clock_glitch_reset_config(true);
56 }
57
super_wdt_auto_feed(void)58 void super_wdt_auto_feed(void)
59 {
60 REG_WRITE(RTC_CNTL_SWD_WPROTECT_REG, RTC_CNTL_SWD_WKEY_VALUE);
61 REG_SET_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_AUTO_FEED_EN);
62 REG_WRITE(RTC_CNTL_SWD_WPROTECT_REG, 0);
63 }
64
wdt_reset_info_dump(int cpu)65 void wdt_reset_info_dump(int cpu)
66 {
67 uint32_t inst = 0, pid = 0, stat = 0, data = 0, pc = 0, lsstat = 0, lsaddr = 0, lsdata = 0,
68 dstat = 0;
69 const char *cpu_name = cpu ? "APP" : "PRO";
70
71 stat = 0xdeadbeef;
72 pid = 0;
73
74 if (cpu == 0) {
75 inst = REG_READ(ASSIST_DEBUG_CORE_0_RCD_PDEBUGINST_REG);
76 dstat = REG_READ(ASSIST_DEBUG_CORE_0_RCD_PDEBUGSTATUS_REG);
77 data = REG_READ(ASSIST_DEBUG_CORE_0_RCD_PDEBUGDATA_REG);
78 pc = REG_READ(ASSIST_DEBUG_CORE_0_RCD_PDEBUGPC_REG);
79 lsstat = REG_READ(ASSIST_DEBUG_CORE_0_RCD_PDEBUGLS0STAT_REG);
80 lsaddr = REG_READ(ASSIST_DEBUG_CORE_0_RCD_PDEBUGLS0ADDR_REG);
81 lsdata = REG_READ(ASSIST_DEBUG_CORE_0_RCD_PDEBUGLS0DATA_REG);
82 } else {
83 ESP_EARLY_LOGE(TAG, "WDT reset info: %s CPU not support!\n", cpu_name);
84 return;
85 }
86
87 ESP_EARLY_LOGD(TAG, "WDT reset info: %s CPU STATUS 0x%08" PRIx32, cpu_name, stat);
88 ESP_EARLY_LOGD(TAG, "WDT reset info: %s CPU PID 0x%08" PRIx32, cpu_name, pid);
89 ESP_EARLY_LOGD(TAG, "WDT reset info: %s CPU PDEBUGINST 0x%08" PRIx32, cpu_name, inst);
90 ESP_EARLY_LOGD(TAG, "WDT reset info: %s CPU PDEBUGSTATUS 0x%08" PRIx32, cpu_name, dstat);
91 ESP_EARLY_LOGD(TAG, "WDT reset info: %s CPU PDEBUGDATA 0x%08" PRIx32, cpu_name, data);
92 ESP_EARLY_LOGD(TAG, "WDT reset info: %s CPU PDEBUGPC 0x%08" PRIx32, cpu_name, pc);
93 ESP_EARLY_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0STAT 0x%08" PRIx32, cpu_name, lsstat);
94 ESP_EARLY_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0ADDR 0x%08" PRIx32, cpu_name, lsaddr);
95 ESP_EARLY_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0DATA 0x%08" PRIx32, cpu_name, lsdata);
96 }
97
wdt_reset_cpu0_info_enable(void)98 void wdt_reset_cpu0_info_enable(void)
99 {
100 REG_SET_BIT(SYSTEM_CPU_PERI_CLK_EN_REG, SYSTEM_CLK_EN_ASSIST_DEBUG);
101 REG_CLR_BIT(SYSTEM_CPU_PERI_RST_EN_REG, SYSTEM_RST_EN_ASSIST_DEBUG);
102 REG_WRITE(ASSIST_DEBUG_CORE_0_RCD_PDEBUGENABLE_REG, 1);
103 REG_WRITE(ASSIST_DEBUG_CORE_0_RCD_RECORDING_REG, 1);
104 }
105
check_wdt_reset(void)106 void check_wdt_reset(void)
107 {
108 int wdt_rst = 0;
109 soc_reset_reason_t rst_reas;
110
111 rst_reas = esp_rom_get_reset_reason(0);
112 if (rst_reas == RESET_REASON_CORE_RTC_WDT || rst_reas == RESET_REASON_CORE_MWDT0 ||
113 rst_reas == RESET_REASON_CORE_MWDT1 || rst_reas == RESET_REASON_CPU0_MWDT0 ||
114 rst_reas == RESET_REASON_CPU0_RTC_WDT) {
115 ESP_EARLY_LOGW(TAG, "PRO CPU has been reset by WDT.");
116 wdt_rst = 1;
117 }
118
119 if (wdt_rst) {
120 wdt_reset_info_dump(0);
121 }
122
123 wdt_reset_cpu0_info_enable();
124 }
125