Skip to content

Commit

Permalink
soc: espressif: Add hardware initialization
Browse files Browse the repository at this point in the history
Bring hardware initialization to zephyr code base.

Signed-off-by: Lucas Tamborrino <[email protected]>
  • Loading branch information
LucasTambor committed Nov 21, 2024
1 parent 903b7cf commit 29e4516
Show file tree
Hide file tree
Showing 21 changed files with 808 additions and 145 deletions.
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

0 comments on commit 29e4516

Please sign in to comment.