1 /*
2 * SPDX-FileCopyrightText: 2019-2023 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
13 #include "bootloader_init.h"
14 #include "bootloader_clock.h"
15 #include "bootloader_common.h"
16 #include "bootloader_flash_config.h"
17 #include "bootloader_mem.h"
18 #include "bootloader_console.h"
19 #include "bootloader_flash_priv.h"
20 #include "esp_private/bootloader_flash_internal.h"
21 #include "esp_cpu.h"
22 #include "soc/dport_reg.h"
23 #include "soc/efuse_reg.h"
24 #include "soc/gpio_periph.h"
25 #include "soc/gpio_sig_map.h"
26 #include "soc/io_mux_reg.h"
27 #include "soc/rtc.h"
28 #include "soc/spi_periph.h"
29 #include "hal/gpio_hal.h"
30 #include "xtensa/config/core.h"
31 #include "xt_instr_macros.h"
32
33 #include "esp32/rom/cache.h"
34 #include "esp_rom_gpio.h"
35 #include "esp_rom_efuse.h"
36 #include "esp_rom_sys.h"
37 #include "esp_rom_spiflash.h"
38 #include "esp_efuse.h"
39 #include "esp_flash_internal.h"
40
41 static const char *TAG = "boot.esp32";
42
43 #if !CONFIG_APP_BUILD_TYPE_RAM
bootloader_reset_mmu(void)44 static void bootloader_reset_mmu(void)
45 {
46 /* completely reset MMU in case serial bootloader was running */
47 Cache_Read_Disable(0);
48 #if !CONFIG_FREERTOS_UNICORE
49 Cache_Read_Disable(1);
50 #endif
51 Cache_Flush(0);
52 #if !CONFIG_FREERTOS_UNICORE
53 Cache_Flush(1);
54 #endif
55 mmu_init(0);
56 #if !CONFIG_FREERTOS_UNICORE
57 /* The lines which manipulate DPORT_APP_CACHE_MMU_IA_CLR bit are
58 necessary to work around a hardware bug. */
59 DPORT_REG_SET_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
60 mmu_init(1);
61 DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
62 #endif
63
64 /* normal ROM boot exits with DROM0 cache unmasked,
65 but serial bootloader exits with it masked. */
66 DPORT_REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MASK_DROM0);
67 #if !CONFIG_FREERTOS_UNICORE
68 DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MASK_DROM0);
69 #endif
70 }
71 #endif //#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
72
bootloader_check_rated_cpu_clock(void)73 static esp_err_t bootloader_check_rated_cpu_clock(void)
74 {
75 int rated_freq = bootloader_clock_get_rated_freq_mhz();
76 if (rated_freq < CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ) {
77 ESP_LOGE(TAG, "Chip CPU frequency rated for %dMHz, configured for %dMHz. Modify CPU frequency in menuconfig",
78 rated_freq, CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ);
79 return ESP_FAIL;
80 }
81 return ESP_OK;
82 }
83
wdt_reset_cpu0_info_enable(void)84 static void wdt_reset_cpu0_info_enable(void)
85 {
86 //We do not reset core1 info here because it didn't work before cpu1 was up. So we put it into call_start_cpu1.
87 DPORT_REG_SET_BIT(DPORT_PRO_CPU_RECORD_CTRL_REG, DPORT_PRO_CPU_PDEBUG_ENABLE | DPORT_PRO_CPU_RECORD_ENABLE);
88 DPORT_REG_CLR_BIT(DPORT_PRO_CPU_RECORD_CTRL_REG, DPORT_PRO_CPU_RECORD_ENABLE);
89 }
90
wdt_reset_info_dump(int cpu)91 static void wdt_reset_info_dump(int cpu)
92 {
93 uint32_t inst = 0, pid = 0, stat = 0, data = 0, pc = 0,
94 lsstat = 0, lsaddr = 0, lsdata = 0, dstat = 0;
95 const char *cpu_name = cpu ? "APP" : "PRO";
96
97 if (cpu == 0) {
98 stat = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_STATUS_REG);
99 pid = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PID_REG);
100 inst = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGINST_REG);
101 dstat = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGSTATUS_REG);
102 data = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGDATA_REG);
103 pc = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGPC_REG);
104 lsstat = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGLS0STAT_REG);
105 lsaddr = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGLS0ADDR_REG);
106 lsdata = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGLS0DATA_REG);
107 } else {
108 #if !CONFIG_FREERTOS_UNICORE
109 stat = DPORT_REG_READ(DPORT_APP_CPU_RECORD_STATUS_REG);
110 pid = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PID_REG);
111 inst = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGINST_REG);
112 dstat = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGSTATUS_REG);
113 data = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGDATA_REG);
114 pc = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGPC_REG);
115 lsstat = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0STAT_REG);
116 lsaddr = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0ADDR_REG);
117 lsdata = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0DATA_REG);
118 #endif
119 }
120
121 if (DPORT_RECORD_PDEBUGINST_SZ(inst) == 0 &&
122 DPORT_RECORD_PDEBUGSTATUS_BBCAUSE(dstat) == DPORT_RECORD_PDEBUGSTATUS_BBCAUSE_WAITI) {
123 ESP_LOGW(TAG, "WDT reset info: %s CPU PC=0x%"PRIx32" (waiti mode)", cpu_name, pc);
124 } else {
125 ESP_LOGW(TAG, "WDT reset info: %s CPU PC=0x%"PRIx32, cpu_name, pc);
126 }
127 ESP_LOGD(TAG, "WDT reset info: %s CPU STATUS 0x%08"PRIx32, cpu_name, stat);
128 ESP_LOGD(TAG, "WDT reset info: %s CPU PID 0x%08"PRIx32, cpu_name, pid);
129 ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGINST 0x%08"PRIx32, cpu_name, inst);
130 ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGSTATUS 0x%08"PRIx32, cpu_name, dstat);
131 ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGDATA 0x%08"PRIx32, cpu_name, data);
132 ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGPC 0x%08"PRIx32, cpu_name, pc);
133 ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0STAT 0x%08"PRIx32, cpu_name, lsstat);
134 ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0ADDR 0x%08"PRIx32, cpu_name, lsaddr);
135 ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0DATA 0x%08"PRIx32, cpu_name, lsdata);
136 }
137
bootloader_check_wdt_reset(void)138 static void bootloader_check_wdt_reset(void)
139 {
140 int wdt_rst = 0;
141 soc_reset_reason_t rst_reas[2];
142
143 rst_reas[0] = esp_rom_get_reset_reason(0);
144 rst_reas[1] = esp_rom_get_reset_reason(1);
145 if (rst_reas[0] == RESET_REASON_CORE_RTC_WDT || rst_reas[0] == RESET_REASON_CORE_MWDT0 || rst_reas[0] == RESET_REASON_CORE_MWDT1 ||
146 rst_reas[0] == RESET_REASON_CPU0_MWDT0 || rst_reas[0] == RESET_REASON_CPU0_RTC_WDT) {
147 ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
148 wdt_rst = 1;
149 }
150 if (rst_reas[1] == RESET_REASON_CORE_RTC_WDT || rst_reas[1] == RESET_REASON_CORE_MWDT0 || rst_reas[1] == RESET_REASON_CORE_MWDT1 ||
151 rst_reas[1] == RESET_REASON_CPU1_MWDT1 || rst_reas[1] == RESET_REASON_CPU1_RTC_WDT) {
152 ESP_LOGW(TAG, "APP CPU has been reset by WDT.");
153 wdt_rst = 1;
154 }
155 if (wdt_rst) {
156 // if reset by WDT dump info from trace port
157 wdt_reset_info_dump(0);
158 #if !CONFIG_FREERTOS_UNICORE
159 wdt_reset_info_dump(1);
160 #endif
161 }
162 wdt_reset_cpu0_info_enable();
163 }
164
bootloader_init(void)165 esp_err_t bootloader_init(void)
166 {
167 esp_err_t ret = ESP_OK;
168
169 #if XCHAL_ERRATUM_572
170 uint32_t memctl = XCHAL_CACHE_MEMCTL_DEFAULT;
171 WSR(MEMCTL, memctl);
172 #endif // XCHAL_ERRATUM_572
173
174 // In RAM_APP, memory will be initialized in `call_start_cpu0`
175 #if !CONFIG_APP_BUILD_TYPE_RAM
176 bootloader_init_mem();
177
178 // check that static RAM is after the stack
179 #ifndef NDEBUG
180 {
181 assert(&_bss_start <= &_bss_end);
182 assert(&_data_start <= &_data_end);
183 // int *sp = esp_cpu_get_sp();
184 // assert((unsigned*)sp < (unsigned*)&_bss_start);
185 // assert((unsigned*)sp < (unsigned*)&_data_start);
186 }
187 #endif
188 #ifndef __ZEPHYR__
189 // clear bss section
190 bootloader_clear_bss_section();
191 #endif
192 #endif // !CONFIG_APP_BUILD_TYPE_RAM
193
194 // init eFuse virtual mode (read eFuses to RAM)
195 #ifdef CONFIG_EFUSE_VIRTUAL
196 ESP_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!");
197 #ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
198 esp_efuse_init_virtual_mode_in_ram();
199 #endif
200 #endif /* CONFIG_EFUSE_VIRTUAL */
201 // bootst up vddsdio
202 bootloader_common_vddsdio_configure();
203 // check rated CPU clock
204 if ((ret = bootloader_check_rated_cpu_clock()) != ESP_OK) {
205 return ret;
206 }
207 // config clock
208 bootloader_clock_configure();
209 // initialize uart console, from now on, we can use esp_log
210 bootloader_console_init();
211 // print 2nd bootloader banner
212 bootloader_print_banner();
213
214 #ifndef CONFIG_BOOTLOADER_MCUBOOT
215 spi_flash_init_chip_state();
216 if ((ret = esp_flash_init_default_chip()) != ESP_OK) {
217 return ret;
218 }
219 #endif
220
221 #if !CONFIG_APP_BUILD_TYPE_RAM
222 // reset MMU
223 bootloader_reset_mmu();
224 // update flash ID
225 bootloader_flash_update_id();
226 // Check and run XMC startup flow
227 if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) {
228 ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!");
229 return ret;
230 }
231 // read bootloader header
232 if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
233 return ret;
234 }
235 // read chip revision and check if it's compatible to bootloader
236 if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) {
237 return ret;
238 }
239 // initialize spi flash
240 if ((ret = bootloader_init_spi_flash()) != ESP_OK) {
241 return ret;
242 }
243 #endif // #if !CONFIG_APP_BUILD_TYPE_RAM
244
245 // check whether a WDT reset happend
246 bootloader_check_wdt_reset();
247 // config WDT
248 bootloader_config_wdt();
249 // enable RNG early entropy source
250 bootloader_enable_random();
251
252 return ret;
253 }
254