1 /*
2 * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /* Include esp-idf headers first to avoid redefining BIT() macro */
8 #include <soc/rtc_cntl_reg.h>
9 #include <soc/timer_group_reg.h>
10 #include <soc/gpio_reg.h>
11 #include <soc/syscon_reg.h>
12 #include <soc/system_reg.h>
13 #include <soc/cache_memory.h>
14 #include "hal/soc_ll.h"
15 #include "hal/wdt_hal.h"
16 #include "esp_cpu.h"
17 #include "esp_timer.h"
18 #include "esp_spi_flash.h"
19 #include "esp_clk_internal.h"
20 #include <soc/interrupt_reg.h>
21 #include <zephyr/drivers/interrupt_controller/intc_esp32c3.h>
22
23 #include <zephyr/kernel_structs.h>
24 #include <kernel_internal.h>
25 #include <string.h>
26 #include <zephyr/toolchain.h>
27 #include <soc.h>
28
29 #ifdef CONFIG_MCUBOOT
30 #include "bootloader_init.h"
31 #endif /* CONFIG_MCUBOOT */
32
33 /*
34 * This is written in C rather than assembly since, during the port bring up,
35 * Zephyr is being booted by the Espressif bootloader. With it, the C stack
36 * is already set up.
37 */
__esp_platform_start(void)38 void __attribute__((section(".iram1"))) __esp_platform_start(void)
39 {
40 #ifdef CONFIG_RISCV_GP
41 /* Configure the global pointer register
42 * (This should be the first thing startup does, as any other piece of code could be
43 * relaxed by the linker to access something relative to __global_pointer$)
44 */
45 __asm__ __volatile__(".option push\n"
46 ".option norelax\n"
47 "la gp, __global_pointer$\n"
48 ".option pop");
49 #endif /* CONFIG_RISCV_GP */
50
51 __asm__ __volatile__("la t0, _esp32c3_vector_table\n"
52 "csrw mtvec, t0\n");
53
54 z_bss_zero();
55
56 /* Disable normal interrupts. */
57 csr_read_clear(mstatus, MSTATUS_MIE);
58
59 #ifdef CONFIG_MCUBOOT
60 /* MCUboot early initialisation.
61 */
62 bootloader_init();
63
64 #else
65 /* ESP-IDF 2nd stage bootloader enables RTC WDT to check on startup sequence
66 * related issues in application. Hence disable that as we are about to start
67 * Zephyr environment.
68 */
69 wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL};
70
71 wdt_hal_write_protect_disable(&rtc_wdt_ctx);
72 wdt_hal_disable(&rtc_wdt_ctx);
73 wdt_hal_write_protect_enable(&rtc_wdt_ctx);
74
75 /* Configure the Cache MMU size for instruction and rodata in flash. */
76 extern uint32_t esp_rom_cache_set_idrom_mmu_size(uint32_t irom_size,
77 uint32_t drom_size);
78
79 extern int _rodata_reserved_start;
80 uint32_t rodata_reserved_start_align =
81 (uint32_t)&_rodata_reserved_start & ~(MMU_PAGE_SIZE - 1);
82 uint32_t cache_mmu_irom_size =
83 ((rodata_reserved_start_align - SOC_DROM_LOW) / MMU_PAGE_SIZE) *
84 sizeof(uint32_t);
85
86 esp_rom_cache_set_idrom_mmu_size(cache_mmu_irom_size,
87 CACHE_DROM_MMU_MAX_END - cache_mmu_irom_size);
88
89 /* Enable wireless phy subsystem clock,
90 * This needs to be done before the kernel starts
91 */
92 REG_CLR_BIT(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_SDIOSLAVE_EN);
93 SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN);
94
95 /* Configures the CPU clock, RTC slow and fast clocks, and performs
96 * RTC slow clock calibration.
97 */
98 esp_clk_init();
99
100 esp_timer_early_init();
101
102 #if CONFIG_SOC_FLASH_ESP32
103 spi_flash_guard_set(&g_flash_guard_default_ops);
104 #endif
105
106 #endif /* CONFIG_MCUBOOT */
107
108 /*Initialize the esp32c3 interrupt controller */
109 esp_intr_initialize();
110
111 /* Start Zephyr */
112 z_cstart();
113
114 CODE_UNREACHABLE;
115 }
116
117 /* Boot-time static default printk handler, possibly to be overridden later. */
arch_printk_char_out(int c)118 int IRAM_ATTR arch_printk_char_out(int c)
119 {
120 if (c == '\n') {
121 esp_rom_uart_tx_one_char('\r');
122 }
123 esp_rom_uart_tx_one_char(c);
124 return 0;
125 }
126
esp_restart_noos(void)127 void IRAM_ATTR esp_restart_noos(void)
128 {
129 /* Disable interrupts */
130 csr_read_clear(mstatus, MSTATUS_MIE);
131
132 /* Flush any data left in UART FIFOs */
133 esp_rom_uart_tx_wait_idle(0);
134 esp_rom_uart_tx_wait_idle(1);
135
136 /* 2nd stage bootloader reconfigures SPI flash signals. */
137 /* Reset them to the defaults expected by ROM */
138 WRITE_PERI_REG(GPIO_FUNC0_IN_SEL_CFG_REG, 0x30);
139 WRITE_PERI_REG(GPIO_FUNC1_IN_SEL_CFG_REG, 0x30);
140 WRITE_PERI_REG(GPIO_FUNC2_IN_SEL_CFG_REG, 0x30);
141 WRITE_PERI_REG(GPIO_FUNC3_IN_SEL_CFG_REG, 0x30);
142 WRITE_PERI_REG(GPIO_FUNC4_IN_SEL_CFG_REG, 0x30);
143 WRITE_PERI_REG(GPIO_FUNC5_IN_SEL_CFG_REG, 0x30);
144
145 /* Reset wifi/bluetooth/ethernet/sdio (bb/mac) */
146 SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG,
147 SYSTEM_BB_RST | SYSTEM_FE_RST | SYSTEM_MAC_RST | SYSTEM_BT_RST |
148 SYSTEM_BTMAC_RST | SYSTEM_SDIO_RST | SYSTEM_EMAC_RST |
149 SYSTEM_MACPWR_RST | SYSTEM_RW_BTMAC_RST | SYSTEM_RW_BTLP_RST |
150 BLE_REG_REST_BIT | BLE_PWR_REG_REST_BIT | BLE_BB_REG_REST_BIT);
151
152 REG_WRITE(SYSTEM_CORE_RST_EN_REG, 0);
153
154 /* Reset uart0 core first, then reset apb side. */
155 SET_PERI_REG_MASK(UART_CLK_CONF_REG(0), UART_RST_CORE_M);
156
157 /* Reset timer/spi/uart */
158 SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG,
159 SYSTEM_TIMERS_RST | SYSTEM_SPI01_RST | SYSTEM_UART_RST);
160 REG_WRITE(SYSTEM_PERIP_RST_EN0_REG, 0);
161 /* Reset dma */
162 SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST);
163 REG_WRITE(SYSTEM_PERIP_RST_EN1_REG, 0);
164
165 /* Reset core */
166 soc_ll_reset_core(0);
167
168 while (true) {
169 ;
170 }
171 }
172
sys_arch_reboot(int type)173 void sys_arch_reboot(int type)
174 {
175 esp_restart_noos();
176 }
177