1 /*
2 * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <stdint.h>
7 #include "sdkconfig.h"
8 #include "esp_attr.h"
9 #include "esp_log.h"
10 #include "esp_image_format.h"
11 #include "flash_qio_mode.h"
12 #include "esp_rom_gpio.h"
13 #include "esp_rom_efuse.h"
14 #include "esp_rom_uart.h"
15 #include "esp_rom_sys.h"
16 #include "esp_rom_spiflash.h"
17 #include "soc/efuse_reg.h"
18 #include "soc/gpio_sig_map.h"
19 #include "soc/io_mux_reg.h"
20 #include "soc/assist_debug_reg.h"
21 #include "esp_cpu.h"
22 #include "soc/rtc.h"
23 #include "soc/spi_periph.h"
24 #include "soc/extmem_reg.h"
25 #include "soc/io_mux_reg.h"
26 #include "soc/system_reg.h"
27 #include "esp32c2/rom/efuse.h"
28 #include "esp32c2/rom/ets_sys.h"
29 #include "esp32c2/rom/rtc.h"
30 #include "bootloader_common.h"
31 #include "bootloader_init.h"
32 #include "bootloader_clock.h"
33 #include "bootloader_flash_config.h"
34 #include "bootloader_mem.h"
35 #include "bootloader_console.h"
36 #include "bootloader_flash_priv.h"
37 #include "bootloader_soc.h"
38 #include "esp_private/bootloader_flash_internal.h"
39 #include "esp_efuse.h"
40 #include "hal/mmu_hal.h"
41 #include "hal/cache_hal.h"
42 #if !defined(CONFIG_BOOTLOADER_MCUBOOT)
43 #include "esp_flash_internal.h"
44 #endif
45
46 static const char *TAG = "boot.esp32c2";
47
wdt_reset_cpu0_info_enable(void)48 static void wdt_reset_cpu0_info_enable(void)
49 {
50 REG_SET_BIT(SYSTEM_CPU_PERI_CLK_EN_REG, SYSTEM_CLK_EN_ASSIST_DEBUG);
51 REG_CLR_BIT(SYSTEM_CPU_PERI_RST_EN_REG, SYSTEM_RST_EN_ASSIST_DEBUG);
52 REG_WRITE(ASSIST_DEBUG_CORE_0_RCD_EN_REG, ASSIST_DEBUG_CORE_0_RCD_PDEBUGEN | ASSIST_DEBUG_CORE_0_RCD_RECORDEN);
53 }
54
wdt_reset_info_dump(int cpu)55 static void wdt_reset_info_dump(int cpu)
56 {
57 (void) cpu;
58 // saved PC was already printed by the ROM bootloader.
59 // nothing to do here.
60 }
61
bootloader_check_wdt_reset(void)62 static void bootloader_check_wdt_reset(void)
63 {
64 int wdt_rst = 0;
65 soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
66 if (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 ||
67 rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_RTC_WDT) {
68 ESP_EARLY_LOGW(TAG, "PRO CPU has been reset by WDT.");
69 wdt_rst = 1;
70 }
71 if (wdt_rst) {
72 // if reset by WDT dump info from trace port
73 wdt_reset_info_dump(0);
74 }
75 wdt_reset_cpu0_info_enable();
76 }
77
bootloader_super_wdt_auto_feed(void)78 static void bootloader_super_wdt_auto_feed(void)
79 {
80 REG_WRITE(RTC_CNTL_SWD_WPROTECT_REG, RTC_CNTL_SWD_WKEY_VALUE);
81 REG_SET_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_AUTO_FEED_EN);
82 REG_WRITE(RTC_CNTL_SWD_WPROTECT_REG, 0);
83 }
84
bootloader_ana_reset_config(void)85 static inline void bootloader_ana_reset_config(void)
86 {
87 //Enable super WDT reset.
88 bootloader_ana_super_wdt_reset_config(true);
89 //Enable BOD reset
90 bootloader_ana_bod_reset_config(true);
91 }
92
bootloader_init(void)93 esp_err_t bootloader_init(void)
94 {
95 esp_err_t ret = ESP_OK;
96
97 bootloader_ana_reset_config();
98 bootloader_super_wdt_auto_feed();
99
100 // In RAM_APP, memory will be initialized in `call_start_cpu0`
101 #if !CONFIG_APP_BUILD_TYPE_RAM
102 // protect memory region
103 bootloader_init_mem();
104 /* check that static RAM is after the stack */
105 assert(&_bss_start <= &_bss_end);
106 assert(&_data_start <= &_data_end);
107 #ifndef __ZEPHYR__
108 // clear bss section
109 bootloader_clear_bss_section();
110 #endif
111 #endif // !CONFIG_APP_BUILD_TYPE_RAM
112
113 // init eFuse virtual mode (read eFuses to RAM)
114 #ifdef CONFIG_EFUSE_VIRTUAL
115 ESP_EARLY_LOGW(TAG, "eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!");
116 #ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
117 esp_efuse_init_virtual_mode_in_ram();
118 #endif
119 #endif
120 // config clock
121 bootloader_clock_configure();
122 // initialize console, from now on, we can use esp_log
123 bootloader_console_init();
124 /* print 2nd bootloader banner */
125 bootloader_print_banner();
126
127 #ifndef CONFIG_BOOTLOADER_MCUBOOT
128 spi_flash_init_chip_state();
129 if ((ret = esp_flash_init_default_chip()) != ESP_OK) {
130 return ret;
131 }
132 #endif
133
134 #if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
135 //init cache hal
136 cache_hal_init();
137 //init mmu
138 mmu_hal_init();
139 // update flash ID
140 bootloader_flash_update_id();
141 // Check and run XMC startup flow
142 if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) {
143 ESP_EARLY_LOGE(TAG, "failed when running XMC startup flow, reboot!");
144 return ret;
145 }
146 #if !CONFIG_APP_BUILD_TYPE_RAM
147 // read bootloader header
148 if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
149 ESP_EARLY_LOGE(TAG, "failed to read flash!");
150 return ret;
151 }
152 // read chip revision and check if it's compatible to bootloader
153 if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) {
154 ESP_EARLY_LOGE(TAG, "failed to vallidate!");
155 return ret;
156 }
157 #endif // !CONFIG_APP_BUILD_TYPE_RAM
158 // initialize spi flash
159 if ((ret = bootloader_init_spi_flash()) != ESP_OK) {
160 ESP_EARLY_LOGE(TAG, "failed to init spi flash!");
161 return ret;
162 }
163 #endif //#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
164
165 // check whether a WDT reset happend
166 bootloader_check_wdt_reset();
167 // config WDT
168 bootloader_config_wdt();
169 // enable RNG early entropy source
170 bootloader_enable_random();
171 return ret;
172 }
173