soc: esp32s3: add esp32s3_appcpu for AMP support
Adds esp32s3_appcpu SoC and update default esp32s3 SoC to support AMP feature. Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
This commit is contained in:
parent
df64ae2d2d
commit
bdda8ac48e
16 changed files with 769 additions and 30 deletions
|
@ -328,6 +328,11 @@ static void esp32_clock_perip_init(void)
|
||||||
#if defined(CONFIG_SOC_SERIES_ESP32S3)
|
#if defined(CONFIG_SOC_SERIES_ESP32S3)
|
||||||
static void esp32_clock_perip_init(void)
|
static void esp32_clock_perip_init(void)
|
||||||
{
|
{
|
||||||
|
#if defined(CONFIG_SOC_ESP32S3_APPCPU)
|
||||||
|
/* skip APPCPU configuration */
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
uint32_t common_perip_clk, hwcrypto_perip_clk, wifi_bt_sdio_clk = 0;
|
uint32_t common_perip_clk, hwcrypto_perip_clk, wifi_bt_sdio_clk = 0;
|
||||||
uint32_t common_perip_clk1 = 0;
|
uint32_t common_perip_clk1 = 0;
|
||||||
|
|
||||||
|
|
|
@ -54,9 +54,17 @@ IRAM_ATTR static void esp32_ipm_isr(const struct device *dev)
|
||||||
|
|
||||||
/* clear interrupt flag */
|
/* clear interrupt flag */
|
||||||
if (core_id == 0) {
|
if (core_id == 0) {
|
||||||
|
#if defined(CONFIG_SOC_SERIES_ESP32) || defined(CONFIG_SOC_SERIES_ESP32_NET)
|
||||||
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, 0);
|
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, 0);
|
||||||
|
#elif defined(CONFIG_SOC_SERIES_ESP32S3)
|
||||||
|
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_0_REG, 0);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
#if defined(CONFIG_SOC_SERIES_ESP32) || defined(CONFIG_SOC_SERIES_ESP32_NET)
|
||||||
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, 0);
|
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, 0);
|
||||||
|
#elif defined(CONFIG_SOC_SERIES_ESP32S3)
|
||||||
|
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_1_REG, 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* first of all take the own of the shared memory */
|
/* first of all take the own of the shared memory */
|
||||||
|
@ -130,12 +138,21 @@ static int esp32_ipm_send(const struct device *dev, int wait, uint32_t id,
|
||||||
memcpy(dev_data->shm.app_cpu_shm, data, size);
|
memcpy(dev_data->shm.app_cpu_shm, data, size);
|
||||||
atomic_set(&dev_data->control->lock, ESP32_IPM_LOCK_FREE_VAL);
|
atomic_set(&dev_data->control->lock, ESP32_IPM_LOCK_FREE_VAL);
|
||||||
LOG_DBG("Generating interrupt on remote CPU 1 from CPU 0");
|
LOG_DBG("Generating interrupt on remote CPU 1 from CPU 0");
|
||||||
|
#if defined(CONFIG_SOC_SERIES_ESP32) || defined(CONFIG_SOC_SERIES_ESP32_NET)
|
||||||
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, DPORT_CPU_INTR_FROM_CPU_1);
|
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, DPORT_CPU_INTR_FROM_CPU_1);
|
||||||
|
#elif defined(CONFIG_SOC_SERIES_ESP32S3)
|
||||||
|
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_1_REG, SYSTEM_CPU_INTR_FROM_CPU_1);
|
||||||
|
#endif
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
memcpy(dev_data->shm.pro_cpu_shm, data, size);
|
memcpy(dev_data->shm.pro_cpu_shm, data, size);
|
||||||
atomic_set(&dev_data->control->lock, ESP32_IPM_LOCK_FREE_VAL);
|
atomic_set(&dev_data->control->lock, ESP32_IPM_LOCK_FREE_VAL);
|
||||||
LOG_DBG("Generating interrupt on remote CPU 0 from CPU 1");
|
LOG_DBG("Generating interrupt on remote CPU 0 from CPU 1");
|
||||||
|
#if defined(CONFIG_SOC_SERIES_ESP32) || defined(CONFIG_SOC_SERIES_ESP32_NET)
|
||||||
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, DPORT_CPU_INTR_FROM_CPU_0);
|
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, DPORT_CPU_INTR_FROM_CPU_0);
|
||||||
|
#elif defined(CONFIG_SOC_SERIES_ESP32S3)
|
||||||
|
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_0_REG, SYSTEM_CPU_INTR_FROM_CPU_0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
|
@ -217,7 +234,6 @@ static int esp32_ipm_init(const struct device *dev)
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
LOG_DBG("Waiting CPU0 to sync");
|
LOG_DBG("Waiting CPU0 to sync");
|
||||||
|
|
||||||
while (!atomic_cas(&data->control->lock,
|
while (!atomic_cas(&data->control->lock,
|
||||||
ESP32_IPM_LOCK_FREE_VAL, data->this_core_id))
|
ESP32_IPM_LOCK_FREE_VAL, data->this_core_id))
|
||||||
;
|
;
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <soc.h>
|
#include <soc.h>
|
||||||
#include <zephyr/drivers/uart.h>
|
#include <zephyr/drivers/uart.h>
|
||||||
#if defined(CONFIG_SOC_ESP32C3)
|
#if defined(CONFIG_SOC_SERIES_ESP32C3)
|
||||||
#include <zephyr/drivers/interrupt_controller/intc_esp32c3.h>
|
#include <zephyr/drivers/interrupt_controller/intc_esp32c3.h>
|
||||||
#else
|
#else
|
||||||
#include <zephyr/drivers/interrupt_controller/intc_esp32.h>
|
#include <zephyr/drivers/interrupt_controller/intc_esp32.h>
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
#include <zephyr/sys/util.h>
|
#include <zephyr/sys/util.h>
|
||||||
#include <esp_attr.h>
|
#include <esp_attr.h>
|
||||||
|
|
||||||
#ifdef CONFIG_SOC_ESP32C3
|
#ifdef CONFIG_SOC_SERIES_ESP32C3
|
||||||
#define ISR_HANDLER isr_handler_t
|
#define ISR_HANDLER isr_handler_t
|
||||||
#else
|
#else
|
||||||
#define ISR_HANDLER intr_handler_t
|
#define ISR_HANDLER intr_handler_t
|
||||||
|
|
7
dts/xtensa/espressif/esp32s3/esp32s3_appcpu.dtsi
Normal file
7
dts/xtensa/espressif/esp32s3/esp32s3_appcpu.dtsi
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "esp32s3_common.dtsi"
|
|
@ -58,6 +58,16 @@
|
||||||
reg = <0x3fc88000 0x77FFF>;
|
reg = <0x3fc88000 0x77FFF>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ipmmem0: memory@3fcbd000 {
|
||||||
|
compatible = "mmio-sram";
|
||||||
|
reg = <0x3fcbd000 0x400>;
|
||||||
|
};
|
||||||
|
|
||||||
|
shm0: memory@3fcbd400 {
|
||||||
|
compatible = "mmio-sram";
|
||||||
|
reg = <0x3fcbd400 0x4000>;
|
||||||
|
};
|
||||||
|
|
||||||
intc: interrupt-controller@600c2000 {
|
intc: interrupt-controller@600c2000 {
|
||||||
#interrupt-cells = <1>;
|
#interrupt-cells = <1>;
|
||||||
compatible = "espressif,esp32-intc";
|
compatible = "espressif,esp32-intc";
|
||||||
|
@ -107,6 +117,16 @@
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ipm0: ipm@3fcc1400 {
|
||||||
|
compatible = "espressif,esp32-ipm";
|
||||||
|
reg = <0x3fcc1400 0x8>;
|
||||||
|
status = "disabled";
|
||||||
|
shared-memory = <&ipmmem0>;
|
||||||
|
shared-memory-size = <0x400>;
|
||||||
|
interrupts = <FROM_CPU_INTR0_SOURCE FROM_CPU_INTR1_SOURCE>;
|
||||||
|
interrupt-parent = <&intc>;
|
||||||
|
};
|
||||||
|
|
||||||
uart0: uart@60000000 {
|
uart0: uart@60000000 {
|
||||||
compatible = "espressif,esp32-uart";
|
compatible = "espressif,esp32-uart";
|
||||||
reg = <0x60000000 0x1000>;
|
reg = <0x60000000 0x1000>;
|
||||||
|
|
|
@ -1,21 +1,18 @@
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
zephyr_sources(
|
if (CONFIG_SOC_ESP32S3_APPCPU)
|
||||||
soc.c
|
zephyr_sources(soc_appcpu.c)
|
||||||
soc_cache.c
|
else()
|
||||||
loader.c
|
zephyr_sources(
|
||||||
)
|
soc.c
|
||||||
|
soc_cache.c
|
||||||
|
loader.c
|
||||||
|
esp32s3-mp.c
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
zephyr_library_sources_ifdef(CONFIG_NEWLIB_LIBC newlib_fix.c)
|
zephyr_library_sources_ifdef(CONFIG_NEWLIB_LIBC newlib_fix.c)
|
||||||
|
|
||||||
# get code-partition slot0 address
|
|
||||||
dt_nodelabel(dts_partition_path NODELABEL "slot0_partition")
|
|
||||||
dt_reg_addr(img_0_off PATH ${dts_partition_path})
|
|
||||||
|
|
||||||
# get code-partition boot address
|
|
||||||
dt_nodelabel(dts_partition_path NODELABEL "boot_partition")
|
|
||||||
dt_reg_addr(boot_off PATH ${dts_partition_path})
|
|
||||||
|
|
||||||
# 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")
|
||||||
|
|
||||||
|
@ -87,8 +84,31 @@ if(CONFIG_MCUBOOT OR CONFIG_BOOTLOADER_ESP_IDF)
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set_property(TARGET bintools PROPERTY disassembly_flag_inline_source)
|
## When building for APPCPU
|
||||||
|
if (CONFIG_SOC_ESP32S3_APPCPU)
|
||||||
|
|
||||||
board_finalize_runner_args(esp32 "--esp-boot-address=${boot_off}")
|
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()
|
||||||
|
|
||||||
board_finalize_runner_args(esp32 "--esp-app-address=${img_0_off}")
|
else()
|
||||||
|
|
||||||
|
set_property(TARGET bintools PROPERTY disassembly_flag_inline_source)
|
||||||
|
|
||||||
|
# get code-partition slot0 address
|
||||||
|
dt_nodelabel(dts_partition_path NODELABEL "slot0_partition")
|
||||||
|
dt_reg_addr(img_0_off PATH ${dts_partition_path})
|
||||||
|
|
||||||
|
# get code-partition boot address
|
||||||
|
dt_nodelabel(dts_partition_path NODELABEL "boot_partition")
|
||||||
|
dt_reg_addr(boot_off PATH ${dts_partition_path})
|
||||||
|
|
||||||
|
board_finalize_runner_args(esp32 "--esp-boot-address=${boot_off}")
|
||||||
|
|
||||||
|
board_finalize_runner_args(esp32 "--esp-app-address=${img_0_off}")
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
|
@ -12,5 +12,17 @@ config SOC_SERIES_ESP32S3
|
||||||
select XIP if !MCUBOOT
|
select XIP if !MCUBOOT
|
||||||
select HAS_ESPRESSIF_HAL
|
select HAS_ESPRESSIF_HAL
|
||||||
select CPU_HAS_FPU
|
select CPU_HAS_FPU
|
||||||
|
|
||||||
|
config SOC_ESP32S3_PROCPU
|
||||||
|
bool "Application runs in ESP32S3 PROCPU (core 0)"
|
||||||
|
depends on SOC_SERIES_ESP32S3
|
||||||
help
|
help
|
||||||
Enable support for Espressif ESP32-S3
|
When this SOC is enabled, it will run application on PROCPU (core 0). It will automatically
|
||||||
|
enable AMP support by building, flashing and loading APPCPU (core 1) image if exists.
|
||||||
|
|
||||||
|
config SOC_ESP32S3_APPCPU
|
||||||
|
bool "Application runs in ESP32S3 APPCPU (core 1)"
|
||||||
|
depends on SOC_SERIES_ESP32S3
|
||||||
|
help
|
||||||
|
When this SOC is enabled, it will run application on APPCPU (core 1). It is expected that
|
||||||
|
there is another image running on PROCPU (core 0) to trigger the AMP support.
|
||||||
|
|
|
@ -13,11 +13,8 @@ config SOC_TOOLCHAIN_NAME
|
||||||
|
|
||||||
choice SOC_PART_NUMBER
|
choice SOC_PART_NUMBER
|
||||||
prompt "ESP32-S3 SOC Selection"
|
prompt "ESP32-S3 SOC Selection"
|
||||||
depends on SOC_SERIES_ESP32S3
|
|
||||||
|
|
||||||
# SoC with/without embedded flash
|
# SoC with/without embedded flash
|
||||||
config SOC_ESP32S3
|
|
||||||
bool "ESP32S3"
|
|
||||||
config SOC_ESP32S3_R2
|
config SOC_ESP32S3_R2
|
||||||
bool "ESP32S3_R2"
|
bool "ESP32S3_R2"
|
||||||
config SOC_ESP32S3_R8
|
config SOC_ESP32S3_R8
|
||||||
|
@ -50,6 +47,20 @@ choice SOC_PART_NUMBER
|
||||||
|
|
||||||
endchoice # SOC_PART_NUMBER
|
endchoice # SOC_PART_NUMBER
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
choice ESP32S3_RTC_CLK_SRC
|
choice ESP32S3_RTC_CLK_SRC
|
||||||
prompt "RTC clock source"
|
prompt "RTC clock source"
|
||||||
default ESP32S3_RTC_CLK_SRC_INT_RC
|
default ESP32S3_RTC_CLK_SRC_INT_RC
|
||||||
|
|
|
@ -57,6 +57,14 @@
|
||||||
#define IROM_SEG_LEN FLASH_SIZE
|
#define IROM_SEG_LEN FLASH_SIZE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_SOC_ESP32S3_PROCPU
|
||||||
|
#define APPCPU_IRAM_SIZE CONFIG_ESP32S3_APPCPU_IRAM
|
||||||
|
#define APPCPU_DRAM_SIZE CONFIG_ESP32S3_APPCPU_DRAM
|
||||||
|
#else
|
||||||
|
#define APPCPU_IRAM_SIZE 0x0
|
||||||
|
#define APPCPU_DRAM_SIZE 0x0
|
||||||
|
#endif
|
||||||
|
|
||||||
#define IROM_SEG_ALIGN 0x10000
|
#define IROM_SEG_ALIGN 0x10000
|
||||||
|
|
||||||
/* 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.
|
||||||
|
@ -69,9 +77,10 @@ MEMORY
|
||||||
mcuboot_hdr (RX): org = 0x0, len = 0x20
|
mcuboot_hdr (RX): org = 0x0, len = 0x20
|
||||||
metadata (RX): org = 0x20, len = 0x20
|
metadata (RX): org = 0x20, len = 0x20
|
||||||
ROM (RX): org = 0x40, len = FLASH_SIZE - 0x40
|
ROM (RX): org = 0x40, len = FLASH_SIZE - 0x40
|
||||||
iram0_0_seg(RX): org = SRAM_IRAM_ORG, len = SRAM_IRAM_SIZE
|
iram0_0_seg(RX): org = SRAM_IRAM_ORG, len = SRAM_IRAM_SIZE - APPCPU_IRAM_SIZE
|
||||||
|
dram0_0_seg(RW): org = SRAM_DRAM_ORG, len = DRAM0_0_SEG_LEN - APPCPU_DRAM_SIZE
|
||||||
|
|
||||||
irom0_0_seg(RX): org = IROM_SEG_ORG, len = IROM_SEG_LEN
|
irom0_0_seg(RX): org = IROM_SEG_ORG, len = IROM_SEG_LEN
|
||||||
dram0_0_seg(RW): org = SRAM_DRAM_ORG, len = DRAM0_0_SEG_LEN
|
|
||||||
|
|
||||||
/* DROM is the first segment placed in generated binary.
|
/* DROM is the first segment placed in generated binary.
|
||||||
* MCUboot binary for ESP32 has image header of 0x20 bytes.
|
* MCUboot binary for ESP32 has image header of 0x20 bytes.
|
||||||
|
@ -86,6 +95,7 @@ MEMORY
|
||||||
#if defined(CONFIG_ESP_SPIRAM)
|
#if defined(CONFIG_ESP_SPIRAM)
|
||||||
ext_ram_seg(RWX): org = EXT_RAM_ORG, len = CONFIG_ESP_SPIRAM_SIZE
|
ext_ram_seg(RWX): org = EXT_RAM_ORG, len = CONFIG_ESP_SPIRAM_SIZE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* RTC fast memory (executable). Persists over deep sleep.
|
/* RTC fast memory (executable). Persists over deep sleep.
|
||||||
*/
|
*/
|
||||||
rtc_iram_seg(RWX): org = 0x600fe000, len = 0x2000
|
rtc_iram_seg(RWX): org = 0x600fe000, len = 0x2000
|
||||||
|
|
372
soc/xtensa/espressif_esp32/esp32s3/default_appcpu.ld
Normal file
372
soc/xtensa/espressif_esp32/esp32s3/default_appcpu.ld
Normal file
|
@ -0,0 +1,372 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/devicetree.h>
|
||||||
|
#include <zephyr/linker/sections.h>
|
||||||
|
#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 SRAM_DRAM_START 0x3FC88000
|
||||||
|
#define SRAM_DRAM_END (SRAM_IRAM_END - I_D_SRAM_OFFSET)
|
||||||
|
|
||||||
|
#define IRAM_REGION iram0_0_seg
|
||||||
|
#define RAMABLE_REGION dram0_0_seg
|
||||||
|
#define ROMABLE_REGION iram0_0_seg
|
||||||
|
|
||||||
|
#define IROM_SEG_ALIGN 0x4
|
||||||
|
|
||||||
|
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_GEN_ISR_TABLES
|
||||||
|
IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Default entry point: */
|
||||||
|
ENTRY(__app_cpu_start)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
#include <zephyr/linker/rel-sections.ld>
|
||||||
|
|
||||||
|
/* Send .iram0 code to iram */
|
||||||
|
.iram0.vectors : ALIGN(4)
|
||||||
|
{
|
||||||
|
/* Vectors go to IRAM */
|
||||||
|
_init_start = ABSOLUTE(.);
|
||||||
|
/* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */
|
||||||
|
. = 0x0;
|
||||||
|
KEEP(*(.WindowVectors.text));
|
||||||
|
. = 0x180;
|
||||||
|
KEEP(*(.Level2InterruptVector.text));
|
||||||
|
. = 0x1c0;
|
||||||
|
KEEP(*(.Level3InterruptVector.text));
|
||||||
|
. = 0x200;
|
||||||
|
KEEP(*(.Level4InterruptVector.text));
|
||||||
|
. = 0x240;
|
||||||
|
KEEP(*(.Level5InterruptVector.text));
|
||||||
|
. = 0x280;
|
||||||
|
KEEP(*(.DebugExceptionVector.text));
|
||||||
|
. = 0x2c0;
|
||||||
|
KEEP(*(.NMIExceptionVector.text));
|
||||||
|
. = 0x300;
|
||||||
|
KEEP(*(.KernelExceptionVector.text));
|
||||||
|
. = 0x340;
|
||||||
|
KEEP(*(.UserExceptionVector.text));
|
||||||
|
. = 0x3C0;
|
||||||
|
KEEP(*(.DoubleExceptionVector.text));
|
||||||
|
. = 0x400;
|
||||||
|
_invalid_pc_placeholder = ABSOLUTE(.);
|
||||||
|
*(.*Vector.literal)
|
||||||
|
|
||||||
|
*(.UserEnter.literal);
|
||||||
|
*(.UserEnter.text);
|
||||||
|
. = ALIGN (16);
|
||||||
|
*(.entry.text)
|
||||||
|
*(.init.literal)
|
||||||
|
*(.init)
|
||||||
|
. = ALIGN (4);
|
||||||
|
_init_end = ABSOLUTE(.);
|
||||||
|
|
||||||
|
_iram_start = ABSOLUTE(.);
|
||||||
|
} GROUP_LINK_IN(IRAM_REGION)
|
||||||
|
|
||||||
|
SECTION_PROLOGUE(_TEXT_SECTION_NAME, , 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)
|
||||||
|
*libesp32.a:panic.*(.literal .text .literal.* .text.*)
|
||||||
|
*librtc.a:(.literal .text .literal.* .text.*)
|
||||||
|
*libarch__xtensa__core.a:(.literal .text .literal.* .text.*)
|
||||||
|
*libkernel.a:(.literal .text .literal.* .text.*)
|
||||||
|
*libsoc.a:rtc_*.*(.literal .text .literal.* .text.*)
|
||||||
|
*libsoc.a:cpu_util.*(.literal .text .literal.* .text.*)
|
||||||
|
*libgcc.a:lib2funcs.*(.literal .text .literal.* .text.*)
|
||||||
|
*libdrivers__flash.a:flash_esp32.*(.literal .text .literal.* .text.*)
|
||||||
|
*libzephyr.a:windowspill_asm.*(.literal .text .literal.* .text.*)
|
||||||
|
*libzephyr.a:log_noos.*(.literal .text .literal.* .text.*)
|
||||||
|
*libdrivers__timer.a:xtensa_sys_timer.*(.literal .text .literal.* .text.*)
|
||||||
|
*libzephyr.a:systimer_hal.*(.literal .text .literal.* .text.*)
|
||||||
|
*libzephyr.a:log_core.*(.literal .text .literal.* .text.*)
|
||||||
|
*libzephyr.a:cbprintf_complete.*(.literal .text .literal.* .text.*)
|
||||||
|
*libzephyr.a:printk.*(.literal.printk .literal.vprintk .literal.char_out .text.printk .text.vprintk .text.char_out)
|
||||||
|
*libzephyr.a:log_msg.*(.literal .text .literal.* .text.*)
|
||||||
|
*libzephyr.a:log_list.*(.literal .text .literal.* .text.*)
|
||||||
|
*libdrivers__console.a:uart_console.*(.literal.console_out .text.console_out)
|
||||||
|
*libzephyr.a:log_output.*(.literal .text .literal.* .text.*)
|
||||||
|
*libzephyr.a:log_backend_uart.*(.literal .text .literal.* .text.*)
|
||||||
|
*libzephyr.a:loader.*(.literal .text .literal.* .text.*)
|
||||||
|
*liblib__libc__minimal.a:string.*(.literal .text .literal.* .text.*)
|
||||||
|
*liblib__libc__newlib.a:string.*(.literal .text .literal.* .text.*)
|
||||||
|
*libc.a:*(.literal .text .literal.* .text.*)
|
||||||
|
*libphy.a:(.phyiram .phyiram.*)
|
||||||
|
*libgcov.a:(.literal .text .literal.* .text.*)
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_iram_end = ABSOLUTE(.);
|
||||||
|
. = ALIGN(4) + 16;
|
||||||
|
|
||||||
|
} GROUP_LINK_IN(IRAM_REGION)
|
||||||
|
|
||||||
|
SECTION_PROLOGUE(_RODATA_SECTION_NAME,,)
|
||||||
|
{
|
||||||
|
_rodata_start = ABSOLUTE(.);
|
||||||
|
|
||||||
|
*(.rodata_desc .rodata_desc.*) /* Should be the first. App version info. DO NOT PUT ANYTHING BEFORE IT! */
|
||||||
|
*(.rodata_custom_desc .rodata_custom_desc.*) /* Should be the second. Custom app version info. DO NOT PUT ANYTHING BEFORE IT! */
|
||||||
|
|
||||||
|
__rodata_region_start = ABSOLUTE(.);
|
||||||
|
. = ALIGN(4);
|
||||||
|
#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.*)
|
||||||
|
|
||||||
|
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
|
||||||
|
*(.gnu.linkonce.r.*)
|
||||||
|
*(.rodata1)
|
||||||
|
__XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
|
||||||
|
*(.xt_except_table)
|
||||||
|
*(.gcc_except_table .gcc_except_table.*)
|
||||||
|
*(.gnu.linkonce.e.*)
|
||||||
|
*(.gnu.version_r)
|
||||||
|
. = (. + 3) & ~ 3;
|
||||||
|
__eh_frame = ABSOLUTE(.);
|
||||||
|
KEEP(*(.eh_frame))
|
||||||
|
. = (. + 7) & ~ 3;
|
||||||
|
|
||||||
|
/* C++ exception handlers table: */
|
||||||
|
__XT_EXCEPTION_DESCS_ = ABSOLUTE(.);
|
||||||
|
*(.xt_except_desc)
|
||||||
|
*(.gnu.linkonce.h.*)
|
||||||
|
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
|
||||||
|
*(.xt_except_desc_end)
|
||||||
|
*(.dynamic)
|
||||||
|
*(.gnu.version_d)
|
||||||
|
. = ALIGN(4);
|
||||||
|
__rodata_region_end = ABSOLUTE(.);
|
||||||
|
/* Literals are also RO data. */
|
||||||
|
_lit4_start = ABSOLUTE(.);
|
||||||
|
*(*.lit4)
|
||||||
|
*(.lit4.*)
|
||||||
|
*(.gnu.linkonce.lit4.*)
|
||||||
|
_lit4_end = ABSOLUTE(.);
|
||||||
|
. = ALIGN(4);
|
||||||
|
_thread_local_start = ABSOLUTE(.);
|
||||||
|
*(.tdata)
|
||||||
|
*(.tdata.*)
|
||||||
|
*(.tbss)
|
||||||
|
*(.tbss.*)
|
||||||
|
*(.rodata_wlog)
|
||||||
|
*(.rodata_wlog*)
|
||||||
|
_thread_local_end = ABSOLUTE(.);
|
||||||
|
_rodata_reserved_end = ABSOLUTE(.);
|
||||||
|
. = ALIGN(4);
|
||||||
|
} GROUP_DATA_LINK_IN(RAMABLE_REGION, IRAM_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/common-rom/common-rom-cpp.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-net.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-misc.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,,)
|
||||||
|
{
|
||||||
|
. = ALIGN(16);
|
||||||
|
_image_rodata_end = ABSOLUTE(.);
|
||||||
|
} GROUP_DATA_LINK_IN(RAMABLE_REGION, IRAM_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);
|
||||||
|
_end = ABSOLUTE(.);
|
||||||
|
_heap_sentry = .;
|
||||||
|
. = ALIGN(4);
|
||||||
|
__data_end = ABSOLUTE(.);
|
||||||
|
} GROUP_DATA_LINK_IN(RAMABLE_REGION, IRAM_REGION)
|
||||||
|
|
||||||
|
/* Shared RAM */
|
||||||
|
SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
|
||||||
|
{
|
||||||
|
. = ALIGN (8);
|
||||||
|
_bss_start = ABSOLUTE(.); /* required by bluetooth library */
|
||||||
|
__bss_start = ABSOLUTE(.);
|
||||||
|
|
||||||
|
*(.dynsbss)
|
||||||
|
*(.sbss)
|
||||||
|
*(.sbss.*)
|
||||||
|
*(.gnu.linkonce.sb.*)
|
||||||
|
*(.scommon)
|
||||||
|
*(.sbss2)
|
||||||
|
*(.sbss2.*)
|
||||||
|
*(.gnu.linkonce.sb2.*)
|
||||||
|
*(.dynbss)
|
||||||
|
*(.bss)
|
||||||
|
*(.bss.*)
|
||||||
|
*(.share.mem)
|
||||||
|
*(.gnu.linkonce.b.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN (8);
|
||||||
|
__bss_end = ABSOLUTE(.);
|
||||||
|
} GROUP_LINK_IN(RAMABLE_REGION)
|
||||||
|
|
||||||
|
ASSERT(((__bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_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)
|
||||||
|
|
||||||
|
.flash.text : ALIGN(IROM_SEG_ALIGN)
|
||||||
|
{
|
||||||
|
_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);
|
||||||
|
} GROUP_LINK_IN(IRAM_REGION)
|
||||||
|
|
||||||
|
#ifdef CONFIG_GEN_ISR_TABLES
|
||||||
|
#include <zephyr/linker/intlist.ld>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <zephyr/linker/debug-sections.ld>
|
||||||
|
|
||||||
|
.xtensa.info 0 : { *(.xtensa.info) }
|
||||||
|
.xt.insn 0 :
|
||||||
|
{
|
||||||
|
KEEP (*(.xt.insn))
|
||||||
|
KEEP (*(.gnu.linkonce.x.*))
|
||||||
|
}
|
||||||
|
.xt.prop 0 :
|
||||||
|
{
|
||||||
|
KEEP (*(.xt.prop))
|
||||||
|
KEEP (*(.xt.prop.*))
|
||||||
|
KEEP (*(.gnu.linkonce.prop.*))
|
||||||
|
}
|
||||||
|
.xt.lit 0 :
|
||||||
|
{
|
||||||
|
KEEP (*(.xt.lit))
|
||||||
|
KEEP (*(.xt.lit.*))
|
||||||
|
KEEP (*(.gnu.linkonce.p.*))
|
||||||
|
}
|
||||||
|
.xt.profile_range 0 :
|
||||||
|
{
|
||||||
|
KEEP (*(.xt.profile_range))
|
||||||
|
KEEP (*(.gnu.linkonce.profile_range.*))
|
||||||
|
}
|
||||||
|
.xt.profile_ranges 0 :
|
||||||
|
{
|
||||||
|
KEEP (*(.xt.profile_ranges))
|
||||||
|
KEEP (*(.gnu.linkonce.xt.profile_ranges.*))
|
||||||
|
}
|
||||||
|
.xt.profile_files 0 :
|
||||||
|
{
|
||||||
|
KEEP (*(.xt.profile_files))
|
||||||
|
KEEP (*(.gnu.linkonce.xt.profile_files.*))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)),
|
||||||
|
"IRAM0 segment data does not fit.")
|
45
soc/xtensa/espressif_esp32/esp32s3/esp32s3-mp.c
Normal file
45
soc/xtensa/espressif_esp32/esp32s3/esp32s3-mp.c
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/device.h>
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#include <zephyr/spinlock.h>
|
||||||
|
#include <zephyr/kernel_structs.h>
|
||||||
|
|
||||||
|
#include <soc.h>
|
||||||
|
#include <esp_cpu.h>
|
||||||
|
#include <hal/soc_hal.h>
|
||||||
|
#include <hal/soc_ll.h>
|
||||||
|
#include <zephyr/drivers/interrupt_controller/intc_esp32.h>
|
||||||
|
|
||||||
|
static struct k_spinlock loglock;
|
||||||
|
|
||||||
|
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');
|
||||||
|
}
|
||||||
|
|
||||||
|
void esp_appcpu_start(void *entry_point)
|
||||||
|
{
|
||||||
|
soc_ll_unstall_core(1);
|
||||||
|
|
||||||
|
if (!REG_GET_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_CLKGATE_EN)) {
|
||||||
|
REG_SET_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_CLKGATE_EN);
|
||||||
|
REG_CLR_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_RUNSTALL);
|
||||||
|
REG_SET_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_RESETTING);
|
||||||
|
REG_CLR_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_RESETTING);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_rom_ets_set_appcpu_boot_addr((void *)entry_point);
|
||||||
|
|
||||||
|
ets_delay_us(50000);
|
||||||
|
|
||||||
|
smp_log("ESP32S3: CPU1 start sequence complete");
|
||||||
|
}
|
|
@ -14,7 +14,12 @@
|
||||||
#include "mcuboot.ld"
|
#include "mcuboot.ld"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* Application default linker script */
|
/* Application default linker script */
|
||||||
#include "default.ld"
|
#if defined(CONFIG_SOC_ESP32S3_APPCPU)
|
||||||
|
#include "default_appcpu.ld"
|
||||||
|
#else
|
||||||
|
#include "default.ld"
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* CONFIG_MCUBOOT */
|
#endif /* CONFIG_MCUBOOT */
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Include esp-idf headers first to avoid redefining BIT() macro */
|
/* Include esp-idf headers first to avoid redefining BIT() macro */
|
||||||
#include "soc.h"
|
#include <soc.h>
|
||||||
#include <soc/rtc_cntl_reg.h>
|
#include <soc/rtc_cntl_reg.h>
|
||||||
#include <soc/timer_group_reg.h>
|
#include <soc/timer_group_reg.h>
|
||||||
#include <zephyr/drivers/interrupt_controller/intc_esp32.h>
|
#include <zephyr/drivers/interrupt_controller/intc_esp32.h>
|
||||||
|
@ -48,6 +48,45 @@ extern int _ext_ram_bss_end;
|
||||||
|
|
||||||
extern void z_cstart(void);
|
extern void z_cstart(void);
|
||||||
|
|
||||||
|
#ifdef CONFIG_SOC_ESP32S3_PROCPU
|
||||||
|
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_ESP32S3_PROCPU*/
|
||||||
|
|
||||||
#ifndef CONFIG_MCUBOOT
|
#ifndef CONFIG_MCUBOOT
|
||||||
/*
|
/*
|
||||||
* This function is a container for SoC patches
|
* This function is a container for SoC patches
|
||||||
|
@ -92,7 +131,7 @@ void IRAM_ATTR __esp_platform_start(void)
|
||||||
* initialization code wants a valid _current before
|
* initialization code wants a valid _current before
|
||||||
* arch_kernel_init() is invoked.
|
* arch_kernel_init() is invoked.
|
||||||
*/
|
*/
|
||||||
__asm__ volatile("wsr.MISC0 %0; rsync" : : "r"(&_kernel.cpus[0]));
|
__asm__ __volatile__("wsr.MISC0 %0; rsync" : : "r"(&_kernel.cpus[0]));
|
||||||
|
|
||||||
#ifdef CONFIG_MCUBOOT
|
#ifdef CONFIG_MCUBOOT
|
||||||
/* MCUboot early initialisation. */
|
/* MCUboot early initialisation. */
|
||||||
|
@ -149,6 +188,11 @@ void IRAM_ATTR __esp_platform_start(void)
|
||||||
|
|
||||||
esp_timer_early_init();
|
esp_timer_early_init();
|
||||||
|
|
||||||
|
#if CONFIG_SOC_ESP32S3_PROCPU
|
||||||
|
/* start the ESP32S3 APP CPU */
|
||||||
|
esp_start_appcpu();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_SOC_FLASH_ESP32
|
#if CONFIG_SOC_FLASH_ESP32
|
||||||
spi_flash_guard_set(&g_flash_guard_default_ops);
|
spi_flash_guard_set(&g_flash_guard_default_ops);
|
||||||
#endif
|
#endif
|
||||||
|
|
172
soc/xtensa/espressif_esp32/esp32s3/soc_appcpu.c
Normal file
172
soc/xtensa/espressif_esp32/esp32s3/soc_appcpu.c
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <soc.h>
|
||||||
|
#include <soc/rtc_cntl_reg.h>
|
||||||
|
#include <soc/timer_group_reg.h>
|
||||||
|
#include <zephyr/drivers/interrupt_controller/intc_esp32.h>
|
||||||
|
#include <xtensa/config/core-isa.h>
|
||||||
|
#include <xtensa/corebits.h>
|
||||||
|
|
||||||
|
#include <zephyr/kernel_structs.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <zephyr/toolchain/gcc.h>
|
||||||
|
#include <zephyr/types.h>
|
||||||
|
#include <zephyr/linker/linker-defs.h>
|
||||||
|
#include <kernel_internal.h>
|
||||||
|
#include <zephyr/sys/util.h>
|
||||||
|
|
||||||
|
#include <esp_private/system_internal.h>
|
||||||
|
#include <esp32s3/rom/cache.h>
|
||||||
|
#include <esp32s3/rom/rtc.h>
|
||||||
|
#include <soc/syscon_reg.h>
|
||||||
|
#include <hal/soc_ll.h>
|
||||||
|
#include <hal/wdt_hal.h>
|
||||||
|
#include <soc/cpu.h>
|
||||||
|
#include <soc/gpio_periph.h>
|
||||||
|
#include <esp_spi_flash.h>
|
||||||
|
#include <esp_err.h>
|
||||||
|
#include <esp_timer.h>
|
||||||
|
#include <esp_app_format.h>
|
||||||
|
#include <esp_clk_internal.h>
|
||||||
|
|
||||||
|
extern void z_cstart(void);
|
||||||
|
|
||||||
|
static void core_intr_matrix_clear(void)
|
||||||
|
{
|
||||||
|
uint32_t core_id = cpu_hal_get_core_id();
|
||||||
|
|
||||||
|
for (int i = 0; i < ETS_MAX_INTR_SOURCE; i++) {
|
||||||
|
intr_matrix_set(core_id, i, ETS_INVALID_INUM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRAM_ATTR __app_cpu_start(void)
|
||||||
|
{
|
||||||
|
extern uint32_t _init_start;
|
||||||
|
extern uint32_t _bss_start;
|
||||||
|
extern uint32_t _bss_end;
|
||||||
|
|
||||||
|
/* Move the exception vector table to IRAM. */
|
||||||
|
__asm__ __volatile__("wsr %0, vecbase" : : "r"(&_init_start));
|
||||||
|
|
||||||
|
/* Zero out BSS. Clobber _bss_start to avoid memset() elision. */
|
||||||
|
z_bss_zero();
|
||||||
|
|
||||||
|
__asm__ __volatile__("" : : "g"(&__bss_start) : "memory");
|
||||||
|
|
||||||
|
/* Disable normal interrupts. */
|
||||||
|
__asm__ __volatile__("wsr %0, PS" : : "r"(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE));
|
||||||
|
|
||||||
|
/* Initialize the architecture CPU pointer. Some of the
|
||||||
|
* initialization code wants a valid _current before
|
||||||
|
* arch_kernel_init() is invoked.
|
||||||
|
*/
|
||||||
|
__asm__ __volatile__("wsr.MISC0 %0; rsync" : : "r"(&_kernel.cpus[1]));
|
||||||
|
|
||||||
|
core_intr_matrix_clear();
|
||||||
|
|
||||||
|
esp_intr_initialize();
|
||||||
|
|
||||||
|
/* Start Zephyr */
|
||||||
|
z_cstart();
|
||||||
|
|
||||||
|
CODE_UNREACHABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Boot-time static default printk handler, possibly to be overridden later. */
|
||||||
|
int IRAM_ATTR arch_printk_char_out(int c)
|
||||||
|
{
|
||||||
|
ARG_UNUSED(c);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sys_arch_reboot(int type)
|
||||||
|
{
|
||||||
|
esp_restart_noos();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRAM_ATTR esp_restart_noos(void)
|
||||||
|
{
|
||||||
|
/* disable interrupts */
|
||||||
|
z_xt_ints_off(0xFFFFFFFF);
|
||||||
|
|
||||||
|
/* enable RTC watchdog for 1 second */
|
||||||
|
wdt_hal_context_t wdt_ctx;
|
||||||
|
uint32_t timeout_ticks = (uint32_t)(1000ULL * rtc_clk_slow_freq_get_hz() / 1000ULL);
|
||||||
|
|
||||||
|
wdt_hal_init(&wdt_ctx, WDT_RWDT, 0, false);
|
||||||
|
wdt_hal_write_protect_disable(&wdt_ctx);
|
||||||
|
wdt_hal_config_stage(&wdt_ctx, WDT_STAGE0, timeout_ticks, WDT_STAGE_ACTION_RESET_SYSTEM);
|
||||||
|
wdt_hal_config_stage(&wdt_ctx, WDT_STAGE1, timeout_ticks, WDT_STAGE_ACTION_RESET_RTC);
|
||||||
|
|
||||||
|
/* enable flash boot mode so that flash booting after restart is protected by the RTC WDT */
|
||||||
|
wdt_hal_set_flashboot_en(&wdt_ctx, true);
|
||||||
|
wdt_hal_write_protect_enable(&wdt_ctx);
|
||||||
|
|
||||||
|
/* disable TG0/TG1 watchdogs */
|
||||||
|
wdt_hal_context_t wdt0_context = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0};
|
||||||
|
|
||||||
|
wdt_hal_write_protect_disable(&wdt0_context);
|
||||||
|
wdt_hal_disable(&wdt0_context);
|
||||||
|
wdt_hal_write_protect_enable(&wdt0_context);
|
||||||
|
|
||||||
|
wdt_hal_context_t wdt1_context = {.inst = WDT_MWDT1, .mwdt_dev = &TIMERG1};
|
||||||
|
|
||||||
|
wdt_hal_write_protect_disable(&wdt1_context);
|
||||||
|
wdt_hal_disable(&wdt1_context);
|
||||||
|
wdt_hal_write_protect_enable(&wdt1_context);
|
||||||
|
|
||||||
|
/* Flush any data left in UART FIFOs */
|
||||||
|
esp_rom_uart_tx_wait_idle(0);
|
||||||
|
esp_rom_uart_tx_wait_idle(1);
|
||||||
|
esp_rom_uart_tx_wait_idle(2);
|
||||||
|
|
||||||
|
/* Disable cache */
|
||||||
|
Cache_Disable_ICache();
|
||||||
|
Cache_Disable_DCache();
|
||||||
|
|
||||||
|
/* 2nd stage bootloader reconfigures SPI flash signals. */
|
||||||
|
/* Reset them to the defaults expected by ROM */
|
||||||
|
WRITE_PERI_REG(GPIO_FUNC0_IN_SEL_CFG_REG, 0x30);
|
||||||
|
WRITE_PERI_REG(GPIO_FUNC1_IN_SEL_CFG_REG, 0x30);
|
||||||
|
WRITE_PERI_REG(GPIO_FUNC2_IN_SEL_CFG_REG, 0x30);
|
||||||
|
WRITE_PERI_REG(GPIO_FUNC3_IN_SEL_CFG_REG, 0x30);
|
||||||
|
WRITE_PERI_REG(GPIO_FUNC4_IN_SEL_CFG_REG, 0x30);
|
||||||
|
WRITE_PERI_REG(GPIO_FUNC5_IN_SEL_CFG_REG, 0x30);
|
||||||
|
|
||||||
|
/* Reset wifi/bluetooth/ethernet/sdio (bb/mac) */
|
||||||
|
SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG,
|
||||||
|
SYSTEM_BB_RST | SYSTEM_FE_RST | SYSTEM_MAC_RST | SYSTEM_BT_RST |
|
||||||
|
SYSTEM_BTMAC_RST | SYSTEM_SDIO_RST | SYSTEM_SDIO_HOST_RST |
|
||||||
|
SYSTEM_EMAC_RST | SYSTEM_MACPWR_RST | SYSTEM_RW_BTMAC_RST |
|
||||||
|
SYSTEM_RW_BTLP_RST | SYSTEM_BLE_REG_RST | SYSTEM_PWR_REG_RST);
|
||||||
|
REG_WRITE(SYSTEM_CORE_RST_EN_REG, 0);
|
||||||
|
|
||||||
|
/* Reset timer/spi/uart */
|
||||||
|
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_TIMERS_RST | SYSTEM_SPI01_RST |
|
||||||
|
SYSTEM_UART_RST | SYSTEM_SYSTIMER_RST);
|
||||||
|
REG_WRITE(SYSTEM_PERIP_RST_EN0_REG, 0);
|
||||||
|
|
||||||
|
/* Reset DMA */
|
||||||
|
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST);
|
||||||
|
REG_WRITE(SYSTEM_PERIP_RST_EN1_REG, 0);
|
||||||
|
|
||||||
|
SET_PERI_REG_MASK(SYSTEM_EDMA_CTRL_REG, SYSTEM_EDMA_RESET);
|
||||||
|
CLEAR_PERI_REG_MASK(SYSTEM_EDMA_CTRL_REG, SYSTEM_EDMA_RESET);
|
||||||
|
|
||||||
|
rtc_clk_cpu_freq_set_xtal();
|
||||||
|
|
||||||
|
/* Running on APP CPU: need to reset PRO CPU and unstall it, */
|
||||||
|
/* then reset APP CPU */
|
||||||
|
soc_ll_reset_core(0);
|
||||||
|
soc_ll_stall_core(0);
|
||||||
|
soc_ll_reset_core(1);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
|
@ -56,7 +56,7 @@
|
||||||
|
|
||||||
#if defined(CONFIG_BOARD_COLIBRI_IMX7D_M4) || defined(CONFIG_SOC_MK64F12) || \
|
#if defined(CONFIG_BOARD_COLIBRI_IMX7D_M4) || defined(CONFIG_SOC_MK64F12) || \
|
||||||
defined(CONFIG_SOC_MKW41Z4) || defined(CONFIG_SOC_SERIES_ESP32S2) || \
|
defined(CONFIG_SOC_MKW41Z4) || defined(CONFIG_SOC_SERIES_ESP32S2) || \
|
||||||
defined(CONFIG_SOC_ESP32S3) || defined(CONFIG_SOC_SERIES_ESP32C3)
|
defined(CONFIG_SOC_SERIES_ESP32S3) || defined(CONFIG_SOC_SERIES_ESP32C3)
|
||||||
#define DEFAULT_PERIOD_CYCLE 1024
|
#define DEFAULT_PERIOD_CYCLE 1024
|
||||||
#define DEFAULT_PULSE_CYCLE 512
|
#define DEFAULT_PULSE_CYCLE 512
|
||||||
#define DEFAULT_PERIOD_NSEC 2000000
|
#define DEFAULT_PERIOD_NSEC 2000000
|
||||||
|
|
2
west.yml
2
west.yml
|
@ -158,7 +158,7 @@ manifest:
|
||||||
groups:
|
groups:
|
||||||
- hal
|
- hal
|
||||||
- name: hal_espressif
|
- name: hal_espressif
|
||||||
revision: 80d910ca89eab9bce03f59a4ade33f1fc30ce0ad
|
revision: 9e4115fcbd6b737ec36488cd88c643eb7efc8b1b
|
||||||
path: modules/hal/espressif
|
path: modules/hal/espressif
|
||||||
west-commands: west/west-commands.yml
|
west-commands: west/west-commands.yml
|
||||||
groups:
|
groups:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue