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