soc: esp32s3: AMP support
Updates and fixes to support APPCPU. - fix ld scripts - fix and update memory layout - fix build issues - fix sysbuild Signed-off-by: Marek Matej <marek.matej@espressif.com>
This commit is contained in:
parent
82eb8a1fb6
commit
ed1179713c
12 changed files with 557 additions and 291 deletions
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
# Select the image origin depending on the boot configuration
|
||||
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
|
||||
dt_nodelabel(dts_partition_path NODELABEL "slot0_appcpu_partition")
|
||||
elseif(CONFIG_MCUBOOT)
|
||||
dt_nodelabel(dts_partition_path NODELABEL "boot_partition")
|
||||
elseif(CONFIG_ESP_SIMPLE_BOOT)
|
||||
dt_nodelabel(dts_partition_path NODELABEL "boot_partition")
|
||||
dt_reg_addr(boot_off PATH ${dts_partition_path})
|
||||
|
||||
# Get code-partition slot0 address
|
||||
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}")
|
||||
dt_nodelabel(dts_partition_path NODELABEL "slot0_partition")
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
31
soc/espressif/esp32s3/Kconfig.amp
Normal file
31
soc/espressif/esp32s3/Kconfig.amp
Normal file
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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,7 +93,11 @@ 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
|
||||
{
|
||||
|
@ -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 <zephyr/linker/rel-sections.ld>
|
||||
|
||||
|
@ -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 <zephyr/linker/intlist.ld>
|
||||
#endif
|
||||
|
|
|
@ -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 <zephyr/linker/linker-defs.h>
|
||||
#include <zephyr/linker/linker-tool.h>
|
||||
|
||||
#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 <zephyr/linker/rel-sections.ld>
|
||||
|
||||
#ifdef CONFIG_LLEXT
|
||||
#include <zephyr/linker/llext-sections.ld>
|
||||
#endif
|
||||
|
||||
/* --- 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 <snippets-rwdata.ld>
|
||||
. = ALIGN(4);
|
||||
|
||||
KEEP(*(.jcr))
|
||||
*(.dram1 .dram1.*)
|
||||
. = ALIGN(16);
|
||||
|
||||
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
|
||||
|
||||
#include <snippets-data-sections.ld>
|
||||
#include <zephyr/linker/common-ram.ld>
|
||||
#include <snippets-ram-sections.ld>
|
||||
#include <zephyr/linker/cplusplus-ram.ld>
|
||||
#include <zephyr/linker/kobject-data.ld>
|
||||
#include <zephyr/linker/common-rom/common-rom-logging.ld>
|
||||
|
||||
/* SECTION_PROLOGUE(_RODATA_SECTION_NAME,,) */
|
||||
.dram0.rodata : ALIGN(4)
|
||||
{
|
||||
_rodata_start = ABSOLUTE(.);
|
||||
|
||||
|
@ -140,8 +303,29 @@ SECTIONS
|
|||
#include <snippets-rodata.ld>
|
||||
|
||||
. = 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 <zephyr/linker/cplusplus-rom.ld>
|
||||
#include <zephyr/linker/common-rom/common-rom-init.ld>
|
||||
#include <zephyr/linker/common-rom/common-rom-kernel-devices.ld>
|
||||
#include <zephyr/linker/common-rom/common-rom-ztest.ld>
|
||||
|
@ -197,78 +383,37 @@ SECTIONS
|
|||
#include <zephyr/linker/common-rom/common-rom-bt.ld>
|
||||
#include <zephyr/linker/common-rom/common-rom-debug.ld>
|
||||
#include <zephyr/linker/common-rom/common-rom-misc.ld>
|
||||
#include <zephyr/linker/thread-local-storage.ld>
|
||||
#include <snippets-sections.ld>
|
||||
|
||||
#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 <snippets-sections.ld>
|
||||
|
||||
.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 <zephyr/linker/cplusplus-rom.ld>
|
||||
#include <snippets-data-sections.ld>
|
||||
#include <zephyr/linker/common-ram.ld>
|
||||
#include <snippets-ram-sections.ld>
|
||||
#include <zephyr/linker/cplusplus-ram.ld>
|
||||
|
||||
/* 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 <zephyr/linker/common-rom/common-rom-logging.ld>
|
||||
#pragma pop_macro("GROUP_ROM_LINK_IN")
|
||||
|
||||
.dram0.end :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
|
||||
#include <snippets-rwdata.ld>
|
||||
|
||||
. = 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 <zephyr/linker/ram-end.ld>
|
||||
|
||||
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 <zephyr/linker/intlist.ld>
|
||||
|
@ -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.")
|
||||
|
|
|
@ -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 <zephyr/kernel.h>
|
||||
#include <zephyr/spinlock.h>
|
||||
#include <zephyr/kernel_structs.h>
|
||||
#include <zephyr/storage/flash_map.h>
|
||||
#include <zephyr/drivers/interrupt_controller/intc_esp32.h>
|
||||
|
||||
#include <soc.h>
|
||||
#include <esp_cpu.h>
|
||||
#include <zephyr/drivers/interrupt_controller/intc_esp32.h>
|
||||
#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 */
|
||||
|
|
|
@ -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 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_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
|
||||
|
|
|
@ -47,49 +47,14 @@
|
|||
#include <zephyr/sys/printk.h>
|
||||
#include "esp_log.h"
|
||||
|
||||
#include <zephyr/drivers/flash.h>
|
||||
#include <zephyr/storage/flash_map.h>
|
||||
|
||||
#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
|
||||
|
|
|
@ -33,6 +33,11 @@
|
|||
#include <esp_app_format.h>
|
||||
#include <esp_clk_internal.h>
|
||||
|
||||
#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;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue