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