1 /*
2 * Copyright (c) 2017 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /* Include esp-idf headers first to avoid redefining BIT() macro */
8 #include <soc.h>
9 #include <soc/rtc_cntl_reg.h>
10 #include <soc/timer_group_reg.h>
11 #include <soc/ext_mem_defs.h>
12 #include <zephyr/drivers/interrupt_controller/intc_esp32.h>
13 #include <xtensa/config/core-isa.h>
14 #include <xtensa/corebits.h>
15 #include <esp_private/spi_flash_os.h>
16 #include <esp_private/esp_mmu_map_private.h>
17 #include <esp_private/mspi_timing_tuning.h>
18 #include <esp_flash_internal.h>
19 #include <esp_private/cache_utils.h>
20 #include <sdkconfig.h>
21
22 #if CONFIG_ESP_SPIRAM
23 #include "psram.h"
24 #endif
25
26 #include <zephyr/kernel_structs.h>
27 #include <zephyr/toolchain.h>
28 #include <zephyr/types.h>
29 #include <zephyr/linker/linker-defs.h>
30 #include <kernel_internal.h>
31 #include <zephyr/sys/util.h>
32
33 #include <esp_private/system_internal.h>
34 #include <esp32s3/rom/cache.h>
35 #include <esp32s3/rom/rtc.h>
36 #include <soc/syscon_reg.h>
37 #include <hal/soc_hal.h>
38 #include <hal/wdt_hal.h>
39 #include <hal/cpu_hal.h>
40 #include <esp_cpu.h>
41 #include <soc/gpio_periph.h>
42 #include <esp_err.h>
43 #include <esp_timer.h>
44 #include <esp_clk_internal.h>
45 #include <esp_app_format.h>
46
47 #include <zephyr/sys/printk.h>
48 #include "esp_log.h"
49
50 #include <zephyr/drivers/flash.h>
51 #include <zephyr/storage/flash_map.h>
52
53 #define TAG "boot.esp32s3"
54
55 extern void z_prep_c(void);
56 extern void esp_reset_reason_init(void);
57 extern int esp_appcpu_init(void);
58
59 #ifndef CONFIG_MCUBOOT
60 /*
61 * This function is a container for SoC patches
62 * that needs to be applied during the startup.
63 */
esp_errata(void)64 static void IRAM_ATTR esp_errata(void)
65 {
66 /* Handle the clock gating fix */
67 REG_CLR_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_CLKGATE_EN);
68 /* The clock gating signal of the App core is invalid. We use RUNSTALL and RESETTING
69 * signals to ensure that the App core stops running in single-core mode.
70 */
71 REG_SET_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_RUNSTALL);
72 REG_CLR_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_RESETTING);
73
74 /* Handle the Dcache case following the IDF startup code */
75 #if CONFIG_ESP32S3_DATA_CACHE_16KB
76 Cache_Invalidate_DCache_All();
77 Cache_Occupy_Addr(SOC_DROM_LOW, 0x4000);
78 #endif
79 }
80 #endif /* CONFIG_MCUBOOT */
81
82 /*
83 * This is written in C rather than assembly since, during the port bring up,
84 * Zephyr is being booted by the Espressif bootloader. With it, the C stack
85 * is already set up.
86 */
__esp_platform_start(void)87 void IRAM_ATTR __esp_platform_start(void)
88 {
89 extern uint32_t _init_start;
90
91 /* Move the exception vector table to IRAM. */
92 __asm__ __volatile__("wsr %0, vecbase" : : "r"(&_init_start));
93
94 z_bss_zero();
95
96 /* Disable normal interrupts. */
97 __asm__ __volatile__("wsr %0, PS" : : "r"(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE));
98
99 /* Initialize the architecture CPU pointer. Some of the
100 * initialization code wants a valid arch_current_thread() before
101 * arch_kernel_init() is invoked.
102 */
103 __asm__ __volatile__("wsr.MISC0 %0; rsync" : : "r"(&_kernel.cpus[0]));
104
105 #ifndef CONFIG_MCUBOOT
106 /* Configure the mode of instruction cache : cache size, cache line size. */
107 esp_config_instruction_cache_mode();
108
109 /* If we need use SPIRAM, we should use data cache.
110 * Configure the mode of data : cache size, cache line size.
111 */
112 esp_config_data_cache_mode();
113
114 /* Apply SoC patches */
115 esp_errata();
116
117 /* ESP-IDF/MCUboot 2nd stage bootloader enables RTC WDT to check on startup sequence
118 * related issues in application. Hence disable that as we are about to start
119 * Zephyr environment.
120 */
121 wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL};
122
123 wdt_hal_write_protect_disable(&rtc_wdt_ctx);
124 wdt_hal_disable(&rtc_wdt_ctx);
125 wdt_hal_write_protect_enable(&rtc_wdt_ctx);
126
127 esp_reset_reason_init();
128
129 esp_timer_early_init();
130
131 esp_mspi_pin_init();
132
133 esp_flash_app_init();
134
135 mspi_timing_flash_tuning();
136
137 esp_mmu_map_init();
138
139 #if CONFIG_ESP_SPIRAM
140 esp_init_psram();
141 #endif /* CONFIG_ESP_SPIRAM */
142
143 #endif /* !CONFIG_MCUBOOT */
144
145 esp_intr_initialize();
146
147 #if CONFIG_ESP_SPIRAM
148 /* Init Shared Multi Heap for PSRAM */
149 int err = esp_psram_smh_init();
150
151 if (err) {
152 printk("Failed to initialize PSRAM shared multi heap (%d)\n", err);
153 }
154 #endif
155
156 /* Start Zephyr */
157 z_prep_c();
158
159 CODE_UNREACHABLE;
160 }
161
162 /* Boot-time static default printk handler, possibly to be overridden later. */
arch_printk_char_out(int c)163 int IRAM_ATTR arch_printk_char_out(int c)
164 {
165 if (c == '\n') {
166 esp_rom_uart_tx_one_char('\r');
167 }
168 esp_rom_uart_tx_one_char(c);
169 return 0;
170 }
171
sys_arch_reboot(int type)172 void sys_arch_reboot(int type)
173 {
174 esp_restart_noos();
175 }
176
177 #if defined(CONFIG_SOC_ENABLE_APPCPU) && !defined(CONFIG_MCUBOOT)
178 extern int esp_appcpu_init(void);
179 SYS_INIT(esp_appcpu_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
180 #endif
181