1 /*
2  * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <soc.h>
8 #include <hal/mmu_hal.h>
9 #include <hal/mmu_types.h>
10 #include <hal/cache_types.h>
11 #include <hal/cache_ll.h>
12 #include <hal/cache_hal.h>
13 #include <rom/cache.h>
14 #include <esp_rom_sys.h>
15 #include <esp_err.h>
16 
17 #include <esp_app_format.h>
18 #include <zephyr/storage/flash_map.h>
19 #include <esp_rom_uart.h>
20 #include <esp_flash.h>
21 #include <esp_log.h>
22 #include <bootloader_clock.h>
23 #include <bootloader_common.h>
24 
25 #include <esp_cpu.h>
26 
27 #if CONFIG_SOC_SERIES_ESP32C6
28 #include <soc/hp_apm_reg.h>
29 #include <soc/lp_apm_reg.h>
30 #include <soc/lp_apm0_reg.h>
31 #include <soc/pcr_reg.h>
32 #endif /* CONFIG_SOC_SERIES_ESP32C6 */
33 
34 #include <esp_flash_internal.h>
35 #include <bootloader_flash.h>
36 #include <bootloader_flash_priv.h>
37 #include <hal/efuse_ll.h>
38 #include <hal/efuse_hal.h>
39 #include <hal/wdt_hal.h>
40 #include <soc/chip_revision.h>
41 #include <soc/rtc.h>
42 #ifndef CONFIG_SOC_SERIES_ESP32
43 #include <soc/assist_debug_reg.h>
44 #include <soc/system_reg.h>
45 #endif
46 
47 #include "hw_init.h"
48 #include "soc_init.h"
49 #include "soc_random.h"
50 
51 #define TAG "boot"
52 
53 #define CHECKSUM_ALIGN 16
54 #define IS_PADD(addr)  (addr == 0)
55 #define IS_DRAM(addr)  (addr >= SOC_DRAM_LOW && addr < SOC_DRAM_HIGH)
56 #define IS_IRAM(addr)  (addr >= SOC_IRAM_LOW && addr < SOC_IRAM_HIGH)
57 #define IS_IROM(addr)  (addr >= SOC_IROM_LOW && addr < SOC_IROM_HIGH)
58 #define IS_DROM(addr)  (addr >= SOC_DROM_LOW && addr < SOC_DROM_HIGH)
59 #define IS_SRAM(addr)  (IS_IRAM(addr) || IS_DRAM(addr))
60 #define IS_MMAP(addr)  (IS_IROM(addr) || IS_DROM(addr))
61 #define IS_NONE(addr)                                                                              \
62 	(!IS_IROM(addr) && !IS_DROM(addr) && !IS_IRAM(addr) && !IS_DRAM(addr) && !IS_PADD(addr))
63 
64 #define HDR_ATTR __attribute__((section(".entry_addr"))) __attribute__((used))
65 
66 void __start(void);
67 static HDR_ATTR void (*_entry_point)(void) = &__start;
68 
69 esp_image_header_t WORD_ALIGNED_ATTR bootloader_image_hdr;
70 extern uint32_t _image_irom_start, _image_irom_size, _image_irom_vaddr;
71 extern uint32_t _image_drom_start, _image_drom_size, _image_drom_vaddr;
72 
73 #ifndef CONFIG_MCUBOOT
74 static uint32_t _app_irom_start =
75 	(FIXED_PARTITION_OFFSET(slot0_partition) + (uint32_t)&_image_irom_start);
76 static uint32_t _app_irom_size = (uint32_t)&_image_irom_size;
77 
78 static uint32_t _app_drom_start =
79 	(FIXED_PARTITION_OFFSET(slot0_partition) + (uint32_t)&_image_drom_start);
80 static uint32_t _app_drom_size = (uint32_t)&_image_drom_size;
81 #endif
82 
83 static uint32_t _app_irom_vaddr = ((uint32_t)&_image_irom_vaddr);
84 static uint32_t _app_drom_vaddr = ((uint32_t)&_image_drom_vaddr);
85 
86 #ifndef CONFIG_BOOTLOADER_MCUBOOT
spi_flash_read(uint32_t address,void * buffer,size_t length)87 static int spi_flash_read(uint32_t address, void *buffer, size_t length)
88 {
89 	return esp_flash_read(NULL, buffer, address, length);
90 }
91 #endif /* CONFIG_BOOTLOADER_MCUBOOT */
92 
map_rom_segments(uint32_t app_drom_start,uint32_t app_drom_vaddr,uint32_t app_drom_size,uint32_t app_irom_start,uint32_t app_irom_vaddr,uint32_t app_irom_size)93 void map_rom_segments(uint32_t app_drom_start, uint32_t app_drom_vaddr, uint32_t app_drom_size,
94 		      uint32_t app_irom_start, uint32_t app_irom_vaddr, uint32_t app_irom_size)
95 {
96 	uint32_t app_irom_start_aligned = app_irom_start & MMU_FLASH_MASK;
97 	uint32_t app_irom_vaddr_aligned = app_irom_vaddr & MMU_FLASH_MASK;
98 
99 	uint32_t app_drom_start_aligned = app_drom_start & MMU_FLASH_MASK;
100 	uint32_t app_drom_vaddr_aligned = app_drom_vaddr & MMU_FLASH_MASK;
101 
102 #ifndef CONFIG_BOOTLOADER_MCUBOOT
103 	esp_image_segment_header_t WORD_ALIGNED_ATTR segment_hdr;
104 	size_t offset = FIXED_PARTITION_OFFSET(boot_partition);
105 	bool checksum = false;
106 	unsigned int segments = 0;
107 	unsigned int ram_segments = 0;
108 
109 	offset += sizeof(esp_image_header_t);
110 
111 	while (segments++ < 16) {
112 
113 		if (spi_flash_read(offset, &segment_hdr, sizeof(esp_image_segment_header_t)) != 0) {
114 			ESP_EARLY_LOGE(TAG, "Failed to read segment header at %x", offset);
115 			abort();
116 		}
117 
118 		/* TODO: Find better end-of-segment detection */
119 		if (IS_NONE(segment_hdr.load_addr)) {
120 			/* Total segment count = (segments - 1) */
121 			break;
122 		}
123 
124 		ESP_EARLY_LOGI(TAG, "%s: lma 0x%08x vma 0x%08x len 0x%-6x (%u)",
125 			       IS_NONE(segment_hdr.load_addr) ? "???"
126 			       : IS_MMAP(segment_hdr.load_addr)
127 				       ? IS_IROM(segment_hdr.load_addr) ? "IMAP" : "DMAP"
128 			       : IS_PADD(segment_hdr.load_addr) ? "padd"
129 			       : IS_DRAM(segment_hdr.load_addr) ? "DRAM"
130 								: "IRAM",
131 			       offset + sizeof(esp_image_segment_header_t), segment_hdr.load_addr,
132 			       segment_hdr.data_len, segment_hdr.data_len);
133 
134 		/* Fix drom and irom produced be the linker, as it could
135 		 * be invalidated by the elf2image and flash load offset
136 		 */
137 		if (segment_hdr.load_addr == _app_drom_vaddr) {
138 			app_drom_start = offset + sizeof(esp_image_segment_header_t);
139 			app_drom_start_aligned = app_drom_start & MMU_FLASH_MASK;
140 		}
141 		if (segment_hdr.load_addr == _app_irom_vaddr) {
142 			app_irom_start = offset + sizeof(esp_image_segment_header_t);
143 			app_irom_start_aligned = app_irom_start & MMU_FLASH_MASK;
144 		}
145 		if (IS_SRAM(segment_hdr.load_addr)) {
146 			ram_segments++;
147 		}
148 		offset += sizeof(esp_image_segment_header_t) + segment_hdr.data_len;
149 
150 		if (ram_segments == bootloader_image_hdr.segment_count && !checksum) {
151 			offset += (CHECKSUM_ALIGN - 1) - (offset % CHECKSUM_ALIGN) + 1;
152 			checksum = true;
153 		}
154 	}
155 	if (segments == 0 || segments == 16) {
156 		ESP_EARLY_LOGE(TAG, "Error parsing segments");
157 		abort();
158 	}
159 
160 	ESP_EARLY_LOGI(TAG, "Image with %d segments", segments - 1);
161 #endif /* !CONFIG_BOOTLOADER_MCUBOOT */
162 
163 #if CONFIG_SOC_SERIES_ESP32
164 	Cache_Read_Disable(0);
165 	Cache_Flush(0);
166 #else
167 	cache_hal_disable(CACHE_TYPE_ALL);
168 #endif /* CONFIG_SOC_SERIES_ESP32 */
169 
170 	/* Clear the MMU entries that are already set up,
171 	 * so the new app only has the mappings it creates.
172 	 */
173 	mmu_hal_unmap_all();
174 
175 #if CONFIG_SOC_SERIES_ESP32
176 	int rc = 0;
177 	uint32_t drom_page_count =
178 		(app_drom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE;
179 
180 	rc |= cache_flash_mmu_set(0, 0, app_drom_vaddr_aligned, app_drom_start_aligned, 64,
181 				  drom_page_count);
182 	rc |= cache_flash_mmu_set(1, 0, app_drom_vaddr_aligned, app_drom_start_aligned, 64,
183 				  drom_page_count);
184 
185 	uint32_t irom_page_count =
186 		(app_irom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE;
187 
188 	rc |= cache_flash_mmu_set(0, 0, app_irom_vaddr_aligned, app_irom_start_aligned, 64,
189 				  irom_page_count);
190 	rc |= cache_flash_mmu_set(1, 0, app_irom_vaddr_aligned, app_irom_start_aligned, 64,
191 				  irom_page_count);
192 	if (rc != 0) {
193 		ESP_EARLY_LOGE(TAG, "Failed to setup XIP, aborting");
194 		abort();
195 	}
196 #else
197 	uint32_t actual_mapped_len = 0;
198 
199 	mmu_hal_map_region(0, MMU_TARGET_FLASH0, app_drom_vaddr_aligned, app_drom_start_aligned,
200 			   app_drom_size, &actual_mapped_len);
201 
202 	mmu_hal_map_region(0, MMU_TARGET_FLASH0, app_irom_vaddr_aligned, app_irom_start_aligned,
203 			   app_irom_size, &actual_mapped_len);
204 #endif /* CONFIG_SOC_SERIES_ESP32 */
205 
206 	/* ----------------------Enable corresponding buses---------------- */
207 	cache_bus_mask_t bus_mask = cache_ll_l1_get_bus(0, app_drom_vaddr_aligned, app_drom_size);
208 
209 	cache_ll_l1_enable_bus(0, bus_mask);
210 	bus_mask = cache_ll_l1_get_bus(0, app_irom_vaddr_aligned, app_irom_size);
211 	cache_ll_l1_enable_bus(0, bus_mask);
212 #if CONFIG_MP_MAX_NUM_CPUS > 1
213 	bus_mask = cache_ll_l1_get_bus(1, app_drom_vaddr_aligned, app_drom_size);
214 	cache_ll_l1_enable_bus(1, bus_mask);
215 	bus_mask = cache_ll_l1_get_bus(1, app_irom_vaddr_aligned, app_irom_size);
216 	cache_ll_l1_enable_bus(1, bus_mask);
217 #endif
218 
219 	/* ----------------------Enable Cache---------------- */
220 #if CONFIG_SOC_SERIES_ESP32
221 	/* Application will need to do Cache_Flush(1) and Cache_Read_Enable(1) */
222 	Cache_Read_Enable(0);
223 #else
224 	cache_hal_enable(CACHE_TYPE_ALL);
225 #endif /* CONFIG_SOC_SERIES_ESP32 */
226 
227 #if !defined(CONFIG_SOC_SERIES_ESP32) && !defined(CONFIG_SOC_SERIES_ESP32S2)
228 	/* Configure the Cache MMU size for instruction and rodata in flash. */
229 	uint32_t cache_mmu_irom_size =
230 		((app_irom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE) *
231 		sizeof(uint32_t);
232 
233 	/* Split the cache usage by the segment sizes */
234 	Cache_Set_IDROM_MMU_Size(cache_mmu_irom_size, CACHE_DROM_MMU_MAX_END - cache_mmu_irom_size);
235 #endif
236 	/* Show map segments continue using same log format as during MCUboot phase */
237 	ESP_EARLY_LOGI(TAG, "%s segment: paddr=%08xh, vaddr=%08xh, size=%05Xh (%6d) map", "DROM",
238 		       app_drom_start_aligned, app_drom_vaddr_aligned, app_drom_size,
239 		       app_drom_size);
240 	ESP_EARLY_LOGI(TAG, "%s segment: paddr=%08xh, vaddr=%08xh, size=%05Xh (%6d) map", "IROM",
241 		       app_irom_start_aligned, app_irom_vaddr_aligned, app_irom_size,
242 		       app_irom_size);
243 	esp_rom_uart_tx_wait_idle(0);
244 }
245 
__start(void)246 void __start(void)
247 {
248 #ifdef CONFIG_RISCV_GP
249 	/* Configure the global pointer register
250 	 * (This should be the first thing startup does, as any other piece of code could be
251 	 * relaxed by the linker to access something relative to __global_pointer$)
252 	 */
253 	__asm__ __volatile__(".option push\n"
254 			     ".option norelax\n"
255 			     "la gp, __global_pointer$\n"
256 			     ".option pop");
257 #endif /* CONFIG_RISCV_GP */
258 
259 #ifndef CONFIG_BOOTLOADER_MCUBOOT
260 	/* Init fundamental components */
261 	if (hardware_init()) {
262 		ESP_EARLY_LOGE(TAG, "HW init failed, aborting");
263 		abort();
264 	}
265 #endif
266 
267 #if !defined(CONFIG_SOC_ESP32_APPCPU) && !defined(CONFIG_SOC_ESP32S3_APPCPU) && \
268 	!defined(CONFIG_MCUBOOT)
269 	map_rom_segments(_app_drom_start, _app_drom_vaddr, _app_drom_size, _app_irom_start,
270 			 _app_irom_vaddr, _app_irom_size);
271 #endif
272 #ifndef CONFIG_SOC_SERIES_ESP32C2
273 	/* Disable RNG entropy source as it was already used */
274 	soc_random_disable();
275 #endif /* CONFIG_SOC_SERIES_ESP32C2 */
276 #if defined(CONFIG_SOC_SERIES_ESP32S3) || defined(CONFIG_SOC_SERIES_ESP32C3)
277 	/* Disable glitch detection as it can be falsely triggered by EMI interference */
278 	ESP_EARLY_LOGI(TAG, "Disabling glitch detection");
279 	ana_clock_glitch_reset_config(false);
280 #endif /* CONFIG_SOC_SERIES_ESP32S2 */
281 	ESP_EARLY_LOGI(TAG, "Jumping to the main image...");
282 	__esp_platform_start();
283 }
284