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 <string.h>
8 #include "sdkconfig.h"
9 #include "bootloader_common.h"
10 #include "soc/efuse_reg.h"
11 #include "soc/gpio_periph.h"
12 #include "soc/gpio_sig_map.h"
13 #include "soc/io_mux_reg.h"
14 
15 #include "bootloader_init.h"
16 #include "bootloader_clock.h"
17 #include "bootloader_flash_config.h"
18 #include "bootloader_mem.h"
19 #include "bootloader_console.h"
20 #include "bootloader_flash_priv.h"
21 #include "esp_private/bootloader_flash_internal.h"
22 #include "esp_rom_gpio.h"
23 #include "esp_rom_efuse.h"
24 #include "esp_rom_sys.h"
25 #include "esp_rom_spiflash.h"
26 
27 #include "esp_attr.h"
28 #include "esp_log.h"
29 #include "esp_image_format.h"
30 #include "flash_qio_mode.h"
31 #include "soc/assist_debug_reg.h"
32 #include "esp_cpu.h"
33 #include "soc/dport_reg.h"
34 #include "soc/extmem_reg.h"
35 #include "soc/rtc.h"
36 #include "soc/rtc_cntl_reg.h"
37 #include "soc/spi_periph.h"
38 #include "esp_efuse.h"
39 #include "hal/mmu_hal.h"
40 #include "hal/cache_hal.h"
41 #if !defined(CONFIG_BOOTLOADER_MCUBOOT)
42 #include "esp_flash_internal.h"
43 #endif
44 
45 static const char *TAG = "boot.esp32s2";
46 
wdt_reset_cpu0_info_enable(void)47 static void wdt_reset_cpu0_info_enable(void)
48 {
49     DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_ASSIST_DEBUG);
50     DPORT_REG_CLR_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_ASSIST_DEBUG);
51     REG_WRITE(ASSIST_DEBUG_PRO_PDEBUGENABLE, 1);
52     REG_WRITE(ASSIST_DEBUG_PRO_RCD_RECORDING, 1);
53 }
54 
wdt_reset_info_dump(int cpu)55 static void wdt_reset_info_dump(int cpu)
56 {
57 /* FIXME: failing EDT test due to error in early log */
58 #if 0
59     uint32_t inst = 0, pid = 0, stat = 0, data = 0, pc = 0,
60              lsstat = 0, lsaddr = 0, lsdata = 0, dstat = 0;
61     const char *cpu_name = cpu ? "APP" : "PRO";
62 
63     stat = 0xdeadbeef;
64     pid = 0;
65     inst = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGINST);
66     dstat = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGSTATUS);
67     data = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGDATA);
68     pc = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGPC);
69     lsstat = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGLS0STAT);
70     lsaddr = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGLS0ADDR);
71     lsdata = REG_READ(ASSIST_DEBUG_PRO_RCD_PDEBUGLS0DATA);
72 
73     if (DPORT_RECORD_PDEBUGINST_SZ(inst) == 0 &&
74             DPORT_RECORD_PDEBUGSTATUS_BBCAUSE(dstat) == DPORT_RECORD_PDEBUGSTATUS_BBCAUSE_WAITI) {
75         ESP_EARLY_LOGW(TAG, "WDT reset info: %s CPU PC=0x%"PRIx32" (waiti mode)", cpu_name, pc);
76     } else {
77         ESP_EARLY_LOGW(TAG, "WDT reset info: %s CPU PC=0x%"PRIx32, cpu_name, pc);
78     }
79     ESP_EARLY_LOGD(TAG, "WDT reset info: %s CPU STATUS        0x%08"PRIx32, cpu_name, stat);
80     ESP_EARLY_LOGD(TAG, "WDT reset info: %s CPU PID           0x%08"PRIx32, cpu_name, pid);
81     ESP_EARLY_LOGD(TAG, "WDT reset info: %s CPU PDEBUGINST    0x%08"PRIx32, cpu_name, inst);
82     ESP_EARLY_LOGD(TAG, "WDT reset info: %s CPU PDEBUGSTATUS  0x%08"PRIx32, cpu_name, dstat);
83     ESP_EARLY_LOGD(TAG, "WDT reset info: %s CPU PDEBUGDATA    0x%08"PRIx32, cpu_name, data);
84     ESP_EARLY_LOGD(TAG, "WDT reset info: %s CPU PDEBUGPC      0x%08"PRIx32, cpu_name, pc);
85     ESP_EARLY_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0STAT 0x%08"PRIx32, cpu_name, lsstat);
86     ESP_EARLY_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0ADDR 0x%08"PRIx32, cpu_name, lsaddr);
87     ESP_EARLY_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0DATA 0x%08"PRIx32, cpu_name, lsdata);
88 #endif
89 }
90 
bootloader_check_wdt_reset(void)91 static void bootloader_check_wdt_reset(void)
92 {
93     int wdt_rst = 0;
94     soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
95     if (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 || rst_reason == RESET_REASON_CORE_MWDT1 ||
96         rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_MWDT1 || rst_reason == RESET_REASON_CPU0_RTC_WDT) {
97         // PRO CPU has been reset by WDT
98         wdt_rst = 1;
99     }
100     if (wdt_rst) {
101         // if reset by WDT dump info from trace port
102         wdt_reset_info_dump(0);
103     }
104     wdt_reset_cpu0_info_enable();
105 }
106 
bootloader_super_wdt_auto_feed(void)107 static void bootloader_super_wdt_auto_feed(void)
108 {
109     REG_SET_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_AUTO_FEED_EN);
110 }
111 
bootloader_init(void)112 esp_err_t bootloader_init(void)
113 {
114     esp_err_t ret = ESP_OK;
115     bootloader_super_wdt_auto_feed();
116     // protect memory region
117 
118 // In RAM_APP, memory will be initialized in `call_start_cpu0`
119 #if !CONFIG_APP_BUILD_TYPE_RAM
120     bootloader_init_mem();
121 
122     /* check that static RAM is after the stack */
123 #ifndef NDEBUG
124     {
125         assert(&_bss_start <= &_bss_end);
126         assert(&_data_start <= &_data_end);
127     }
128 #endif
129 #ifndef __ZEPHYR__
130     // clear bss section
131     bootloader_clear_bss_section();
132 #endif /* __ZEPHYR__ */
133 #endif // !CONFIG_APP_BUILD_TYPE_RAM
134 
135     // init eFuse virtual mode (read eFuses to RAM)
136 #ifdef CONFIG_EFUSE_VIRTUAL
137     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!");
138 #ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
139     esp_efuse_init_virtual_mode_in_ram();
140 #endif
141 #endif
142 
143     // config clock
144     bootloader_clock_configure();
145     // initialize console, from now on, we can use esp_log
146     bootloader_console_init();
147     /* print 2nd bootloader banner */
148     bootloader_print_banner();
149 
150 #ifndef CONFIG_BOOTLOADER_MCUBOOT
151     spi_flash_init_chip_state();
152     if ((ret = esp_flash_init_default_chip()) != ESP_OK) {
153         return ret;
154     }
155 #endif
156 
157 #if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
158     // init cache hal
159     cache_hal_init();
160     //init mmu
161     mmu_hal_init();
162     // Workaround: normal ROM bootloader exits with DROM0 cache unmasked, but 2nd bootloader exits with it masked.
163     REG_CLR_BIT(EXTMEM_PRO_ICACHE_CTRL1_REG, EXTMEM_PRO_ICACHE_MASK_DROM0);
164     // update flash ID
165     bootloader_flash_update_id();
166     // Check and run XMC startup flow
167     if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) {
168         ESP_EARLY_LOGE(TAG, "failed when running XMC startup flow, reboot!");
169         return ret;
170     }
171 #if !CONFIG_APP_BUILD_TYPE_RAM
172     // read bootloader header
173     if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
174         return ret;
175     }
176     // read chip revision and check if it's compatible to bootloader
177     if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) {
178         return ret;
179     }
180 #endif // !CONFIG_APP_BUILD_TYPE_RAM
181     // initialize spi flash
182     if ((ret = bootloader_init_spi_flash()) != ESP_OK) {
183         return ret;
184     }
185 #endif // #if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
186 
187     // check whether a WDT reset happend
188     bootloader_check_wdt_reset();
189     // config WDT
190     bootloader_config_wdt();
191     // enable RNG early entropy source
192     bootloader_enable_random();
193 
194     return ret;
195 }
196