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 segments = 0;
|
||||||
unsigned int ram_segments = 0;
|
unsigned int ram_segments = 0;
|
||||||
|
|
||||||
/* Using already fetched bootloader image header from bootloader_init */
|
|
||||||
offset += sizeof(esp_image_header_t);
|
offset += sizeof(esp_image_header_t);
|
||||||
|
|
||||||
while (segments++ < 16) {
|
while (segments++ < 16) {
|
||||||
|
@ -223,7 +222,6 @@ void map_rom_segments(uint32_t app_drom_start, uint32_t app_drom_vaddr,
|
||||||
"IROM",
|
"IROM",
|
||||||
app_irom_start_aligned, app_irom_vaddr_aligned,
|
app_irom_start_aligned, app_irom_vaddr_aligned,
|
||||||
app_irom_size, app_irom_size);
|
app_irom_size, app_irom_size);
|
||||||
ets_printf("\n\r");
|
|
||||||
esp_rom_uart_tx_wait_idle(0);
|
esp_rom_uart_tx_wait_idle(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +246,7 @@ void __start(void)
|
||||||
}
|
}
|
||||||
#endif
|
#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,
|
map_rom_segments(_app_drom_start, _app_drom_vaddr, _app_drom_size,
|
||||||
_app_irom_start, _app_irom_vaddr, _app_irom_size);
|
_app_irom_start, _app_irom_vaddr, _app_irom_size);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -32,8 +32,7 @@ config ESP32_APPCPU_DRAM
|
||||||
config SOC_ENABLE_APPCPU
|
config SOC_ENABLE_APPCPU
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
depends on IPM && SOC_ESP32_PROCPU
|
depends on (IPM || MBOX) && SOC_ESP32_PROCPU
|
||||||
depends on MBOX && SOC_ESP32_PROCPU
|
|
||||||
help
|
help
|
||||||
This hidden configuration lets PROCPU core to map and start APPCPU whenever IPM is enabled.
|
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
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
if (CONFIG_SOC_ESP32S3_APPCPU)
|
if (CONFIG_SOC_ESP32S3_APPCPU)
|
||||||
zephyr_sources(soc_appcpu.c)
|
|
||||||
|
zephyr_sources(
|
||||||
|
soc_appcpu.c
|
||||||
|
)
|
||||||
|
|
||||||
else()
|
else()
|
||||||
|
|
||||||
zephyr_sources(
|
zephyr_sources(
|
||||||
soc.c
|
soc.c
|
||||||
soc_cache.c
|
soc_cache.c
|
||||||
esp32s3-mp.c
|
esp32s3-mp.c
|
||||||
../common/loader.c
|
../common/loader.c
|
||||||
)
|
)
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
zephyr_include_directories(.)
|
zephyr_include_directories(.)
|
||||||
|
@ -22,13 +28,24 @@ zephyr_library_sources_ifdef(CONFIG_POWEROFF poweroff.c)
|
||||||
# Get flash size to use in esptool as string
|
# Get flash size to use in esptool as string
|
||||||
math(EXPR esptoolpy_flashsize "${CONFIG_FLASH_SIZE} / 0x100000")
|
math(EXPR esptoolpy_flashsize "${CONFIG_FLASH_SIZE} / 0x100000")
|
||||||
|
|
||||||
# Make rom loader compatible binary file
|
# Get UART baudrate from DT
|
||||||
if(NOT CONFIG_BOOTLOADER_MCUBOOT)
|
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)
|
if(CONFIG_BUILD_OUTPUT_BIN)
|
||||||
|
|
||||||
set(ESPTOOL_PY ${ESP_IDF_PATH}/tools/esptool_py/esptool.py)
|
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 "")
|
set(ELF2IMAGE_ARG "")
|
||||||
if(NOT CONFIG_MCUBOOT)
|
if(NOT CONFIG_MCUBOOT)
|
||||||
|
@ -37,49 +54,35 @@ if(NOT CONFIG_BOOTLOADER_MCUBOOT)
|
||||||
|
|
||||||
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
|
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
|
||||||
COMMAND ${PYTHON_EXECUTABLE} ${ESPTOOL_PY}
|
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_mode dio --flash_freq 40m
|
||||||
--flash_size ${esptoolpy_flashsize}MB
|
--flash_size ${esptoolpy_flashsize}MB
|
||||||
-o ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin
|
-o ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin
|
||||||
${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.elf)
|
${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.elf)
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
## When building for APPCPU
|
# Select the image origin depending on the boot configuration
|
||||||
if(CONFIG_SOC_ESP32S3_APPCPU)
|
if(CONFIG_SOC_ESP32S3_APPCPU)
|
||||||
|
dt_nodelabel(dts_partition_path NODELABEL "slot0_appcpu_partition")
|
||||||
if(CONFIG_BUILD_OUTPUT_BIN)
|
elseif(CONFIG_MCUBOOT)
|
||||||
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
|
dt_nodelabel(dts_partition_path NODELABEL "boot_partition")
|
||||||
COMMAND ${PYTHON_EXECUTABLE} ${ESP_IDF_PATH}/tools/esp_bin2c_array.py
|
elseif(CONFIG_ESP_SIMPLE_BOOT)
|
||||||
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 "boot_partition")
|
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()
|
else()
|
||||||
board_finalize_runner_args(esp32 "--esp-app-address=${boot_off}")
|
dt_nodelabel(dts_partition_path NODELABEL "slot0_partition")
|
||||||
endif()
|
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)
|
if(CONFIG_MCUBOOT)
|
||||||
# search from cross references between bootloader sections
|
|
||||||
message("check_callgraph using: ${ESP_IDF_PATH}/tools/ci/check_callgraph.py")
|
message("check_callgraph using: ${ESP_IDF_PATH}/tools/ci/check_callgraph.py")
|
||||||
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
|
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
|
||||||
COMMAND
|
COMMAND
|
||||||
|
|
|
@ -14,28 +14,6 @@ config SOC_SERIES_ESP32S3
|
||||||
|
|
||||||
if 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"
|
menu "Cache config"
|
||||||
|
|
||||||
choice ESP32S3_INSTRUCTION_CACHE_SIZE
|
choice ESP32S3_INSTRUCTION_CACHE_SIZE
|
||||||
|
@ -178,4 +156,6 @@ config MAC_BB_PD
|
||||||
|
|
||||||
endmenu # Cache config
|
endmenu # Cache config
|
||||||
|
|
||||||
|
rsource "Kconfig.amp"
|
||||||
|
|
||||||
endif # SOC_SERIES_ESP32S3
|
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
|
config FLASH_BASE_ADDRESS
|
||||||
default $(dt_node_reg_addr_hex,/soc/flash-controller@60002000/flash@0)
|
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
|
endif # SOC_SERIES_ESP32S3
|
||||||
|
|
|
@ -10,24 +10,16 @@
|
||||||
|
|
||||||
#include "memory.h"
|
#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 available SRAM memory segments */
|
||||||
user_dram_seg_org = SRAM1_DRAM_START;
|
amp_total_size = APPCPU_SRAM_TOTAL_SIZE;
|
||||||
user_iram_seg_org = SRAM0_IRAM_START + CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE;
|
procpu_iram_end = USER_IRAM_END - APPCPU_SRAM_TOTAL_SIZE;
|
||||||
user_dram_end = BOOTLOADER_IRAM_LOADER_SEG_START - IRAM_DRAM_OFFSET;
|
procpu_dram_end = USER_DRAM_END - APPCPU_SRAM_TOTAL_SIZE;
|
||||||
user_idram_size = user_dram_end - SRAM1_DRAM_START;
|
|
||||||
sram0_iram_size = SRAM0_SIZE - CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE;
|
procpu_iram_org = SRAM_USER_IRAM_START;
|
||||||
user_iram_seg_len = user_idram_size + sram0_iram_size;
|
procpu_iram_len = procpu_iram_end - procpu_iram_org;
|
||||||
user_dram_seg_len = user_idram_size;
|
|
||||||
|
procpu_dram_org = SRAM1_DRAM_START;
|
||||||
|
procpu_dram_len = procpu_dram_end - procpu_dram_org;
|
||||||
|
|
||||||
/* Aliases */
|
/* Aliases */
|
||||||
#define FLASH_CODE_REGION irom0_0_seg
|
#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 RAMABLE_REGION dram0_0_seg
|
||||||
#define ROMABLE_REGION FLASH
|
#define ROMABLE_REGION FLASH
|
||||||
|
|
||||||
|
/* Zephyr macro re-definitions */
|
||||||
#undef GROUP_DATA_LINK_IN
|
#undef GROUP_DATA_LINK_IN
|
||||||
#define GROUP_DATA_LINK_IN(vregion, lregion) > vregion AT > lregion
|
#define GROUP_DATA_LINK_IN(vregion, lregion) > vregion AT > lregion
|
||||||
|
|
||||||
|
@ -66,14 +59,13 @@ MEMORY
|
||||||
FLASH (R): org = 0x0, len = FLASH_SIZE - 0x100
|
FLASH (R): org = 0x0, len = FLASH_SIZE - 0x100
|
||||||
#endif /* CONFIG_BOOTLOADER_MCUBOOT */
|
#endif /* CONFIG_BOOTLOADER_MCUBOOT */
|
||||||
|
|
||||||
iram0_0_seg(RX): org = user_iram_seg_org, len = user_iram_seg_len - APPCPU_IRAM_SIZE
|
iram0_0_seg(RX): org = procpu_iram_org, len = procpu_iram_len
|
||||||
dram0_0_seg(RW): org = user_dram_seg_org, len = user_dram_seg_len - APPCPU_DRAM_SIZE
|
dram0_0_seg(RW): org = procpu_dram_org, len = procpu_dram_len
|
||||||
|
|
||||||
irom0_0_seg(RX): org = IROM_SEG_ORG, len = IROM_SEG_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
|
drom0_0_seg(R): org = DROM_SEG_ORG, len = DROM_SEG_LEN
|
||||||
|
|
||||||
/**
|
/* The `ext_ram_seg` and `drom0_0_seg` share the same bus and the address region.
|
||||||
* `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`
|
* A dummy section is used to avoid overlap. See `.ext_ram.dummy` in `sections.ld.in`
|
||||||
*/
|
*/
|
||||||
#if defined(CONFIG_ESP_SPIRAM)
|
#if defined(CONFIG_ESP_SPIRAM)
|
||||||
|
@ -101,7 +93,11 @@ MEMORY
|
||||||
ENTRY(CONFIG_KERNEL_ENTRY)
|
ENTRY(CONFIG_KERNEL_ENTRY)
|
||||||
|
|
||||||
/* Used as a pointer to the heap end */
|
/* Used as a pointer to the heap end */
|
||||||
|
#ifdef CONFIG_SOC_ENABLE_APPCPU
|
||||||
|
_heap_sentry = procpu_dram_end;
|
||||||
|
#else
|
||||||
_heap_sentry = DRAM_RESERVED_START;
|
_heap_sentry = DRAM_RESERVED_START;
|
||||||
|
#endif
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
|
@ -116,6 +112,7 @@ SECTIONS
|
||||||
QUAD(0x0)
|
QUAD(0x0)
|
||||||
QUAD(0x0)
|
QUAD(0x0)
|
||||||
} > mcuboot_hdr
|
} > mcuboot_hdr
|
||||||
|
/* Image load table */
|
||||||
.metadata :
|
.metadata :
|
||||||
{
|
{
|
||||||
/* 0. Magic byte for load header */
|
/* 0. Magic byte for load header */
|
||||||
|
@ -144,7 +141,6 @@ SECTIONS
|
||||||
} > metadata
|
} > metadata
|
||||||
#endif /* CONFIG_BOOTLOADER_MCUBOOT */
|
#endif /* CONFIG_BOOTLOADER_MCUBOOT */
|
||||||
|
|
||||||
|
|
||||||
/* Virtual non-loadable sections */
|
/* Virtual non-loadable sections */
|
||||||
#include <zephyr/linker/rel-sections.ld>
|
#include <zephyr/linker/rel-sections.ld>
|
||||||
|
|
||||||
|
@ -275,7 +271,9 @@ SECTIONS
|
||||||
*(.entry.text)
|
*(.entry.text)
|
||||||
*(.init.literal)
|
*(.init.literal)
|
||||||
*(.init)
|
*(.init)
|
||||||
|
|
||||||
_init_end = ABSOLUTE(.);
|
_init_end = ABSOLUTE(.);
|
||||||
|
|
||||||
} GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION)
|
} GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION)
|
||||||
|
|
||||||
.iram0.text : ALIGN(4)
|
.iram0.text : ALIGN(4)
|
||||||
|
@ -310,6 +308,11 @@ SECTIONS
|
||||||
*libphy.a:(.phyiram .phyiram.*)
|
*libphy.a:(.phyiram .phyiram.*)
|
||||||
*libgcov.a:(.literal .text .literal.* .text.*)
|
*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] */
|
/* [mapping:esp_psram] */
|
||||||
*libzephyr.a:mmu_psram_flash.*(.literal .literal.* .text .text.*)
|
*libzephyr.a:mmu_psram_flash.*(.literal .literal.* .text .text.*)
|
||||||
*libzephyr.a:esp_psram_impl_quad.*(.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.*)
|
*libzephyr.a:esp_mmu_map.*(.rodata .rodata.*)
|
||||||
*libdrivers__interrupt_controller.a:(.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] */
|
/* [mapping:esp_psram] */
|
||||||
*libzephyr.a:mmu_psram_flash.*(.rodata .rodata.*)
|
*libzephyr.a:mmu_psram_flash.*(.rodata .rodata.*)
|
||||||
*libzephyr.a:esp_psram_impl_octal.*(.rodata .rodata.*)
|
*libzephyr.a:esp_psram_impl_octal.*(.rodata .rodata.*)
|
||||||
|
@ -798,6 +806,10 @@ SECTIONS
|
||||||
|
|
||||||
} GROUP_DATA_LINK_IN(FLASH_CODE_REGION, ROMABLE_REGION)
|
} 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.
|
/* This dummy section represents the .flash.text section but in default_rodata_seg.
|
||||||
* Thus, it must have its alignment and (at least) its size.
|
* Thus, it must have its alignment and (at least) its size.
|
||||||
*/
|
*/
|
||||||
|
@ -879,6 +891,10 @@ SECTIONS
|
||||||
_image_rodata_end = ABSOLUTE(.);
|
_image_rodata_end = ABSOLUTE(.);
|
||||||
} GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION)
|
} 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`
|
* This section is required to skip flash rodata sections, because `ext_ram_seg`
|
||||||
* and `drom0_0_seg` are on the same bus
|
* and `drom0_0_seg` are on the same bus
|
||||||
|
@ -907,8 +923,9 @@ SECTIONS
|
||||||
|
|
||||||
#endif /* CONFIG_ESP_SPIRAM */
|
#endif /* CONFIG_ESP_SPIRAM */
|
||||||
|
|
||||||
/* --- XTENSA GLUE AND DEBUG BEGIN --- */
|
/* --- END OF SPIRAM --- */
|
||||||
|
|
||||||
|
/* --- XTENSA GLUE AND DEBUG BEGIN --- */
|
||||||
#ifdef CONFIG_GEN_ISR_TABLES
|
#ifdef CONFIG_GEN_ISR_TABLES
|
||||||
#include <zephyr/linker/intlist.ld>
|
#include <zephyr/linker/intlist.ld>
|
||||||
#endif
|
#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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -8,48 +8,121 @@
|
||||||
#include <zephyr/linker/linker-defs.h>
|
#include <zephyr/linker/linker-defs.h>
|
||||||
#include <zephyr/linker/linker-tool.h>
|
#include <zephyr/linker/linker-tool.h>
|
||||||
|
|
||||||
#define SRAM_IRAM_START 0x40370000
|
#include "memory.h"
|
||||||
#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
|
|
||||||
|
|
||||||
#define SRAM_DRAM_START 0x3FC88000
|
/* User available SRAM memory segments */
|
||||||
#define SRAM_DRAM_END (SRAM_IRAM_END - I_D_SRAM_OFFSET)
|
appcpu_iram_end = USER_IRAM_END;
|
||||||
|
appcpu_dram_end = USER_DRAM_END;
|
||||||
|
|
||||||
#define IRAM_REGION iram0_0_seg
|
appcpu_iram_org = appcpu_iram_end - APPCPU_SRAM_SIZE;
|
||||||
#define RAMABLE_REGION dram0_0_seg
|
appcpu_dram_org = appcpu_dram_end - APPCPU_SRAM_SIZE;
|
||||||
#define ROMABLE_REGION iram0_0_seg
|
|
||||||
|
|
||||||
#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
|
MEMORY
|
||||||
{
|
{
|
||||||
iram0_0_seg(RX): org = SRAM_IRAM_END - CONFIG_ESP32S3_APPCPU_IRAM, len = CONFIG_ESP32S3_APPCPU_IRAM
|
#ifdef CONFIG_BOOTLOADER_MCUBOOT
|
||||||
dram0_0_seg(RW): org = SRAM_DRAM_END - CONFIG_ESP32S3_APPCPU_DRAM, len = CONFIG_ESP32S3_APPCPU_DRAM
|
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
|
#ifdef CONFIG_GEN_ISR_TABLES
|
||||||
IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000
|
IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Default entry point: */
|
/* Default entry point: */
|
||||||
ENTRY(__app_cpu_start)
|
ENTRY(__appcpu_start)
|
||||||
|
|
||||||
/* Used as a pointer to the heap end */
|
/* Used as a pointer to the heap end */
|
||||||
_heap_sentry = DRAM_RESERVED_START;
|
_heap_sentry = DRAM_RESERVED_START;
|
||||||
|
|
||||||
SECTIONS
|
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>
|
#include <zephyr/linker/rel-sections.ld>
|
||||||
|
|
||||||
#ifdef CONFIG_LLEXT
|
#ifdef CONFIG_LLEXT
|
||||||
#include <zephyr/linker/llext-sections.ld>
|
#include <zephyr/linker/llext-sections.ld>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* --- START OF IRAM --- */
|
||||||
|
|
||||||
/* Send .iram0 code to iram */
|
/* Send .iram0 code to iram */
|
||||||
.iram0.vectors : ALIGN(4)
|
.iram0.vectors : ALIGN(4)
|
||||||
{
|
{
|
||||||
|
_iram_start = ABSOLUTE(.);
|
||||||
/* Vectors go to IRAM */
|
/* Vectors go to IRAM */
|
||||||
_init_start = ABSOLUTE(.);
|
_init_start = ABSOLUTE(.);
|
||||||
/* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */
|
/* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */
|
||||||
|
@ -83,15 +156,14 @@ SECTIONS
|
||||||
*(.entry.text)
|
*(.entry.text)
|
||||||
*(.init.literal)
|
*(.init.literal)
|
||||||
*(.init)
|
*(.init)
|
||||||
. = ALIGN (4);
|
. = ALIGN (16);
|
||||||
|
|
||||||
_init_end = ABSOLUTE(.);
|
_init_end = ABSOLUTE(.);
|
||||||
|
|
||||||
_iram_start = ABSOLUTE(.);
|
} GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION)
|
||||||
} GROUP_LINK_IN(IRAM_REGION)
|
|
||||||
|
|
||||||
SECTION_PROLOGUE(_TEXT_SECTION_NAME, , ALIGN(4))
|
.iram0.text : ALIGN(4)
|
||||||
{
|
{
|
||||||
/* Code marked as running out of IRAM */
|
|
||||||
_iram_text_start = ABSOLUTE(.);
|
_iram_text_start = ABSOLUTE(.);
|
||||||
*(.iram1 .iram1.*)
|
*(.iram1 .iram1.*)
|
||||||
*(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text)
|
*(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text)
|
||||||
|
@ -122,13 +194,104 @@ SECTIONS
|
||||||
*libphy.a:(.phyiram .phyiram.*)
|
*libphy.a:(.phyiram .phyiram.*)
|
||||||
*libgcov.a:(.literal .text .literal.* .text.*)
|
*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);
|
. = ALIGN(4);
|
||||||
_iram_end = ABSOLUTE(.);
|
_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(.);
|
_rodata_start = ABSOLUTE(.);
|
||||||
|
|
||||||
|
@ -140,8 +303,29 @@ SECTIONS
|
||||||
#include <snippets-rodata.ld>
|
#include <snippets-rodata.ld>
|
||||||
|
|
||||||
. = ALIGN(4);
|
. = 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 (
|
||||||
*(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.*)
|
*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 */
|
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
|
||||||
*(.gnu.linkonce.r.*)
|
*(.gnu.linkonce.r.*)
|
||||||
|
@ -183,13 +367,15 @@ SECTIONS
|
||||||
_thread_local_end = ABSOLUTE(.);
|
_thread_local_end = ABSOLUTE(.);
|
||||||
_rodata_reserved_end = ABSOLUTE(.);
|
_rodata_reserved_end = ABSOLUTE(.);
|
||||||
. = ALIGN(4);
|
. = 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.
|
/* Flash segments (rodata and text) should be mapped in virtual address space by providing VMA.
|
||||||
* Executing directly from LMA is not possible. */
|
* Executing directly from LMA is not possible. */
|
||||||
#pragma push_macro("GROUP_ROM_LINK_IN")
|
#pragma push_macro("GROUP_ROM_LINK_IN")
|
||||||
#undef GROUP_ROM_LINK_IN
|
#undef GROUP_ROM_LINK_IN
|
||||||
#define GROUP_ROM_LINK_IN(vregion, lregion) > RAMABLE_REGION AT > lregion
|
#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-init.ld>
|
||||||
#include <zephyr/linker/common-rom/common-rom-kernel-devices.ld>
|
#include <zephyr/linker/common-rom/common-rom-kernel-devices.ld>
|
||||||
#include <zephyr/linker/common-rom/common-rom-ztest.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-bt.ld>
|
||||||
#include <zephyr/linker/common-rom/common-rom-debug.ld>
|
#include <zephyr/linker/common-rom/common-rom-debug.ld>
|
||||||
#include <zephyr/linker/common-rom/common-rom-misc.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")
|
#pragma pop_macro("GROUP_ROM_LINK_IN")
|
||||||
|
|
||||||
/* Create an explicit section at the end of all the data that shall be mapped into drom.
|
/* 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 */
|
* 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);
|
. = ALIGN(16);
|
||||||
_image_rodata_end = ABSOLUTE(.);
|
_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 :
|
.dram0.end :
|
||||||
{
|
{
|
||||||
. = ALIGN(4);
|
|
||||||
|
|
||||||
#include <snippets-rwdata.ld>
|
|
||||||
|
|
||||||
. = ALIGN(4);
|
|
||||||
__data_end = ABSOLUTE(.);
|
__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 */
|
/* Shared RAM */
|
||||||
SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
|
.dram0.bss (NOLOAD) :
|
||||||
{
|
{
|
||||||
. = ALIGN (8);
|
. = ALIGN (8);
|
||||||
_bss_start = ABSOLUTE(.); /* required by bluetooth library */
|
_bss_start = ABSOLUTE(.); /* required by bluetooth library */
|
||||||
|
@ -296,45 +441,15 @@ SECTIONS
|
||||||
_image_ram_start = _iram_start - IRAM_DRAM_OFFSET;
|
_image_ram_start = _iram_start - IRAM_DRAM_OFFSET;
|
||||||
#include <zephyr/linker/ram-end.ld>
|
#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),)
|
/* --- END OF DRAM --- */
|
||||||
{
|
|
||||||
. = ALIGN(8);
|
|
||||||
*(.noinit)
|
|
||||||
*(.noinit.*)
|
|
||||||
. = ALIGN(8) ;
|
|
||||||
} GROUP_LINK_IN(RAMABLE_REGION)
|
|
||||||
|
|
||||||
.flash.text : ALIGN(IROM_SEG_ALIGN)
|
/* --- START OF IROM --- */
|
||||||
{
|
/* --- END OF IROM --- */
|
||||||
_stext = .;
|
|
||||||
_text_start = ABSOLUTE(.);
|
|
||||||
|
|
||||||
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
/* --- START OF DROM --- */
|
||||||
*(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
|
/* --- END OF DROM --- */
|
||||||
*(.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)
|
|
||||||
|
|
||||||
#ifdef CONFIG_GEN_ISR_TABLES
|
#ifdef CONFIG_GEN_ISR_TABLES
|
||||||
#include <zephyr/linker/intlist.ld>
|
#include <zephyr/linker/intlist.ld>
|
||||||
|
@ -375,8 +490,7 @@ SECTIONS
|
||||||
KEEP (*(.xt.profile_files))
|
KEEP (*(.xt.profile_files))
|
||||||
KEEP (*(.gnu.linkonce.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.")
|
"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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
@ -8,19 +8,22 @@
|
||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
#include <zephyr/spinlock.h>
|
#include <zephyr/spinlock.h>
|
||||||
#include <zephyr/kernel_structs.h>
|
#include <zephyr/kernel_structs.h>
|
||||||
|
#include <zephyr/storage/flash_map.h>
|
||||||
|
#include <zephyr/drivers/interrupt_controller/intc_esp32.h>
|
||||||
|
|
||||||
#include <soc.h>
|
#include <soc.h>
|
||||||
#include <esp_cpu.h>
|
#include <esp_cpu.h>
|
||||||
#include <zephyr/drivers/interrupt_controller/intc_esp32.h>
|
#include "esp_rom_uart.h"
|
||||||
|
|
||||||
void smp_log(const char *msg)
|
#include "esp_mcuboot_image.h"
|
||||||
{
|
#include "esp_memory_utils.h"
|
||||||
while (*msg) {
|
|
||||||
esp_rom_uart_tx_one_char(*msg++);
|
#ifdef CONFIG_SOC_ENABLE_APPCPU
|
||||||
}
|
|
||||||
esp_rom_uart_tx_one_char('\r');
|
#include "bootloader_flash_priv.h"
|
||||||
esp_rom_uart_tx_one_char('\n');
|
|
||||||
}
|
#define sys_mmap bootloader_mmap
|
||||||
|
#define sys_munmap bootloader_munmap
|
||||||
|
|
||||||
void esp_appcpu_start(void *entry_point)
|
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);
|
esp_rom_ets_set_appcpu_boot_addr((void *)entry_point);
|
||||||
|
|
||||||
ets_delay_us(50000);
|
esp_cpu_reset(1);
|
||||||
|
|
||||||
smp_log("ESP32S3: CPU1 start sequence complete");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
#pragma once
|
||||||
|
|
||||||
/* SRAM0 (64k), SRAM1 (416k), SRAM2 (64k) memories
|
/* SRAM0 (32k), SRAM1 (416k), SRAM2 (64k) memories
|
||||||
* Ibus and Dbus address space
|
* Ibus and Dbus address space
|
||||||
*/
|
*/
|
||||||
#define SRAM0_IRAM_START 0x40370000
|
#define SRAM0_IRAM_START 0x40370000
|
||||||
#define SRAM0_SIZE 0x8000
|
#define SRAM0_SIZE 0x8000
|
||||||
#define SRAM1_DRAM_START 0x3fc88000
|
#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_DRAM_START 0x3fcf0000
|
||||||
#define SRAM2_SIZE 0x10000
|
#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.
|
/** Simplified memory map for the bootloader.
|
||||||
* Make sure the bootloader can load into main memory without overwriting itself.
|
* 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 */
|
/* Set the limit for the application runtime dynamic allocations */
|
||||||
#define DRAM_RESERVED_START DRAM_BUFFERS_END
|
#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 */
|
/* For safety margin between bootloader data section and startup stacks */
|
||||||
#define BOOTLOADER_STACK_OVERHEAD 0x0
|
#define BOOTLOADER_STACK_OVERHEAD 0x0
|
||||||
#define BOOTLOADER_DRAM_SEG_LEN 0x15000
|
#define BOOTLOADER_DRAM_SEG_LEN 0x15000
|
||||||
#define BOOTLOADER_IRAM_LOADER_SEG_LEN 0x1a00
|
#define BOOTLOADER_IRAM_LOADER_SEG_LEN 0x1a00
|
||||||
#define BOOTLOADER_IRAM_SEG_LEN 0xc000
|
#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 */
|
/* 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 + \
|
#define BOOTLOADER_IRAM_LOADER_SEG_START \
|
||||||
IRAM_DRAM_OFFSET - BOOTLOADER_IRAM_LOADER_SEG_LEN)
|
(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_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_END (BOOTLOADER_IRAM_SEG_START - IRAM_DRAM_OFFSET)
|
||||||
#define BOOTLOADER_DRAM_SEG_START (BOOTLOADER_DRAM_SEG_END - BOOTLOADER_DRAM_SEG_LEN)
|
#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 */
|
/* Flash */
|
||||||
#ifdef CONFIG_FLASH_SIZE
|
#ifdef CONFIG_FLASH_SIZE
|
||||||
#define FLASH_SIZE CONFIG_FLASH_SIZE
|
#define FLASH_SIZE CONFIG_FLASH_SIZE
|
||||||
|
@ -74,12 +103,3 @@
|
||||||
#define IROM_SEG_LEN FLASH_SIZE
|
#define IROM_SEG_LEN FLASH_SIZE
|
||||||
#define DROM_SEG_ORG 0x3c000000
|
#define DROM_SEG_ORG 0x3c000000
|
||||||
#define DROM_SEG_LEN FLASH_SIZE
|
#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 <zephyr/sys/printk.h>
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
#include <zephyr/drivers/flash.h>
|
||||||
|
#include <zephyr/storage/flash_map.h>
|
||||||
|
|
||||||
#define TAG "boot.esp32s3"
|
#define TAG "boot.esp32s3"
|
||||||
|
|
||||||
extern void z_prep_c(void);
|
extern void z_prep_c(void);
|
||||||
extern void esp_reset_reason_init(void);
|
extern void esp_reset_reason_init(void);
|
||||||
|
extern int esp_appcpu_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*/
|
|
||||||
|
|
||||||
#ifndef CONFIG_MCUBOOT
|
#ifndef CONFIG_MCUBOOT
|
||||||
/*
|
/*
|
||||||
|
@ -175,11 +140,6 @@ void IRAM_ATTR __esp_platform_start(void)
|
||||||
esp_init_psram();
|
esp_init_psram();
|
||||||
#endif /* CONFIG_ESP_SPIRAM */
|
#endif /* CONFIG_ESP_SPIRAM */
|
||||||
|
|
||||||
#if CONFIG_SOC_ENABLE_APPCPU
|
|
||||||
/* start the ESP32S3 APP CPU */
|
|
||||||
esp_start_appcpu();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* !CONFIG_MCUBOOT */
|
#endif /* !CONFIG_MCUBOOT */
|
||||||
|
|
||||||
esp_intr_initialize();
|
esp_intr_initialize();
|
||||||
|
@ -213,3 +173,8 @@ void sys_arch_reboot(int type)
|
||||||
{
|
{
|
||||||
esp_restart_noos();
|
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_app_format.h>
|
||||||
#include <esp_clk_internal.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);
|
extern void z_prep_c(void);
|
||||||
|
|
||||||
static void core_intr_matrix_clear(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;
|
extern uint32_t _init_start;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue