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