Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

soc: espressif: Add hardware initialization #80400

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions soc/espressif/common/include/hw_init.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef _SOC_ESPRESSIF_COMMON_HW_INIT_H_
#define _SOC_ESPRESSIF_COMMON_HW_INIT_H_

int hardware_init(void);

#endif /* _SOC_ESPRESSIF_COMMON_HW_INIT_H_ */
169 changes: 95 additions & 74 deletions soc/espressif/common/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,62 +14,84 @@
#include <esp_rom_sys.h>
#include <esp_err.h>

#define MMU_FLASH_MASK (~(CONFIG_MMU_PAGE_SIZE - 1))

#include <esp_app_format.h>
#include <zephyr/storage/flash_map.h>
#include "esp_rom_uart.h"
#include "esp_flash.h"
#include "esp_log.h"
#include "bootloader_init.h"
#include "bootloader_random.h"
#include "bootloader_soc.h"
#include <esp_rom_uart.h>
#include <esp_flash.h>
#include <esp_log.h>
#include <bootloader_clock.h>
#include <bootloader_common.h>

#include <esp_cpu.h>

#if CONFIG_SOC_SERIES_ESP32C6
#include <soc/hp_apm_reg.h>
#include <soc/lp_apm_reg.h>
#include <soc/lp_apm0_reg.h>
#include <soc/pcr_reg.h>
#endif /* CONFIG_SOC_SERIES_ESP32C6 */

#include <esp_flash_internal.h>
#include <bootloader_flash.h>
#include <bootloader_flash_priv.h>
#include <hal/efuse_ll.h>
#include <hal/efuse_hal.h>
#include <hal/wdt_hal.h>
#include <soc/chip_revision.h>
#include <soc/rtc.h>
#ifndef CONFIG_SOC_SERIES_ESP32
#include <soc/assist_debug_reg.h>
#include <soc/system_reg.h>
#endif

#include "hw_init.h"
#include "soc_init.h"
#include "soc_random.h"

#define TAG "boot"

#define CHECKSUM_ALIGN 16
#define IS_PADD(addr) (addr == 0)
#define IS_DRAM(addr) (addr >= SOC_DRAM_LOW && addr < SOC_DRAM_HIGH)
#define IS_IRAM(addr) (addr >= SOC_IRAM_LOW && addr < SOC_IRAM_HIGH)
#define IS_IROM(addr) (addr >= SOC_IROM_LOW && addr < SOC_IROM_HIGH)
#define IS_DROM(addr) (addr >= SOC_DROM_LOW && addr < SOC_DROM_HIGH)
#define IS_SRAM(addr) (IS_IRAM(addr) || IS_DRAM(addr))
#define IS_MMAP(addr) (IS_IROM(addr) || IS_DROM(addr))
#define IS_NONE(addr) (!IS_IROM(addr) && !IS_DROM(addr) \
&& !IS_IRAM(addr) && !IS_DRAM(addr) && !IS_PADD(addr))
#define IS_PADD(addr) (addr == 0)
#define IS_DRAM(addr) (addr >= SOC_DRAM_LOW && addr < SOC_DRAM_HIGH)
#define IS_IRAM(addr) (addr >= SOC_IRAM_LOW && addr < SOC_IRAM_HIGH)
#define IS_IROM(addr) (addr >= SOC_IROM_LOW && addr < SOC_IROM_HIGH)
#define IS_DROM(addr) (addr >= SOC_DROM_LOW && addr < SOC_DROM_HIGH)
#define IS_SRAM(addr) (IS_IRAM(addr) || IS_DRAM(addr))
#define IS_MMAP(addr) (IS_IROM(addr) || IS_DROM(addr))
#define IS_NONE(addr) \
(!IS_IROM(addr) && !IS_DROM(addr) && !IS_IRAM(addr) && !IS_DRAM(addr) && !IS_PADD(addr))

#define HDR_ATTR __attribute__((section(".entry_addr"))) __attribute__((used))

void __start(void);
static HDR_ATTR void (*_entry_point)(void) = &__start;

extern esp_image_header_t bootloader_image_hdr;
esp_image_header_t WORD_ALIGNED_ATTR bootloader_image_hdr;
extern uint32_t _image_irom_start, _image_irom_size, _image_irom_vaddr;
extern uint32_t _image_drom_start, _image_drom_size, _image_drom_vaddr;

#ifndef CONFIG_MCUBOOT
static uint32_t _app_irom_start = (FIXED_PARTITION_OFFSET(slot0_partition) +
(uint32_t)&_image_irom_start);
static uint32_t _app_irom_start =
(FIXED_PARTITION_OFFSET(slot0_partition) + (uint32_t)&_image_irom_start);
static uint32_t _app_irom_size = (uint32_t)&_image_irom_size;

static uint32_t _app_drom_start = (FIXED_PARTITION_OFFSET(slot0_partition) +
(uint32_t)&_image_drom_start);
static uint32_t _app_drom_start =
(FIXED_PARTITION_OFFSET(slot0_partition) + (uint32_t)&_image_drom_start);
static uint32_t _app_drom_size = (uint32_t)&_image_drom_size;
#endif

static uint32_t _app_irom_vaddr = ((uint32_t)&_image_irom_vaddr);
static uint32_t _app_drom_vaddr = ((uint32_t)&_image_drom_vaddr);

#ifndef CONFIG_BOOTLOADER_MCUBOOT
static esp_err_t spi_flash_read(uint32_t address, void *buffer, size_t length)
static int spi_flash_read(uint32_t address, void *buffer, size_t length)
{
return esp_flash_read(NULL, buffer, address, length);
}
#endif /* CONFIG_BOOTLOADER_MCUBOOT */

void 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)
void 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)
{
uint32_t app_irom_start_aligned = app_irom_start & MMU_FLASH_MASK;
uint32_t app_irom_vaddr_aligned = app_irom_vaddr & MMU_FLASH_MASK;
Expand All @@ -88,8 +110,7 @@ void map_rom_segments(uint32_t app_drom_start, uint32_t app_drom_vaddr,

while (segments++ < 16) {

if (spi_flash_read(offset, &segment_hdr,
sizeof(esp_image_segment_header_t)) != ESP_OK) {
if (spi_flash_read(offset, &segment_hdr, sizeof(esp_image_segment_header_t)) != 0) {
ESP_EARLY_LOGE(TAG, "Failed to read segment header at %x", offset);
abort();
}
Expand All @@ -101,13 +122,14 @@ void map_rom_segments(uint32_t app_drom_start, uint32_t app_drom_vaddr,
}

ESP_EARLY_LOGI(TAG, "%s: lma 0x%08x vma 0x%08x len 0x%-6x (%u)",
IS_NONE(segment_hdr.load_addr) ? "???" :
IS_MMAP(segment_hdr.load_addr) ?
IS_IROM(segment_hdr.load_addr) ? "IMAP" : "DMAP" :
IS_PADD(segment_hdr.load_addr) ? "padd" :
IS_DRAM(segment_hdr.load_addr) ? "DRAM" : "IRAM",
offset + sizeof(esp_image_segment_header_t),
segment_hdr.load_addr, segment_hdr.data_len, segment_hdr.data_len);
IS_NONE(segment_hdr.load_addr) ? "???"
: IS_MMAP(segment_hdr.load_addr)
? IS_IROM(segment_hdr.load_addr) ? "IMAP" : "DMAP"
: IS_PADD(segment_hdr.load_addr) ? "padd"
: IS_DRAM(segment_hdr.load_addr) ? "DRAM"
: "IRAM",
offset + sizeof(esp_image_segment_header_t), segment_hdr.load_addr,
segment_hdr.data_len, segment_hdr.data_len);

/* Fix drom and irom produced be the linker, as it could
* be invalidated by the elf2image and flash load offset
Expand Down Expand Up @@ -153,34 +175,32 @@ void map_rom_segments(uint32_t app_drom_start, uint32_t app_drom_vaddr,
#if CONFIG_SOC_SERIES_ESP32
int rc = 0;
uint32_t drom_page_count =
(app_drom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE;
(app_drom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE;

rc |= cache_flash_mmu_set(0, 0, app_drom_vaddr_aligned,
app_drom_start_aligned, 64, drom_page_count);
rc |= cache_flash_mmu_set(1, 0, app_drom_vaddr_aligned,
app_drom_start_aligned, 64, drom_page_count);
rc |= cache_flash_mmu_set(0, 0, app_drom_vaddr_aligned, app_drom_start_aligned, 64,
drom_page_count);
rc |= cache_flash_mmu_set(1, 0, app_drom_vaddr_aligned, app_drom_start_aligned, 64,
drom_page_count);

uint32_t irom_page_count =
(app_irom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE;
(app_irom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE;

rc |= cache_flash_mmu_set(0, 0, app_irom_vaddr_aligned,
app_irom_start_aligned, 64, irom_page_count);
rc |= cache_flash_mmu_set(1, 0, app_irom_vaddr_aligned,
app_irom_start_aligned, 64, irom_page_count);
rc |= cache_flash_mmu_set(0, 0, app_irom_vaddr_aligned, app_irom_start_aligned, 64,
irom_page_count);
rc |= cache_flash_mmu_set(1, 0, app_irom_vaddr_aligned, app_irom_start_aligned, 64,
irom_page_count);
if (rc != 0) {
ESP_EARLY_LOGE(TAG, "Failed to setup XIP, aborting");
abort();
}
#else
uint32_t actual_mapped_len = 0;

mmu_hal_map_region(0, MMU_TARGET_FLASH0,
app_drom_vaddr_aligned, app_drom_start_aligned,
app_drom_size, &actual_mapped_len);
mmu_hal_map_region(0, MMU_TARGET_FLASH0, app_drom_vaddr_aligned, app_drom_start_aligned,
app_drom_size, &actual_mapped_len);

mmu_hal_map_region(0, MMU_TARGET_FLASH0,
app_irom_vaddr_aligned, app_irom_start_aligned,
app_irom_size, &actual_mapped_len);
mmu_hal_map_region(0, MMU_TARGET_FLASH0, app_irom_vaddr_aligned, app_irom_start_aligned,
app_irom_size, &actual_mapped_len);
#endif /* CONFIG_SOC_SERIES_ESP32 */

/* ----------------------Enable corresponding buses---------------- */
Expand All @@ -206,22 +226,20 @@ void map_rom_segments(uint32_t app_drom_start, uint32_t app_drom_vaddr,

#if !defined(CONFIG_SOC_SERIES_ESP32) && !defined(CONFIG_SOC_SERIES_ESP32S2)
/* Configure the Cache MMU size for instruction and rodata in flash. */
uint32_t cache_mmu_irom_size = ((app_irom_size + CONFIG_MMU_PAGE_SIZE - 1) /
CONFIG_MMU_PAGE_SIZE) * sizeof(uint32_t);
uint32_t cache_mmu_irom_size =
((app_irom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE) *
sizeof(uint32_t);

/* Split the cache usage by the segment sizes */
Cache_Set_IDROM_MMU_Size(cache_mmu_irom_size,
CACHE_DROM_MMU_MAX_END - cache_mmu_irom_size);
Cache_Set_IDROM_MMU_Size(cache_mmu_irom_size, CACHE_DROM_MMU_MAX_END - cache_mmu_irom_size);
#endif
/* Show map segments continue using same log format as during MCUboot phase */
ESP_EARLY_LOGI(TAG, "%s segment: paddr=%08xh, vaddr=%08xh, size=%05Xh (%6d) map",
"DROM",
app_drom_start_aligned, app_drom_vaddr_aligned,
app_drom_size, app_drom_size);
ESP_EARLY_LOGI(TAG, "%s segment: paddr=%08xh, vaddr=%08xh, size=%05Xh (%6d) map",
"IROM",
app_irom_start_aligned, app_irom_vaddr_aligned,
app_irom_size, app_irom_size);
ESP_EARLY_LOGI(TAG, "%s segment: paddr=%08xh, vaddr=%08xh, size=%05Xh (%6d) map", "DROM",
app_drom_start_aligned, app_drom_vaddr_aligned, app_drom_size,
app_drom_size);
ESP_EARLY_LOGI(TAG, "%s segment: paddr=%08xh, vaddr=%08xh, size=%05Xh (%6d) map", "IROM",
app_irom_start_aligned, app_irom_vaddr_aligned, app_irom_size,
app_irom_size);
esp_rom_uart_tx_wait_idle(0);
}

Expand All @@ -233,29 +251,32 @@ void __start(void)
* relaxed by the linker to access something relative to __global_pointer$)
*/
__asm__ __volatile__(".option push\n"
".option norelax\n"
"la gp, __global_pointer$\n"
".option pop");
".option norelax\n"
"la gp, __global_pointer$\n"
".option pop");
#endif /* CONFIG_RISCV_GP */

#ifndef CONFIG_BOOTLOADER_MCUBOOT
/* Init fundamental components */
if (bootloader_init()) {
if (hardware_init()) {
ESP_EARLY_LOGE(TAG, "HW init failed, aborting");
abort();
}
#endif

#if !defined(CONFIG_MCUBOOT) && !defined(CONFIG_SOC_ESP32S3_APPCPU)
map_rom_segments(_app_drom_start, _app_drom_vaddr, _app_drom_size,
_app_irom_start, _app_irom_vaddr, _app_irom_size);
map_rom_segments(_app_drom_start, _app_drom_vaddr, _app_drom_size, _app_irom_start,
_app_irom_vaddr, _app_irom_size);
#endif

#ifndef CONFIG_SOC_SERIES_ESP32C2
/* Disable RNG entropy source as it was already used */
bootloader_random_disable();

soc_random_disable();
#endif /* CONFIG_SOC_SERIES_ESP32C2 */
#if defined(CONFIG_SOC_SERIES_ESP32S3) || defined(CONFIG_SOC_SERIES_ESP32C3)
/* Disable glitch detection as it can be falsely triggered by EMI interference */
bootloader_ana_clock_glitch_reset_config(false);

ESP_EARLY_LOGI(TAG, "Disabling glitch detection");
ana_clock_glitch_reset_config(false);
#endif /* CONFIG_SOC_SERIES_ESP32S2 */
ESP_EARLY_LOGI(TAG, "Jumping to the main image...");
__esp_platform_start();
}
2 changes: 2 additions & 0 deletions soc/espressif/esp32/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ endif()

zephyr_include_directories(.)

zephyr_sources_ifndef(CONFIG_BOOTLOADER_MCUBOOT hw_init.c)

zephyr_library_sources_ifdef(CONFIG_NEWLIB_LIBC newlib_fix.c)

zephyr_library_sources_ifdef(CONFIG_GDBSTUB gdbstub.c)
Expand Down
23 changes: 12 additions & 11 deletions soc/espressif/esp32/default.ld
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,12 @@ SECTIONS
*libzephyr.a:log_output.*(.literal .text .literal.* .text.*)
*libzephyr.a:log_backend_uart.*(.literal .text .literal.* .text.*)
*libzephyr.a:loader.*(.literal .text .literal.* .text.*)
*libzephyr.a:flash_init.*(.literal .text .literal.* .text.*)
*libzephyr.a:soc_flash_init.*(.literal .text .literal.* .text.*)
*libzephyr.a:console_init.*(.literal .text .literal.* .text.*)
*libzephyr.a:soc_random.*(.literal .text .literal.* .text.*)
*libzephyr.a:soc_init.*(.literal .text .literal.* .text.*)
*libzephyr.a:hw_init.*(.literal .text .literal.* .text.*)
*libzephyr.a:rtc_*.*(.literal .text .literal.* .text.*)
*libzephyr.a:cpu_util.*(.literal .text .literal.* .text.*)
*libdrivers__flash.a:flash_esp32.*(.literal .text .literal.* .text.*)
Expand Down Expand Up @@ -403,21 +409,14 @@ SECTIONS
.loader.text :
{
. = ALIGN(4);
*libzephyr.a:bootloader_init.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_esp32.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_clock_init.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_wdt.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_flash.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_flash_config_esp32.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_common_loader.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_common.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_mem.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_random.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_efuse.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_utility.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_sha.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_console.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_panic.*(.literal .text .literal.* .text.*)

*libzephyr.a:esp_image_format.*(.literal .text .literal.* .text.*)
Expand Down Expand Up @@ -520,6 +519,12 @@ SECTIONS
*libzephyr.a:log_backend_uart.*(.rodata .rodata.*)
*libzephyr.a:log_output.*(.rodata .rodata.*)
*libzephyr.a:loader.*(.rodata .rodata.*)
*libzephyr.a:flash_init.*(.rodata .rodata.*)
*libzephyr.a:soc_flash_init.*(.rodata .rodata.*)
*libzephyr.a:console_init.*(.rodata .rodata.*)
*libzephyr.a:soc_random.*(.rodata .rodata.*)
*libzephyr.a:soc_init.*(.rodata .rodata.*)
*libzephyr.a:hw_init.*(.rodata .rodata.*)
*libdrivers__flash.a:flash_esp32.*(.rodata .rodata.*)
*libdrivers__serial.a:uart_esp32.*(.rodata .rodata.*)
*libzephyr.a:esp_memory_utils.*(.rodata .rodata.* .sdata2 .sdata2.* .srodata .srodata.*)
Expand Down Expand Up @@ -625,14 +630,10 @@ SECTIONS
{
. = ALIGN(4);
_loader_data_start = ABSOLUTE(.);
*libzephyr.a:bootloader_init.*(.rodata .rodata.* .sdata2 .sdata2.* .srodata .srodata.*)
*libzephyr.a:bootloader_esp32.*(.rodata .rodata.* .sdata2 .sdata2.* .srodata .srodata.*)
*libzephyr.a:bootloader_clock_init.*(.rodata .rodata.* .sdata2 .sdata2.* .srodata .srodata.*)
*libzephyr.a:bootloader_wdt.*(.rodata .rodata.* .sdata2 .sdata2.* .srodata .srodata.*)
*libzephyr.a:bootloader_flash.*(.rodata .rodata.* .sdata2 .sdata2.* .srodata .srodata.*)
*libzephyr.a:bootloader_flash_config_esp32.*(.rodata .rodata.* .sdata2 .sdata2.* .srodata .srodata.*)
*libzephyr.a:bootloader_common.*(.rodata .rodata.* .sdata2 .sdata2.* .srodata .srodata.*)
*libzephyr.a:bootloader_common_loader.*(.rodata .rodata.* .sdata2 .sdata2.* .srodata .srodata.*)
*libzephyr.a:bootloader_efuse.*(.rodata .rodata.* .sdata2 .sdata2.* .srodata .srodata.*)

*libzephyr.a:cpu_util.*(.rodata .rodata.* .sdata2 .sdata2.* .srodata .srodata.*)
Expand Down
Loading
Loading