diff --git a/soc/espressif/common/loader.c b/soc/espressif/common/loader.c index b520e427ac2..01e27bc5886 100644 --- a/soc/espressif/common/loader.c +++ b/soc/espressif/common/loader.c @@ -84,7 +84,6 @@ void map_rom_segments(uint32_t app_drom_start, uint32_t app_drom_vaddr, unsigned int segments = 0; unsigned int ram_segments = 0; - /* Using already fetched bootloader image header from bootloader_init */ offset += sizeof(esp_image_header_t); while (segments++ < 16) { @@ -223,7 +222,6 @@ void map_rom_segments(uint32_t app_drom_start, uint32_t app_drom_vaddr, "IROM", app_irom_start_aligned, app_irom_vaddr_aligned, app_irom_size, app_irom_size); - ets_printf("\n\r"); esp_rom_uart_tx_wait_idle(0); } @@ -248,7 +246,7 @@ void __start(void) } #endif -#ifndef CONFIG_MCUBOOT +#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); #endif diff --git a/soc/espressif/esp32/Kconfig b/soc/espressif/esp32/Kconfig index 3059ea322f5..9aeaada682e 100644 --- a/soc/espressif/esp32/Kconfig +++ b/soc/espressif/esp32/Kconfig @@ -32,8 +32,7 @@ config ESP32_APPCPU_DRAM config SOC_ENABLE_APPCPU bool default y - depends on IPM && SOC_ESP32_PROCPU - depends on MBOX && SOC_ESP32_PROCPU + depends on (IPM || MBOX) && SOC_ESP32_PROCPU help This hidden configuration lets PROCPU core to map and start APPCPU whenever IPM is enabled. diff --git a/soc/espressif/esp32s3/CMakeLists.txt b/soc/espressif/esp32s3/CMakeLists.txt index 5f64bd335c2..706fe6eb39f 100644 --- a/soc/espressif/esp32s3/CMakeLists.txt +++ b/soc/espressif/esp32s3/CMakeLists.txt @@ -1,14 +1,20 @@ # SPDX-License-Identifier: Apache-2.0 if (CONFIG_SOC_ESP32S3_APPCPU) - zephyr_sources(soc_appcpu.c) + + zephyr_sources( + soc_appcpu.c + ) + else() + zephyr_sources( soc.c soc_cache.c esp32s3-mp.c ../common/loader.c ) + endif() zephyr_include_directories(.) @@ -22,13 +28,24 @@ zephyr_library_sources_ifdef(CONFIG_POWEROFF poweroff.c) # Get flash size to use in esptool as string math(EXPR esptoolpy_flashsize "${CONFIG_FLASH_SIZE} / 0x100000") -# Make rom loader compatible binary file -if(NOT CONFIG_BOOTLOADER_MCUBOOT) +# Get UART baudrate from DT +dt_chosen(dts_shell_uart PROPERTY "zephyr,shell-uart") +if(${dts_shell_uart}) + dt_prop(monitor_baud PATH ${dts_shell_uart} PROPERTY "current-speed") +endif() + +board_runner_args(esp32 "--esp-monitor-baud=${monitor_baud}") + +message("-- Espressif HAL path: ${ESP_IDF_PATH}") + +# Select image processing + +if(CONFIG_ESP_SIMPLE_BOOT OR CONFIG_MCUBOOT) if(CONFIG_BUILD_OUTPUT_BIN) set(ESPTOOL_PY ${ESP_IDF_PATH}/tools/esptool_py/esptool.py) - message("esptool path: ${ESPTOOL_PY}") + message("-- Use the esptool.py: ${ESPTOOL_PY}") set(ELF2IMAGE_ARG "") if(NOT CONFIG_MCUBOOT) @@ -37,49 +54,35 @@ if(NOT CONFIG_BOOTLOADER_MCUBOOT) set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND ${PYTHON_EXECUTABLE} ${ESPTOOL_PY} - ARGS --chip esp32s3 elf2image ${ELF2IMAGE_ARG} + ARGS --chip ${CONFIG_SOC} elf2image ${ELF2IMAGE_ARG} --flash_mode dio --flash_freq 40m --flash_size ${esptoolpy_flashsize}MB -o ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.elf) + endif() endif() -## When building for APPCPU -if (CONFIG_SOC_ESP32S3_APPCPU) - - if(CONFIG_BUILD_OUTPUT_BIN) - set_property(GLOBAL APPEND PROPERTY extra_post_build_commands - COMMAND ${PYTHON_EXECUTABLE} ${ESP_IDF_PATH}/tools/esp_bin2c_array.py - ARGS -i ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin - -o ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.c - -a "esp32s3_appcpu_fw_array") - endif() - -else() - ## Building for PROCPU - - set_property(TARGET bintools PROPERTY disassembly_flag_inline_source) - - # Get code-partition boot address +# Select the image origin depending on the boot configuration +if(CONFIG_SOC_ESP32S3_APPCPU) + dt_nodelabel(dts_partition_path NODELABEL "slot0_appcpu_partition") +elseif(CONFIG_MCUBOOT) dt_nodelabel(dts_partition_path NODELABEL "boot_partition") - dt_reg_addr(boot_off PATH ${dts_partition_path}) - - # Get code-partition slot0 address +elseif(CONFIG_ESP_SIMPLE_BOOT) + dt_nodelabel(dts_partition_path NODELABEL "boot_partition") +else() dt_nodelabel(dts_partition_path NODELABEL "slot0_partition") - dt_reg_addr(img_0_off PATH ${dts_partition_path}) - - if(CONFIG_BOOTLOADER_MCUBOOT) - board_finalize_runner_args(esp32 "--esp-app-address=${img_0_off}") - else() - board_finalize_runner_args(esp32 "--esp-app-address=${boot_off}") - endif() - endif() +dt_reg_addr(image_off PATH ${dts_partition_path}) +board_finalize_runner_args(esp32 "--esp-app-address=${image_off}") + +message("-- Image partition ${dts_partition_path}") + +# Look for cross references between bootloader sections if(CONFIG_MCUBOOT) - # search from cross references between bootloader sections + message("check_callgraph using: ${ESP_IDF_PATH}/tools/ci/check_callgraph.py") set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND diff --git a/soc/espressif/esp32s3/Kconfig b/soc/espressif/esp32s3/Kconfig index cfda258d8c2..3e2886edcf6 100644 --- a/soc/espressif/esp32s3/Kconfig +++ b/soc/espressif/esp32s3/Kconfig @@ -14,28 +14,6 @@ config SOC_SERIES_ESP32S3 if SOC_SERIES_ESP32S3 -config ESP32S3_APPCPU_IRAM - hex "ESP32S3 APPCPU IRAM size" - depends on SOC_ESP32S3_PROCPU || SOC_ESP32S3_APPCPU - default 0x20000 - help - Defines APPCPU IRAM area in bytes. - -config ESP32S3_APPCPU_DRAM - hex "ESP32S3 APPCPU DRAM size" - depends on SOC_ESP32S3_PROCPU || SOC_ESP32S3_APPCPU - default 0x10000 - help - Defines APPCPU DRAM area in bytes. - -config SOC_ENABLE_APPCPU - bool - default y - depends on IPM && SOC_ESP32S3_PROCPU - depends on MBOX && SOC_ESP32S3_PROCPU - help - This hidden configuration lets PROCPU core to map and start APPCPU whenever IPM is enabled. - menu "Cache config" choice ESP32S3_INSTRUCTION_CACHE_SIZE @@ -178,4 +156,6 @@ config MAC_BB_PD endmenu # Cache config +rsource "Kconfig.amp" + endif # SOC_SERIES_ESP32S3 diff --git a/soc/espressif/esp32s3/Kconfig.amp b/soc/espressif/esp32s3/Kconfig.amp new file mode 100644 index 00000000000..f6acbbc52a2 --- /dev/null +++ b/soc/espressif/esp32s3/Kconfig.amp @@ -0,0 +1,31 @@ +# Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_ESP32S3 + +menu "AMP config" + +config ESP32S3_APPCPU_IRAM_SIZE + hex "ESP32S3 APPCPU IRAM size" + depends on SOC_ESP32S3_PROCPU || SOC_ESP32S3_APPCPU + default 0x10000 + help + Defines APPCPU IRAM area size in bytes. + +config ESP32S3_APPCPU_DRAM_SIZE + hex "ESP32S3 APPCPU DRAM size" + depends on SOC_ESP32S3_PROCPU || SOC_ESP32S3_APPCPU + default 0x10000 + help + Defines APPCPU DRAM area size in bytes. + +config SOC_ENABLE_APPCPU + bool + default y + depends on (IPM || MBOX) && SOC_ESP32S3_PROCPU + help + This hidden configuration lets PROCPU core to map and start APPCPU whenever IPM is enabled. + +endmenu # AMP config + +endif # SOC_SERIES_ESP32S3 diff --git a/soc/espressif/esp32s3/Kconfig.defconfig b/soc/espressif/esp32s3/Kconfig.defconfig index 2d61a5cfa4b..110471dba62 100644 --- a/soc/espressif/esp32s3/Kconfig.defconfig +++ b/soc/espressif/esp32s3/Kconfig.defconfig @@ -9,4 +9,7 @@ config FLASH_SIZE config FLASH_BASE_ADDRESS default $(dt_node_reg_addr_hex,/soc/flash-controller@60002000/flash@0) +config BOOTLOADER_MCUBOOT + default y if SOC_ESP32S3_APPCPU + endif # SOC_SERIES_ESP32S3 diff --git a/soc/espressif/esp32s3/default.ld b/soc/espressif/esp32s3/default.ld index 17d865cf526..b51f1d5282c 100644 --- a/soc/espressif/esp32s3/default.ld +++ b/soc/espressif/esp32s3/default.ld @@ -10,24 +10,16 @@ #include "memory.h" -/* The "user_iram_end" represents the 2nd stage bootloader - * "iram_loader_seg" start address (that should not be overlapped). - * If no bootloader is used, we can extend it to gain more user ram. - */ -#ifdef CONFIG_ESP_SIMPLE_BOOT -user_iram_end = (BOOTLOADER_USER_DRAM_END + IRAM_DRAM_OFFSET); -#else -user_iram_end = BOOTLOADER_IRAM_LOADER_SEG_START; -#endif - /* User available SRAM memory segments */ -user_dram_seg_org = SRAM1_DRAM_START; -user_iram_seg_org = SRAM0_IRAM_START + CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE; -user_dram_end = BOOTLOADER_IRAM_LOADER_SEG_START - IRAM_DRAM_OFFSET; -user_idram_size = user_dram_end - SRAM1_DRAM_START; -sram0_iram_size = SRAM0_SIZE - CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE; -user_iram_seg_len = user_idram_size + sram0_iram_size; -user_dram_seg_len = user_idram_size; +amp_total_size = APPCPU_SRAM_TOTAL_SIZE; +procpu_iram_end = USER_IRAM_END - APPCPU_SRAM_TOTAL_SIZE; +procpu_dram_end = USER_DRAM_END - APPCPU_SRAM_TOTAL_SIZE; + +procpu_iram_org = SRAM_USER_IRAM_START; +procpu_iram_len = procpu_iram_end - procpu_iram_org; + +procpu_dram_org = SRAM1_DRAM_START; +procpu_dram_len = procpu_dram_end - procpu_dram_org; /* Aliases */ #define FLASH_CODE_REGION irom0_0_seg @@ -36,6 +28,7 @@ user_dram_seg_len = user_idram_size; #define RAMABLE_REGION dram0_0_seg #define ROMABLE_REGION FLASH +/* Zephyr macro re-definitions */ #undef GROUP_DATA_LINK_IN #define GROUP_DATA_LINK_IN(vregion, lregion) > vregion AT > lregion @@ -66,14 +59,13 @@ MEMORY FLASH (R): org = 0x0, len = FLASH_SIZE - 0x100 #endif /* CONFIG_BOOTLOADER_MCUBOOT */ - iram0_0_seg(RX): org = user_iram_seg_org, len = user_iram_seg_len - APPCPU_IRAM_SIZE - dram0_0_seg(RW): org = user_dram_seg_org, len = user_dram_seg_len - APPCPU_DRAM_SIZE + iram0_0_seg(RX): org = procpu_iram_org, len = procpu_iram_len + dram0_0_seg(RW): org = procpu_dram_org, len = procpu_dram_len irom0_0_seg(RX): org = IROM_SEG_ORG, len = IROM_SEG_LEN drom0_0_seg(R): org = DROM_SEG_ORG, len = DROM_SEG_LEN - /** - * `ext_ram_seg` and `drom0_0_seg` share the same bus and the address region. + /* The `ext_ram_seg` and `drom0_0_seg` share the same bus and the address region. * A dummy section is used to avoid overlap. See `.ext_ram.dummy` in `sections.ld.in` */ #if defined(CONFIG_ESP_SPIRAM) @@ -101,11 +93,15 @@ MEMORY ENTRY(CONFIG_KERNEL_ENTRY) /* Used as a pointer to the heap end */ +#ifdef CONFIG_SOC_ENABLE_APPCPU +_heap_sentry = procpu_dram_end; +#else _heap_sentry = DRAM_RESERVED_START; +#endif SECTIONS { - _iram_dram_offset = IRAM_DRAM_OFFSET; + _iram_dram_offset = IRAM_DRAM_OFFSET; #ifdef CONFIG_BOOTLOADER_MCUBOOT /* Reserve space for MCUboot header in the binary */ @@ -116,6 +112,7 @@ SECTIONS QUAD(0x0) QUAD(0x0) } > mcuboot_hdr + /* Image load table */ .metadata : { /* 0. Magic byte for load header */ @@ -144,7 +141,6 @@ SECTIONS } > metadata #endif /* CONFIG_BOOTLOADER_MCUBOOT */ - /* Virtual non-loadable sections */ #include @@ -275,7 +271,9 @@ SECTIONS *(.entry.text) *(.init.literal) *(.init) + _init_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION) .iram0.text : ALIGN(4) @@ -310,6 +308,11 @@ SECTIONS *libphy.a:(.phyiram .phyiram.*) *libgcov.a:(.literal .text .literal.* .text.*) + /* APPCPU_ENABLED */ + *libzephyr.a:esp32s3-mp.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_flash.*(.literal .text .literal.* .text.*) + *libzephyr.a:flash_mmap.*(.literal .text .literal.* .text.*) + /* [mapping:esp_psram] */ *libzephyr.a:mmu_psram_flash.*(.literal .literal.* .text .text.*) *libzephyr.a:esp_psram_impl_quad.*(.literal .literal.* .text .text.*) @@ -550,6 +553,11 @@ SECTIONS *libzephyr.a:esp_mmu_map.*(.rodata .rodata.*) *libdrivers__interrupt_controller.a:(.rodata .rodata.*) + /* APPCPU_ENABLE */ + *libzephyr.a:esp32s3-mp.*(.rodata .rodata.*) + *libzephyr.a:bootloader_flash.*(.rodata .rodata.* .sdata2 .sdata2.* .srodata .srodata.*) + *libzephyr.a:flash_mmap.*(.rodata .rodata.* .sdata2 .sdata2.* .srodata .srodata.*) + /* [mapping:esp_psram] */ *libzephyr.a:mmu_psram_flash.*(.rodata .rodata.*) *libzephyr.a:esp_psram_impl_octal.*(.rodata .rodata.*) @@ -798,6 +806,10 @@ SECTIONS } GROUP_DATA_LINK_IN(FLASH_CODE_REGION, ROMABLE_REGION) + /* --- END OF IROM --- */ + + /* --- START OF DROM --- */ + /* This dummy section represents the .flash.text section but in default_rodata_seg. * Thus, it must have its alignment and (at least) its size. */ @@ -879,6 +891,10 @@ SECTIONS _image_rodata_end = ABSOLUTE(.); } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) + /* --- END OF DROM --- */ + + /* --- START OF SPIRAM --- */ + /** * This section is required to skip flash rodata sections, because `ext_ram_seg` * and `drom0_0_seg` are on the same bus @@ -907,8 +923,9 @@ SECTIONS #endif /* CONFIG_ESP_SPIRAM */ - /* --- XTENSA GLUE AND DEBUG BEGIN --- */ + /* --- END OF SPIRAM --- */ + /* --- XTENSA GLUE AND DEBUG BEGIN --- */ #ifdef CONFIG_GEN_ISR_TABLES #include #endif diff --git a/soc/espressif/esp32s3/default_appcpu.ld b/soc/espressif/esp32s3/default_appcpu.ld index 4641540db75..58ec051e389 100644 --- a/soc/espressif/esp32s3/default_appcpu.ld +++ b/soc/espressif/esp32s3/default_appcpu.ld @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. * SPDX-License-Identifier: Apache-2.0 */ @@ -8,48 +8,121 @@ #include #include -#define SRAM_IRAM_START 0x40370000 -#define SRAM_DIRAM_I_START 0x40378000 -#define SRAM_IRAM_END 0x403BA000 -#define I_D_SRAM_OFFSET (SRAM_DIRAM_I_START - SRAM_DRAM_START) -#define DRAM_RESERVED_START 0x3fce9704 -#define IRAM_DRAM_OFFSET 0x6f0000 +#include "memory.h" -#define SRAM_DRAM_START 0x3FC88000 -#define SRAM_DRAM_END (SRAM_IRAM_END - I_D_SRAM_OFFSET) +/* User available SRAM memory segments */ +appcpu_iram_end = USER_IRAM_END; +appcpu_dram_end = USER_DRAM_END; -#define IRAM_REGION iram0_0_seg -#define RAMABLE_REGION dram0_0_seg -#define ROMABLE_REGION iram0_0_seg +appcpu_iram_org = appcpu_iram_end - APPCPU_SRAM_SIZE; +appcpu_dram_org = appcpu_dram_end - APPCPU_SRAM_SIZE; -#define IROM_SEG_ALIGN 0x4 +appcpu_iram_len = APPCPU_SRAM_SIZE; +appcpu_dram_len = APPCPU_SRAM_SIZE; + +/* Aliases */ +#define ROMABLE_REGION FLASH +#define RODATA_REGION dram0_1_seg /* drom0_1_seg */ +#define RAMABLE_REGION dram0_1_seg +#define IRAM_REGION iram0_1_seg + +/* Zephyr macro re-definitions */ +#undef GROUP_DATA_LINK_IN +#define GROUP_DATA_LINK_IN(vregion, lregion) > vregion AT > lregion + +#undef GROUP_NOLOAD_LINK_IN +#define GROUP_NOLOAD_LINK_IN(vregion, lregion) > vregion + +/* Flash segments (rodata and text) should be mapped in the virtual address spaces. + * Executing directly from LMA is not possible. */ +#undef GROUP_ROM_LINK_IN +#define GROUP_ROM_LINK_IN(vregion, lregion) > RODATA_REGION AT > lregion + +/* Make sure new sections have consistent alignment between input and output sections */ +#undef SECTION_DATA_PROLOGUE +#define SECTION_DATA_PROLOGUE(name, options, align) name options : ALIGN_WITH_INPUT + +#undef SECTION_PROLOGUE +#define SECTION_PROLOGUE SECTION_DATA_PROLOGUE MEMORY { - iram0_0_seg(RX): org = SRAM_IRAM_END - CONFIG_ESP32S3_APPCPU_IRAM, len = CONFIG_ESP32S3_APPCPU_IRAM - dram0_0_seg(RW): org = SRAM_DRAM_END - CONFIG_ESP32S3_APPCPU_DRAM, len = CONFIG_ESP32S3_APPCPU_DRAM +#ifdef CONFIG_BOOTLOADER_MCUBOOT + mcuboot_hdr (R): org = 0x0, len = 0x20 + metadata (R): org = 0x20, len = 0x20 + FLASH (R): org = 0x40, len = FLASH_SIZE - 0x40 +#else + /* Make safety margin in the FLASH memory size so the + * (esp_img_header + (n*esp_seg_headers)) would fit */ + FLASH (R): org = 0x0, len = FLASH_SIZE - 0x100 +#endif /* CONFIG_BOOTLOADER_MCUBOOT */ + + iram0_1_seg(RX): org = appcpu_iram_org, len = appcpu_iram_len + dram0_1_seg(RW): org = appcpu_dram_org, len = appcpu_dram_len + #ifdef CONFIG_GEN_ISR_TABLES IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000 #endif } /* Default entry point: */ -ENTRY(__app_cpu_start) +ENTRY(__appcpu_start) /* Used as a pointer to the heap end */ _heap_sentry = DRAM_RESERVED_START; SECTIONS { +#if defined(CONFIG_BOOTLOADER_MCUBOOT) + /* Reserve space for MCUboot header in the binary */ + .mcuboot_header : + { + QUAD(0x0) + QUAD(0x0) + QUAD(0x0) + QUAD(0x0) + } > mcuboot_hdr + /* Image load table */ + .metadata : + { + /* 0. Magic byte for load header */ + LONG(0xace637d3) + + /* 1. Application entry point address */ + KEEP(*(.entry_addr)) + + /* IRAM metadata: + * 2. Destination address (VMA) for IRAM region + * 3. Flash offset (LMA) for start of IRAM region + * 4. Size of IRAM region + */ + LONG(ADDR(.iram0.vectors)) + LONG(LOADADDR(.iram0.vectors)) + LONG(_iram_end - _init_start); + + /* DRAM metadata: + * 5. Destination address (VMA) for DRAM region + * 6. Flash offset (LMA) for start of DRAM region + * 7. Size of DRAM region + */ + LONG(ADDR(.dram0.data)) + LONG(LOADADDR(.dram0.data)) + LONG(_data_end - _data_start) + } > metadata +#endif /* CONFIG_BOOTLOADER_MCUBOOT */ + #include #ifdef CONFIG_LLEXT #include #endif - /* Send .iram0 code to iram */ + /* --- START OF IRAM --- */ + + /* Send .iram0 code to iram */ .iram0.vectors : ALIGN(4) { + _iram_start = ABSOLUTE(.); /* Vectors go to IRAM */ _init_start = ABSOLUTE(.); /* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */ @@ -83,15 +156,14 @@ SECTIONS *(.entry.text) *(.init.literal) *(.init) - . = ALIGN (4); + . = ALIGN (16); + _init_end = ABSOLUTE(.); - _iram_start = ABSOLUTE(.); - } GROUP_LINK_IN(IRAM_REGION) + } GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION) - SECTION_PROLOGUE(_TEXT_SECTION_NAME, , ALIGN(4)) + .iram0.text : ALIGN(4) { - /* Code marked as running out of IRAM */ _iram_text_start = ABSOLUTE(.); *(.iram1 .iram1.*) *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text) @@ -122,13 +194,104 @@ SECTIONS *libphy.a:(.phyiram .phyiram.*) *libgcov.a:(.literal .text .literal.* .text.*) + . = ALIGN(16); + + } GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION) + + .flash.text : ALIGN(16) + { + _stext = .; + _text_start = ABSOLUTE(.); + + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.fini.literal) + *(.fini) + *(.gnu.version) + *(.literal .text .literal.* .text.*) + + /* CPU will try to prefetch up to 16 bytes of + * of instructions. This means that any configuration (e.g. MMU, PMS) must allow + * safe access to up to 16 bytes after the last real instruction, add + * dummy bytes to ensure this + */ + . += 16; + + _text_end = ABSOLUTE(.); + _etext = .; + + /* Similar to _iram_start, this symbol goes here so it is + * resolved by addr2line in preference to the first symbol in + * the flash.text segment. + */ + . = ALIGN(4); + _flash_cache_start = ABSOLUTE(0); + . = ALIGN(4); _iram_end = ABSOLUTE(.); - . = ALIGN(4) + 16; - } GROUP_LINK_IN(IRAM_REGION) + } GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION) - SECTION_PROLOGUE(_RODATA_SECTION_NAME,,) + /* --- END OF IRAM --- */ + + /* --- START OF DRAM --- */ + + .dram0.dummy (NOLOAD): + { + . = ORIGIN(dram0_1_seg) + MAX(_iram_end, appcpu_iram_org) - appcpu_iram_org; + . = ALIGN(16); + } GROUP_LINK_IN(RAMABLE_REGION) + + .dram0.data : + { + . = ALIGN (8); + __data_start = ABSOLUTE(.); + _data_start = ABSOLUTE(.); + + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + *(.data1) + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + /* rodata for panic handler(libarch__xtensa__core.a) and all + * dependent functions should be placed in DRAM to avoid issue + * when flash cache is disabled */ + *libarch__xtensa__core.a:(.rodata .rodata.*) + *libkernel.a:fatal.*(.rodata .rodata.*) + *libkernel.a:init.*(.rodata .rodata.*) + *libzephyr.a:cbprintf_complete*(.rodata .rodata.*) + *libzephyr.a:systimer_hal.*(.rodata .rodata.*) + *libzephyr.a:log_core.*(.rodata .rodata.*) + *libzephyr.a:log_backend_uart.*(.rodata .rodata.*) + *libzephyr.a:log_output.*(.rodata .rodata.*) + *libzephyr.a:loader.*(.rodata .rodata.*) + *libdrivers__serial.a:uart_esp32.*(.rodata .rodata.*) + *libdrivers__flash.a:flash_esp32.*(.rodata .rodata.*) + + . = ALIGN(4); + #include + . = ALIGN(4); + + KEEP(*(.jcr)) + *(.dram1 .dram1.*) + . = ALIGN(16); + + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + + #include + #include + #include + #include + #include + #include + + /* SECTION_PROLOGUE(_RODATA_SECTION_NAME,,) */ + .dram0.rodata : ALIGN(4) { _rodata_start = ABSOLUTE(.); @@ -140,8 +303,29 @@ SECTIONS #include . = ALIGN(4); - *(EXCLUDE_FILE (*libarch__xtensa__core.a:* *libkernel.a:fatal.* *libkernel.a:init.* *libzephyr.a:cbprintf_complete* *libzephyr.a:log_core.* *libzephyr.a:log_backend_uart.* *libzephyr.a:log_output.* *libzephyr.a:loader.* *libdrivers__serial.a:uart_esp32.*) .rodata) - *(EXCLUDE_FILE (*libarch__xtensa__core.a:* *libkernel.a:fatal.* *libkernel.a:init.* *libzephyr.a:cbprintf_complete* *libzephyr.a:log_core.* *libzephyr.a:log_backend_uart.* *libzephyr.a:log_output.* *libzephyr.a:loader.* *libdrivers__serial.a:uart_esp32.*) .rodata.*) + *(EXCLUDE_FILE ( + *libarch__xtensa__core.a:* + *libkernel.a:fatal.* + *libkernel.a:init.* + *libzephyr.a:cbprintf_complete* + *libzephyr.a:log_core.* + *libzephyr.a:log_backend_uart.* + *libzephyr.a:log_output.* + *libzephyr.a:loader.* + *libdrivers__serial.a:uart_esp32.*) .rodata) + + *(EXCLUDE_FILE ( + *libarch__xtensa__core.a:* + *libkernel.a:fatal.* + *libkernel.a:init.* + *libzephyr.a:cbprintf_complete* + *libzephyr.a:log_core.* + *libzephyr.a:log_backend_uart.* + *libzephyr.a:log_output.* + *libzephyr.a:loader.* + *libdrivers__serial.a:uart_esp32.*) .rodata.*) + + . = ALIGN(4); *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ *(.gnu.linkonce.r.*) @@ -183,13 +367,15 @@ SECTIONS _thread_local_end = ABSOLUTE(.); _rodata_reserved_end = ABSOLUTE(.); . = ALIGN(4); - } GROUP_DATA_LINK_IN(RAMABLE_REGION, IRAM_REGION) + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) /* Flash segments (rodata and text) should be mapped in virtual address space by providing VMA. * Executing directly from LMA is not possible. */ #pragma push_macro("GROUP_ROM_LINK_IN") #undef GROUP_ROM_LINK_IN #define GROUP_ROM_LINK_IN(vregion, lregion) > RAMABLE_REGION AT > lregion + + #include #include #include #include @@ -197,78 +383,37 @@ SECTIONS #include #include #include + #include + #include + #pragma pop_macro("GROUP_ROM_LINK_IN") /* Create an explicit section at the end of all the data that shall be mapped into drom. * This is used to calculate the size of the _image_drom_size variable */ - SECTION_PROLOGUE(_RODATA_SECTION_END,,) + /* SECTION_PROLOGUE(_RODATA_SECTION_END,,) */ + .dram0.rodata_end : ALIGN(0x10) { . = ALIGN(16); _image_rodata_end = ABSOLUTE(.); - } GROUP_DATA_LINK_IN(RAMABLE_REGION, IRAM_REGION) + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) -#include - - .dram0.data : - { - . = ALIGN (8); - __data_start = ABSOLUTE(.); - - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - *(.data1) - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.sdata2) - *(.sdata2.*) - *(.gnu.linkonce.s2.*) - /* rodata for panic handler(libarch__xtensa__core.a) and all - * dependent functions should be placed in DRAM to avoid issue - * when flash cache is disabled */ - *libarch__xtensa__core.a:(.rodata .rodata.*) - *libkernel.a:fatal.*(.rodata .rodata.*) - *libkernel.a:init.*(.rodata .rodata.*) - *libzephyr.a:cbprintf_complete*(.rodata .rodata.*) - *libzephyr.a:systimer_hal.*(.rodata .rodata.*) - *libzephyr.a:log_core.*(.rodata .rodata.*) - *libzephyr.a:log_backend_uart.*(.rodata .rodata.*) - *libzephyr.a:log_output.*(.rodata .rodata.*) - *libzephyr.a:loader.*(.rodata .rodata.*) - *libdrivers__serial.a:uart_esp32.*(.rodata .rodata.*) - *libdrivers__flash.a:flash_esp32.*(.rodata .rodata.*) - - KEEP(*(.jcr)) - *(.dram1 .dram1.*) - . = ALIGN(4); - } GROUP_DATA_LINK_IN(RAMABLE_REGION, IRAM_REGION) - - #include - #include - #include - #include - #include - - /* logging sections should be placed in RAM area to avoid flash cache disabled issues */ - #pragma push_macro("GROUP_ROM_LINK_IN") - #undef GROUP_ROM_LINK_IN - #define GROUP_ROM_LINK_IN GROUP_DATA_LINK_IN - #include - #pragma pop_macro("GROUP_ROM_LINK_IN") .dram0.end : { - . = ALIGN(4); - - #include - - . = ALIGN(4); __data_end = ABSOLUTE(.); - } GROUP_DATA_LINK_IN(RAMABLE_REGION, IRAM_REGION) + _data_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + + .dram0.noinit (NOLOAD): + { + . = ALIGN(8); + *(.noinit) + *(.noinit.*) + . = ALIGN(8) ; + } GROUP_LINK_IN(RAMABLE_REGION) /* Shared RAM */ - SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),) + .dram0.bss (NOLOAD) : { . = ALIGN (8); _bss_start = ABSOLUTE(.); /* required by bluetooth library */ @@ -296,45 +441,15 @@ SECTIONS _image_ram_start = _iram_start - IRAM_DRAM_OFFSET; #include - ASSERT(((__bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), "DRAM segment data does not fit.") + ASSERT(((__bss_end - ORIGIN(dram0_1_seg)) <= LENGTH(dram0_1_seg)), "DRAM segment data does not fit.") - SECTION_DATA_PROLOGUE(_NOINIT_SECTION_NAME, (NOLOAD),) - { - . = ALIGN(8); - *(.noinit) - *(.noinit.*) - . = ALIGN(8) ; - } GROUP_LINK_IN(RAMABLE_REGION) + /* --- END OF DRAM --- */ - .flash.text : ALIGN(IROM_SEG_ALIGN) - { - _stext = .; - _text_start = ABSOLUTE(.); + /* --- START OF IROM --- */ + /* --- END OF IROM --- */ - *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ - *(.fini.literal) - *(.fini) - *(.gnu.version) - *(.literal .text .literal.* .text.*) - - /* CPU will try to prefetch up to 16 bytes of - * of instructions. This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += 16; - - _text_end = ABSOLUTE(.); - _etext = .; - - /* Similar to _iram_start, this symbol goes here so it is - * resolved by addr2line in preference to the first symbol in - * the flash.text segment. - */ - . = ALIGN(4); - _flash_cache_start = ABSOLUTE(0); - } GROUP_LINK_IN(IRAM_REGION) + /* --- START OF DROM --- */ + /* --- END OF DROM --- */ #ifdef CONFIG_GEN_ISR_TABLES #include @@ -375,8 +490,7 @@ SECTIONS KEEP (*(.xt.profile_files)) KEEP (*(.gnu.linkonce.xt.profile_files.*)) } - } -ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), +ASSERT(((_iram_end - ORIGIN(iram0_1_seg)) <= LENGTH(iram0_1_seg)), "IRAM0 segment data does not fit.") diff --git a/soc/espressif/esp32s3/esp32s3-mp.c b/soc/espressif/esp32s3/esp32s3-mp.c index 61e4d8d5812..8cae6d5e87c 100644 --- a/soc/espressif/esp32s3/esp32s3-mp.c +++ b/soc/espressif/esp32s3/esp32s3-mp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,19 +8,22 @@ #include #include #include +#include +#include #include #include -#include +#include "esp_rom_uart.h" -void smp_log(const char *msg) -{ - while (*msg) { - esp_rom_uart_tx_one_char(*msg++); - } - esp_rom_uart_tx_one_char('\r'); - esp_rom_uart_tx_one_char('\n'); -} +#include "esp_mcuboot_image.h" +#include "esp_memory_utils.h" + +#ifdef CONFIG_SOC_ENABLE_APPCPU + +#include "bootloader_flash_priv.h" + +#define sys_mmap bootloader_mmap +#define sys_munmap bootloader_munmap void esp_appcpu_start(void *entry_point) { @@ -35,7 +38,135 @@ void esp_appcpu_start(void *entry_point) esp_rom_ets_set_appcpu_boot_addr((void *)entry_point); - ets_delay_us(50000); - - smp_log("ESP32S3: CPU1 start sequence complete"); + esp_cpu_reset(1); } + +static int load_segment(uint32_t src_addr, uint32_t src_len, uint32_t dst_addr) +{ + const uint32_t *data = (const uint32_t *)sys_mmap(src_addr, src_len); + + if (!data) { + ets_printf("%s: mmap failed", __func__); + return -1; + } + + volatile uint32_t *dst = (volatile uint32_t *)dst_addr; + + for (int i = 0; i < src_len / 4; i++) { + dst[i] = data[i]; + } + + sys_munmap(data); + + return 0; +} + +int IRAM_ATTR esp_appcpu_image_load(unsigned int hdr_offset, unsigned int *entry_addr) +{ + const uint32_t img_off = FIXED_PARTITION_OFFSET(slot0_appcpu_partition); + const uint32_t fa_size = FIXED_PARTITION_SIZE(slot0_appcpu_partition); + const uint8_t fa_id = FIXED_PARTITION_ID(slot0_appcpu_partition); + int rc = 0; + + if (entry_addr == NULL) { + ets_printf("Can't return the entry address. Aborting!\n"); + abort(); + return -1; + } + + ets_printf("Loading appcpu image, area id: %d, offset: 0x%x, hdr.off: 0x%x, size: %d kB\n", + fa_id, img_off, hdr_offset, fa_size / 1024); + + uint32_t mcuboot_header[8] = {0}; + esp_image_load_header_t image_header = {0}; + + const uint32_t *data = (const uint32_t *)sys_mmap(img_off, 0x40); + + memcpy((void *)&mcuboot_header, data, sizeof(mcuboot_header)); + memcpy((void *)&image_header, data + (hdr_offset / sizeof(uint32_t)), + sizeof(esp_image_load_header_t)); + + sys_munmap(data); + + if (image_header.header_magic == ESP_LOAD_HEADER_MAGIC) { + ets_printf("MCUboot image format\n"); + } else if ((image_header.header_magic & 0xff) == 0xE9) { + ets_printf("ESP image format is not supported\n"); + abort(); + } else { + ets_printf("Unknown or empty image detected. Aborting!\n"); + abort(); + } + + if (!esp_ptr_in_iram((void *)image_header.iram_dest_addr) || + !esp_ptr_in_iram((void *)(image_header.iram_dest_addr + image_header.iram_size))) { + ets_printf("IRAM region in load header is not valid. Aborting"); + abort(); + } + + if (!esp_ptr_in_dram((void *)image_header.dram_dest_addr) || + !esp_ptr_in_dram((void *)(image_header.dram_dest_addr + image_header.dram_size))) { + ets_printf("DRAM region in load header is not valid. Aborting"); + abort(); + } + + if (!esp_ptr_in_iram((void *)image_header.entry_addr)) { + ets_printf("Application entry point (%xh) is not in IRAM. Aborting", + image_header.entry_addr); + abort(); + } + + ets_printf("IRAM segment: paddr=%08xh, vaddr=%08xh, size=%05xh (%6d) load\n", + (img_off + image_header.iram_flash_offset), image_header.iram_dest_addr, + image_header.iram_size, image_header.iram_size); + + load_segment(img_off + image_header.iram_flash_offset, image_header.iram_size, + image_header.iram_dest_addr); + + ets_printf("DRAM segment: paddr=%08xh, vaddr=%08xh, size=%05xh (%6d) load\n", + (img_off + image_header.dram_flash_offset), image_header.dram_dest_addr, + image_header.dram_size, image_header.dram_size); + + load_segment(img_off + image_header.dram_flash_offset, image_header.dram_size, + image_header.dram_dest_addr); + + ets_printf("Application start=%xh\n", image_header.entry_addr); + esp_rom_uart_tx_wait_idle(0); + + assert(entry_addr != NULL); + *entry_addr = image_header.entry_addr; + + return rc; +} + +void esp_appcpu_image_stop(void) +{ + esp_cpu_stall(1); +} + +void esp_appcpu_image_start(unsigned int hdr_offset) +{ + static int started; + unsigned int entry_addr = 0; + + if (started) { + printk("APPCPU already started.\r\n"); + return; + } + + /* Input image meta header, output appcpu entry point */ + esp_appcpu_image_load(hdr_offset, &entry_addr); + + esp_appcpu_start((void *)entry_addr); +} + +int esp_appcpu_init(void) +{ + /* Load APPCPU image using image header offset + * (skipping the MCUBoot header) + */ + esp_appcpu_image_start(0x20); + + return 0; +} +#endif /* CONFIG_SOC_ENABLE_APPCPU */ diff --git a/soc/espressif/esp32s3/memory.h b/soc/espressif/esp32s3/memory.h index 0283c51fe0d..f3e22a04513 100644 --- a/soc/espressif/esp32s3/memory.h +++ b/soc/espressif/esp32s3/memory.h @@ -4,17 +4,19 @@ */ #pragma once -/* SRAM0 (64k), SRAM1 (416k), SRAM2 (64k) memories +/* SRAM0 (32k), SRAM1 (416k), SRAM2 (64k) memories * Ibus and Dbus address space */ -#define SRAM0_IRAM_START 0x40370000 -#define SRAM0_SIZE 0x8000 -#define SRAM1_DRAM_START 0x3fc88000 +#define SRAM0_IRAM_START 0x40370000 +#define SRAM0_SIZE 0x8000 +#define SRAM1_DRAM_START 0x3fc88000 +#define SRAM1_IRAM_START 0x40378000 +#define SRAM_USER_IRAM_START (SRAM0_IRAM_START + CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE) -/* IRAM equivalent address where DRAM actually start */ -#define SRAM1_IRAM_START (SRAM0_IRAM_START + SRAM0_SIZE) -#define SRAM2_DRAM_START 0x3fcf0000 -#define SRAM2_SIZE 0x10000 +#define SRAM2_DRAM_START 0x3fcf0000 +#define SRAM2_SIZE 0x10000 +#define SRAM2_USER_DRAM_START (SRAM2_DRAM_START + CONFIG_ESP32S3_DATA_CACHE_SIZE) +#define SRAM2_USER_DRAM_SIZE (SRAM2_SIZE - CONFIG_ESP32S3_DATA_CACHE_SIZE) /** Simplified memory map for the bootloader. * Make sure the bootloader can load into main memory without overwriting itself. @@ -43,24 +45,51 @@ /* Set the limit for the application runtime dynamic allocations */ #define DRAM_RESERVED_START DRAM_BUFFERS_END -/* Base address used for calculating memory layout - * counted from Dbus backwards and back to the Ibus - */ -#define BOOTLOADER_USER_DRAM_END DRAM_BUFFERS_START - /* For safety margin between bootloader data section and startup stacks */ #define BOOTLOADER_STACK_OVERHEAD 0x0 #define BOOTLOADER_DRAM_SEG_LEN 0x15000 #define BOOTLOADER_IRAM_LOADER_SEG_LEN 0x1a00 #define BOOTLOADER_IRAM_SEG_LEN 0xc000 +/* Base address used for calculating memory layout + * counted from Dbus backwards and back to the Ibus + */ +#define BOOTLOADER_USER_DRAM_END (DRAM_BUFFERS_START - BOOTLOADER_STACK_OVERHEAD) + /* Start of the lower region is determined by region size and the end of the higher region */ -#define BOOTLOADER_IRAM_LOADER_SEG_START (BOOTLOADER_USER_DRAM_END - BOOTLOADER_STACK_OVERHEAD + \ - IRAM_DRAM_OFFSET - BOOTLOADER_IRAM_LOADER_SEG_LEN) +#define BOOTLOADER_IRAM_LOADER_SEG_START \ + (BOOTLOADER_USER_DRAM_END - BOOTLOADER_IRAM_LOADER_SEG_LEN + IRAM_DRAM_OFFSET) #define BOOTLOADER_IRAM_SEG_START (BOOTLOADER_IRAM_LOADER_SEG_START - BOOTLOADER_IRAM_SEG_LEN) #define BOOTLOADER_DRAM_SEG_END (BOOTLOADER_IRAM_SEG_START - IRAM_DRAM_OFFSET) #define BOOTLOADER_DRAM_SEG_START (BOOTLOADER_DRAM_SEG_END - BOOTLOADER_DRAM_SEG_LEN) +/* The "USER_IRAM_END" represents the end of staticaly allocated memory. + * This address is where 2nd stage bootloader starts allocating memory, + * and it should not be overlapped by the user image. + * When there is no 2nd stage bootloader the bootstrapping is done + * by the so-called SIMPLE_BOOT. + */ +#ifdef CONFIG_ESP_SIMPLE_BOOT +#define USER_DRAM_END BOOTLOADER_USER_DRAM_END +#else +#define USER_DRAM_END (BOOTLOADER_IRAM_LOADER_SEG_START - IRAM_DRAM_OFFSET) +#endif +#define USER_IRAM_END (USER_DRAM_END + IRAM_DRAM_OFFSET) + +/* AMP */ +#if defined(CONFIG_SOC_ENABLE_APPCPU) || defined(CONFIG_SOC_ESP32S3_APPCPU) +#define APPCPU_IRAM_SIZE CONFIG_ESP32S3_APPCPU_IRAM_SIZE +#define APPCPU_DRAM_SIZE CONFIG_ESP32S3_APPCPU_DRAM_SIZE +#define AMP_COMM_SIZE (0x4000 + 0x400) +#else +#define APPCPU_IRAM_SIZE 0 +#define APPCPU_DRAM_SIZE 0 +#define AMP_COMM_SIZE 0 +#endif + +#define APPCPU_SRAM_SIZE (APPCPU_IRAM_SIZE + APPCPU_DRAM_SIZE) +#define APPCPU_SRAM_TOTAL_SIZE (APPCPU_SRAM_SIZE + AMP_COMM_SIZE) + /* Flash */ #ifdef CONFIG_FLASH_SIZE #define FLASH_SIZE CONFIG_FLASH_SIZE @@ -74,12 +103,3 @@ #define IROM_SEG_LEN FLASH_SIZE #define DROM_SEG_ORG 0x3c000000 #define DROM_SEG_LEN FLASH_SIZE - -/* AMP */ -#ifdef CONFIG_SOC_ENABLE_APPCPU -#define APPCPU_IRAM_SIZE CONFIG_ESP32S3_APPCPU_IRAM -#define APPCPU_DRAM_SIZE CONFIG_ESP32S3_APPCPU_DRAM -#else -#define APPCPU_IRAM_SIZE 0 -#define APPCPU_DRAM_SIZE 0 -#endif diff --git a/soc/espressif/esp32s3/soc.c b/soc/espressif/esp32s3/soc.c index a1349b61db0..80a02696fe0 100644 --- a/soc/espressif/esp32s3/soc.c +++ b/soc/espressif/esp32s3/soc.c @@ -47,49 +47,14 @@ #include #include "esp_log.h" +#include +#include + #define TAG "boot.esp32s3" extern void z_prep_c(void); extern void esp_reset_reason_init(void); - -#ifdef CONFIG_SOC_ENABLE_APPCPU -extern const unsigned char esp32s3_appcpu_fw_array[]; - -void IRAM_ATTR esp_start_appcpu(void) -{ - esp_image_header_t *header = (esp_image_header_t *)&esp32s3_appcpu_fw_array[0]; - esp_image_segment_header_t *segment = - (esp_image_segment_header_t *)&esp32s3_appcpu_fw_array[sizeof(esp_image_header_t)]; - uint8_t *segment_payload; - uint32_t entry_addr = header->entry_addr; - uint32_t idx = sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t); - - for (int i = 0; i < header->segment_count; i++) { - segment_payload = (uint8_t *)&esp32s3_appcpu_fw_array[idx]; - - if (segment->load_addr >= SOC_IRAM_LOW && segment->load_addr < SOC_IRAM_HIGH) { - /* IRAM segment only accepts 4 byte access, avoid memcpy usage here */ - volatile uint32_t *src = (volatile uint32_t *)segment_payload; - volatile uint32_t *dst = (volatile uint32_t *)segment->load_addr; - - for (int i = 0; i < segment->data_len / 4; i++) { - dst[i] = src[i]; - } - - } else if (segment->load_addr >= SOC_DRAM_LOW && - segment->load_addr < SOC_DRAM_HIGH) { - memcpy((void *)segment->load_addr, (const void *)segment_payload, - segment->data_len); - } - - idx += segment->data_len; - segment = (esp_image_segment_header_t *)&esp32s3_appcpu_fw_array[idx]; - idx += sizeof(esp_image_segment_header_t); - } - - esp_appcpu_start((void *)entry_addr); -} -#endif /* CONFIG_SOC_ENABLE_APPCPU*/ +extern int esp_appcpu_init(void); #ifndef CONFIG_MCUBOOT /* @@ -175,11 +140,6 @@ void IRAM_ATTR __esp_platform_start(void) esp_init_psram(); #endif /* CONFIG_ESP_SPIRAM */ -#if CONFIG_SOC_ENABLE_APPCPU - /* start the ESP32S3 APP CPU */ - esp_start_appcpu(); -#endif - #endif /* !CONFIG_MCUBOOT */ esp_intr_initialize(); @@ -213,3 +173,8 @@ void sys_arch_reboot(int type) { esp_restart_noos(); } + +#if defined(CONFIG_SOC_ENABLE_APPCPU) && !defined(CONFIG_MCUBOOT) +extern int esp_appcpu_init(void); +SYS_INIT(esp_appcpu_init, POST_KERNEL, 50); +#endif diff --git a/soc/espressif/esp32s3/soc_appcpu.c b/soc/espressif/esp32s3/soc_appcpu.c index 6ca213557ce..a03304c8751 100644 --- a/soc/espressif/esp32s3/soc_appcpu.c +++ b/soc/espressif/esp32s3/soc_appcpu.c @@ -33,6 +33,11 @@ #include #include +#define HDR_ATTR __attribute__((section(".entry_addr"))) __attribute__((used)) + +void __appcpu_start(void); +static HDR_ATTR void (*_entry_point)(void) = &__appcpu_start; + extern void z_prep_c(void); static void core_intr_matrix_clear(void) @@ -44,7 +49,7 @@ static void core_intr_matrix_clear(void) } } -void IRAM_ATTR __app_cpu_start(void) +void IRAM_ATTR __appcpu_start(void) { extern uint32_t _init_start;