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:
Marek Matej 2024-09-04 14:28:07 +02:00 committed by Mahesh Mahadevan
commit ed1179713c
12 changed files with 557 additions and 291 deletions

View file

@ -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

View file

@ -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.

View file

@ -1,14 +1,20 @@
# SPDX-License-Identifier: Apache-2.0
if (CONFIG_SOC_ESP32S3_APPCPU)
zephyr_sources(soc_appcpu.c)
zephyr_sources(
soc_appcpu.c
)
else()
zephyr_sources(
soc.c
soc_cache.c
esp32s3-mp.c
../common/loader.c
)
endif()
zephyr_include_directories(.)
@ -22,13 +28,24 @@ zephyr_library_sources_ifdef(CONFIG_POWEROFF poweroff.c)
# Get flash size to use in esptool as string
math(EXPR esptoolpy_flashsize "${CONFIG_FLASH_SIZE} / 0x100000")
# Make rom loader compatible binary file
if(NOT CONFIG_BOOTLOADER_MCUBOOT)
# Get UART baudrate from DT
dt_chosen(dts_shell_uart PROPERTY "zephyr,shell-uart")
if(${dts_shell_uart})
dt_prop(monitor_baud PATH ${dts_shell_uart} PROPERTY "current-speed")
endif()
board_runner_args(esp32 "--esp-monitor-baud=${monitor_baud}")
message("-- Espressif HAL path: ${ESP_IDF_PATH}")
# Select image processing
if(CONFIG_ESP_SIMPLE_BOOT OR CONFIG_MCUBOOT)
if(CONFIG_BUILD_OUTPUT_BIN)
set(ESPTOOL_PY ${ESP_IDF_PATH}/tools/esptool_py/esptool.py)
message("esptool path: ${ESPTOOL_PY}")
message("-- Use the esptool.py: ${ESPTOOL_PY}")
set(ELF2IMAGE_ARG "")
if(NOT CONFIG_MCUBOOT)
@ -37,49 +54,35 @@ if(NOT CONFIG_BOOTLOADER_MCUBOOT)
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
COMMAND ${PYTHON_EXECUTABLE} ${ESPTOOL_PY}
ARGS --chip esp32s3 elf2image ${ELF2IMAGE_ARG}
ARGS --chip ${CONFIG_SOC} elf2image ${ELF2IMAGE_ARG}
--flash_mode dio --flash_freq 40m
--flash_size ${esptoolpy_flashsize}MB
-o ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin
${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.elf)
endif()
endif()
## When building for APPCPU
if (CONFIG_SOC_ESP32S3_APPCPU)
if(CONFIG_BUILD_OUTPUT_BIN)
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
COMMAND ${PYTHON_EXECUTABLE} ${ESP_IDF_PATH}/tools/esp_bin2c_array.py
ARGS -i ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin
-o ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.c
-a "esp32s3_appcpu_fw_array")
endif()
else()
## Building for PROCPU
set_property(TARGET bintools PROPERTY disassembly_flag_inline_source)
# Get code-partition boot address
# Select the image origin depending on the boot configuration
if(CONFIG_SOC_ESP32S3_APPCPU)
dt_nodelabel(dts_partition_path NODELABEL "slot0_appcpu_partition")
elseif(CONFIG_MCUBOOT)
dt_nodelabel(dts_partition_path NODELABEL "boot_partition")
dt_reg_addr(boot_off PATH ${dts_partition_path})
# Get code-partition slot0 address
elseif(CONFIG_ESP_SIMPLE_BOOT)
dt_nodelabel(dts_partition_path NODELABEL "boot_partition")
else()
dt_nodelabel(dts_partition_path NODELABEL "slot0_partition")
dt_reg_addr(img_0_off PATH ${dts_partition_path})
if(CONFIG_BOOTLOADER_MCUBOOT)
board_finalize_runner_args(esp32 "--esp-app-address=${img_0_off}")
else()
board_finalize_runner_args(esp32 "--esp-app-address=${boot_off}")
endif()
endif()
dt_reg_addr(image_off PATH ${dts_partition_path})
board_finalize_runner_args(esp32 "--esp-app-address=${image_off}")
message("-- Image partition ${dts_partition_path}")
# Look for cross references between bootloader sections
if(CONFIG_MCUBOOT)
# search from cross references between bootloader sections
message("check_callgraph using: ${ESP_IDF_PATH}/tools/ci/check_callgraph.py")
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
COMMAND

View file

@ -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

View 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

View file

@ -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

View file

@ -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

View file

@ -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.")

View file

@ -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 */

View file

@ -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

View file

@ -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

View file

@ -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;