soc: xtensa,riscv: esp32xx: refactor folder structure

Refactor the ESP32 target SOCs together with
all related boards. Most braking changes includes:

- changing the CONFIG_SOC_ESP32* to refer to
  the actual soc line (esp32,esp32s2,esp32s3,esp32c3)
- replacing CONFIG_SOC with the CONFIG_SOC_SERIES
- creating CONFIG_SOC_FAMILY_ESP32 to embrace all
  the ESP32 across all used architectures
- introducing CONFIG_SOC_PART_NUMBER_* to
  provide a SOC model config
- introducing the 'common' folder to hide all
  commonly used configs and files.
- updating west.yml to reflect previous changes in hal

Signed-off-by: Marek Matej <marek.matej@espressif.com>
This commit is contained in:
Marek Matej 2023-07-20 18:24:09 +02:00 committed by Carles Cufí
commit 6b57b3b786
154 changed files with 1049 additions and 1646 deletions

View file

@ -0,0 +1,94 @@
# SPDX-License-Identifier: Apache-2.0
zephyr_sources(
soc.c
soc_cache.c
loader.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
math(EXPR esptoolpy_flashsize "${CONFIG_FLASH_SIZE} / 0x100000")
if(CONFIG_BOOTLOADER_ESP_IDF)
include(ExternalProject)
## we use hello-world project, but I think any can be used.
set(espidf_components_dir ${ESP_IDF_PATH}/components)
set(espidf_prefix ${CMAKE_BINARY_DIR}/esp-idf)
set(espidf_build_dir ${espidf_prefix}/build)
ExternalProject_Add(
EspIdfBootloader
PREFIX ${espidf_prefix}
SOURCE_DIR ${espidf_components_dir}/bootloader/subproject
BINARY_DIR ${espidf_build_dir}/bootloader
CONFIGURE_COMMAND
${CMAKE_COMMAND} -G${CMAKE_GENERATOR}
-S ${espidf_components_dir}/bootloader/subproject
-B ${espidf_build_dir}/bootloader -DSDKCONFIG=${espidf_build_dir}/sdkconfig
-DIDF_PATH=${ESP_IDF_PATH} -DIDF_TARGET=${CONFIG_SOC_SERIES}
-DPYTHON_DEPS_CHECKED=1
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_ASM_COMPILER=${CMAKE_ASM_COMPILER}
-DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
-DPYTHON=${PYTHON_EXECUTABLE}
BUILD_COMMAND
${CMAKE_COMMAND} --build .
INSTALL_COMMAND "" # This particular build system has no install command
)
ExternalProject_Add(
EspPartitionTable
SOURCE_DIR ${espidf_components_dir}/partition_table
BINARY_DIR ${espidf_build_dir}
CONFIGURE_COMMAND ""
BUILD_COMMAND
${PYTHON_EXECUTABLE} ${ESP_IDF_PATH}/components/partition_table/gen_esp32part.py -q
--offset 0x8000 --flash-size ${esptoolpy_flashsize}MB ${ESP_IDF_PATH}/components/partition_table/partitions_singleapp.csv ${espidf_build_dir}/partitions_singleapp.bin
INSTALL_COMMAND ""
)
set_property(TARGET bintools PROPERTY disassembly_flag_inline_source)
add_dependencies(app EspIdfBootloader EspPartitionTable)
board_finalize_runner_args(esp32 "--esp-flash-bootloader=${espidf_build_dir}/bootloader/bootloader.bin")
board_finalize_runner_args(esp32 "--esp-flash-partition_table=${espidf_build_dir}/partitions_singleapp.bin")
board_finalize_runner_args(esp32 "--esp-partition-table-address=0x8000")
endif()
if(CONFIG_MCUBOOT OR CONFIG_BOOTLOADER_ESP_IDF)
if(CONFIG_BUILD_OUTPUT_BIN)
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
COMMAND ${PYTHON_EXECUTABLE} ${ESP_IDF_PATH}/components/esptool_py/esptool/esptool.py
ARGS --chip esp32s3 elf2image --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()
if(CONFIG_MCUBOOT)
board_finalize_runner_args(esp32 "--esp-flash-bootloader=${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin")
endif()
endif()
set_property(TARGET bintools PROPERTY disassembly_flag_inline_source)
board_finalize_runner_args(esp32 "--esp-boot-address=${boot_off}")
board_finalize_runner_args(esp32 "--esp-app-address=${img_0_off}")

View file

@ -0,0 +1,30 @@
# Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd.
# SPDX-License-Identifier: Apache-2.0
if SOC_SERIES_ESP32S3
config SOC_SERIES
default "esp32s3"
config HEAP_MEM_POOL_SIZE
default 32768
config MINIMAL_LIBC_OPTIMIZE_STRING_FOR_SIZE
default n
config SYS_CLOCK_HW_CYCLES_PER_SEC
default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency)
config XTENSA_CCOUNT_HZ
default SYS_CLOCK_HW_CYCLES_PER_SEC
config ESPTOOLPY_FLASHFREQ_80M
default y
config FLASH_SIZE
default $(dt_node_reg_size_int,/soc/flash-controller@60002000/flash@0,0)
config FLASH_BASE_ADDRESS
default $(dt_node_reg_addr_hex,/soc/flash-controller@60002000/flash@0)
endif # SOC_SERIES_ESP32S3

View file

@ -0,0 +1,16 @@
# Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd.
# SPDX-License-Identifier: Apache-2.0
config SOC_SERIES_ESP32S3
bool "ESP32-S3 Series"
select XTENSA
select SOC_FAMILY_ESP32
select DYNAMIC_INTERRUPTS
select ARCH_SUPPORTS_COREDUMP
select CLOCK_CONTROL
select PINCTRL
select XIP if !MCUBOOT
select HAS_ESPRESSIF_HAL
select CPU_HAS_FPU
help
Enable support for Espressif ESP32-S3

View file

@ -0,0 +1,296 @@
# Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd.
# SPDX-License-Identifier: Apache-2.0
if SOC_SERIES_ESP32S3
config IDF_TARGET_ESP32S3
bool "ESP32S3 as target SOC"
default y
config SOC_TOOLCHAIN_NAME
string
default "espressif_esp32s3"
choice SOC_PART_NUMBER
prompt "ESP32-S3 SOC Selection"
depends on SOC_SERIES_ESP32S3
# SoC with/without embedded flash
config SOC_ESP32S3
bool "ESP32S3"
config SOC_ESP32S3_R2
bool "ESP32S3_R2"
config SOC_ESP32S3_R8
bool "ESP32S3_R8"
config SOC_ESP32S3_R8V
bool "ESP32S3_R8V"
config SOC_ESP32S3_FN8
bool "ESP32S3_FN8"
config SOC_ESP32S3_PICO_N8R2
bool "ESP32S3_PICO_N8R2"
config SOC_ESP32S3_PICO_N8R8
bool "ESP32S3_PICO_N8R8"
# SiP with flash and/or psram
config SOC_ESP32S3_MINI_N8
bool "ESP32S3_MINI_N8"
config SOC_ESP32S3_MINI_N4R2
bool "ESP32S3_MINI_N4R2"
config SOC_ESP32S3_WROOM_N4
bool "ESP32S3_WROOM_N4"
config SOC_ESP32S3_WROOM_N8
bool "ESP32S3_WROOM_N8"
config SOC_ESP32S3_WROOM_N16
bool "ESP32S3_WROOM_N16"
config SOC_ESP32S3_WROOM_N4R8
bool "ESP32S3_WROOM_N4R8"
config SOC_ESP32S3_WROOM_N8R8
bool "ESP32S3_WROOM_N8R8"
config SOC_ESP32S3_WROOM_N16R8
bool "ESP32S3_WROOM_N16"
endchoice # SOC_PART_NUMBER
choice ESP32S3_RTC_CLK_SRC
prompt "RTC clock source"
default ESP32S3_RTC_CLK_SRC_INT_RC
help
Choose which clock is used as RTC clock source.
config ESP32S3_RTC_CLK_SRC_INT_RC
bool "Internal 150kHz RC oscillator"
config ESP32S3_RTC_CLK_SRC_EXT_CRYS
bool "External 32kHz crystal"
select ESP_SYSTEM_RTC_EXT_XTAL
config ESP32S3_RTC_CLK_SRC_EXT_OSC
bool "External 32kHz oscillator at 32K_XP pin"
select ESP_SYSTEM_RTC_EXT_OSC
config ESP32S3_RTC_CLK_SRC_INT_8MD256
bool "Internal 8MHz oscillator, divided by 256 (~32kHz)"
endchoice
config ESP32S3_RTC_CLK_CAL_CYCLES
int "Number of cycles for RTC_SLOW_CLK calibration"
default 3000 if ESP32S3_RTC_CLK_SRC_EXT_CRYS || ESP32S3_RTC_CLK_SRC_EXT_OSC || ESP32S3_RTC_CLK_SRC_INT_8MD256
default 1024 if ESP32S3_RTC_CLK_SRC_INT_RC
range 0 27000 if ESP32S3_RTC_CLK_SRC_EXT_CRYS || ESP32S3_RTC_CLK_SRC_EXT_OSC || ESP32S3_RTC_CLK_SRC_INT_8MD256
range 0 32766 if ESP32S3_RTC_CLK_SRC_INT_RC
help
When the startup code initializes RTC_SLOW_CLK, it can perform
calibration by comparing the RTC_SLOW_CLK frequency with main XTAL
frequency. This option sets the number of RTC_SLOW_CLK cycles measured
by the calibration routine. Higher numbers increase calibration
precision, which may be important for applications which spend a lot of
time in deep sleep. Lower numbers reduce startup time.
When this option is set to 0, clock calibration will not be performed at
startup, and approximate clock frequencies will be assumed:
- 150000 Hz if internal RC oscillator is used as clock source. For this use value 1024.
- 32768 Hz if the 32k crystal oscillator is used. For this use value 3000 or more.
In case more value will help improve the definition of the launch of the crystal.
If the crystal could not start, it will be switched to internal RC.
choice ESP32_UNIVERSAL_MAC_ADDRESSES
bool "Number of universally administered (by IEEE) MAC address"
default ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR
help
Configure the number of universally administered (by IEEE) MAC addresses.
During initialization, MAC addresses for each network interface are generated or
derived from a single base MAC address. If the number of universal MAC addresses is four,
all four interfaces (WiFi station, WiFi softap, Bluetooth and Ethernet) receive a universally
administered MAC address. These are generated sequentially by adding 0, 1, 2 and 3 (respectively)
to the final octet of the base MAC address. If the number of universal MAC addresses is two,
only two interfaces (WiFi station and Bluetooth) receive a universally administered MAC address.
These are generated sequentially by adding 0 and 1 (respectively) to the base MAC address.
The remaining two interfaces (WiFi softap and Ethernet) receive local MAC addresses.
These are derived from the universal WiFi station and Bluetooth MAC addresses, respectively.
When using the default (Espressif-assigned) base MAC address, either setting can be used.
When using a custom universal MAC address range, the correct setting will depend on the
allocation of MAC addresses in this range (either 2 or 4 per device.)
config ESP32_UNIVERSAL_MAC_ADDRESSES_TWO
bool "Two"
select ESP_MAC_ADDR_UNIVERSE_WIFI_STA
select ESP_MAC_ADDR_UNIVERSE_BT
config ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR
bool "Four"
select ESP_MAC_ADDR_UNIVERSE_WIFI_STA
select ESP_MAC_ADDR_UNIVERSE_WIFI_AP
select ESP_MAC_ADDR_UNIVERSE_BT
select ESP_MAC_ADDR_UNIVERSE_ETH
endchoice # ESP32_UNIVERSAL_MAC_ADDRESSES
config ESP_MAC_ADDR_UNIVERSE_WIFI_AP
bool
config ESP_MAC_ADDR_UNIVERSE_WIFI_STA
bool
config ESP_MAC_ADDR_UNIVERSE_BT
bool
config ESP_MAC_ADDR_UNIVERSE_ETH
bool
config ESP32_UNIVERSAL_MAC_ADDRESSES
int
default 2 if ESP32_UNIVERSAL_MAC_ADDRESSES_TWO
default 4 if ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR
config ESP32_PHY_MAX_WIFI_TX_POWER
int "Max WiFi/BLE TX power (dBm)"
range 10 20
default 20
help
Set maximum transmit power for WiFi radio. Actual transmit power for high
data rates may be lower than this setting.
config ESP32_PHY_MAX_TX_POWER
int
default ESP32_PHY_MAX_WIFI_TX_POWER
menu "Cache config"
choice ESP32S3_INSTRUCTION_CACHE_SIZE
prompt "Instruction cache size"
default ESP32S3_INSTRUCTION_CACHE_16KB
help
Instruction cache size to be set on application startup.
If you use 16KB instruction cache rather than 32KB instruction cache,
then the other 16KB will be managed by heap allocator.
config ESP32S3_INSTRUCTION_CACHE_16KB
bool "16KB"
config ESP32S3_INSTRUCTION_CACHE_32KB
bool "32KB"
endchoice
config ESP32S3_INSTRUCTION_CACHE_SIZE
hex
default 0x4000 if ESP32S3_INSTRUCTION_CACHE_16KB
default 0x8000 if ESP32S3_INSTRUCTION_CACHE_32KB
choice ESP32S3_ICACHE_ASSOCIATED_WAYS
prompt "Instruction cache associated ways"
default ESP32S3_INSTRUCTION_CACHE_8WAYS
help
Instruction cache associated ways to be set on application startup.
config ESP32S3_INSTRUCTION_CACHE_4WAYS
bool "4 ways"
config ESP32S3_INSTRUCTION_CACHE_8WAYS
bool "8 ways"
endchoice
config ESP32S3_ICACHE_ASSOCIATED_WAYS
int
default 4 if ESP32S3_INSTRUCTION_CACHE_4WAYS
default 8 if ESP32S3_INSTRUCTION_CACHE_8WAYS
choice ESP32S3_INSTRUCTION_CACHE_LINE_SIZE
prompt "Instruction cache line size"
default ESP32S3_INSTRUCTION_CACHE_LINE_32B
help
Instruction cache line size to be set on application startup.
config ESP32S3_INSTRUCTION_CACHE_LINE_16B
bool "16 Bytes"
depends on ESP32S3_INSTRUCTION_CACHE_16KB
config ESP32S3_INSTRUCTION_CACHE_LINE_32B
bool "32 Bytes"
endchoice
config ESP32S3_INSTRUCTION_CACHE_LINE_SIZE
int
default 16 if ESP32S3_INSTRUCTION_CACHE_LINE_16B
default 32 if ESP32S3_INSTRUCTION_CACHE_LINE_32B
config ESP32S3_INSTRUCTION_CACHE_WRAP
bool "Define instruction cache wrap mode"
help
If enabled, instruction cache will use wrap mode to read spi flash or spi ram.
The wrap length equals to ESP32S3_INSTRUCTION_CACHE_LINE_SIZE.
However, it depends on complex conditions.
choice ESP32S3_DATA_CACHE_SIZE
prompt "Data cache size"
default ESP32S3_DATA_CACHE_32KB
help
Data cache size to be set on application startup.
If you use 32KB data cache rather than 64KB data cache,
the other 32KB will be added to the heap.
config ESP32S3_DATA_CACHE_16KB
bool "16KB"
config ESP32S3_DATA_CACHE_32KB
bool "32KB"
config ESP32S3_DATA_CACHE_64KB
bool "64KB"
endchoice
config ESP32S3_DATA_CACHE_SIZE
hex
# For 16KB the actual configuration is 32kb cache, but 16kb will be reserved for heap at startup
default 0x8000 if ESP32S3_DATA_CACHE_16KB
default 0x8000 if ESP32S3_DATA_CACHE_32KB
default 0x10000 if ESP32S3_DATA_CACHE_64KB
choice ESP32S3_DCACHE_ASSOCIATED_WAYS
prompt "Data cache associated ways"
default ESP32S3_DATA_CACHE_8WAYS
help
Data cache associated ways to be set on application startup.
config ESP32S3_DATA_CACHE_4WAYS
bool "4 ways"
config ESP32S3_DATA_CACHE_8WAYS
bool "8 ways"
endchoice
config ESP32S3_DCACHE_ASSOCIATED_WAYS
int
default 4 if ESP32S3_DATA_CACHE_4WAYS
default 8 if ESP32S3_DATA_CACHE_8WAYS
choice ESP32S3_DATA_CACHE_LINE_SIZE
prompt "Data cache line size"
default ESP32S3_DATA_CACHE_LINE_32B
help
Data cache line size to be set on application startup.
config ESP32S3_DATA_CACHE_LINE_16B
bool "16 Bytes"
depends on ESP32S3_DATA_CACHE_16KB || ESP32S3_DATA_CACHE_32KB
config ESP32S3_DATA_CACHE_LINE_32B
bool "32 Bytes"
config ESP32S3_DATA_CACHE_LINE_64B
bool "64 Bytes"
endchoice
config ESP32S3_DATA_CACHE_LINE_SIZE
int
default 16 if ESP32S3_DATA_CACHE_LINE_16B
default 32 if ESP32S3_DATA_CACHE_LINE_32B
default 64 if ESP32S3_DATA_CACHE_LINE_64B
config ESP32S3_DATA_CACHE_WRAP
bool "Define data cache wrap mode"
help
If enabled, data cache will use wrap mode to read spi flash or spi ram.
The wrap length equals to ESP32S3_DATA_CACHE_LINE_SIZE.
However, it depends on complex conditions.
config MAC_BB_PD
bool "Power down MAC and baseband of Wi-Fi and Bluetooth when PHY is disabled"
depends on SOC_SERIES_ESP32S3 && TICKLESS_KERNEL
default n
help
If enabled, the MAC and baseband of Wi-Fi and Bluetooth will be powered
down when PHY is disabled. Enabling this setting reduces power consumption
by a small amount but increases RAM use by approximat
endmenu # Cache config
endif # SOC_SERIES_ESP32S3

View file

@ -0,0 +1,644 @@
/*
* Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the ESP32S3 platform.
*/
#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 I_D_SRAM_SIZE (SRAM_DRAM_END - SRAM_DRAM_START)
#define ICACHE_SIZE 0x8000
#define SRAM_IRAM_ORG (SRAM_IRAM_START + CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE)
#define SRAM_IRAM_SIZE (I_D_SRAM_SIZE + ICACHE_SIZE - CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE)
#define DCACHE_SIZE 0x10000
#define SRAM_DRAM_ORG (SRAM_DRAM_START)
#define DRAM0_0_SEG_LEN I_D_SRAM_SIZE
#define FLASH_CODE_REGION irom0_0_seg
#define RODATA_REGION drom0_0_seg
#define IRAM_REGION iram0_0_seg
#define RAMABLE_REGION dram0_0_seg
#define ROMABLE_REGION ROM
#ifdef CONFIG_FLASH_SIZE
#define FLASH_SIZE CONFIG_FLASH_SIZE
#else
#define FLASH_SIZE 0x800000
#endif
#ifdef CONFIG_BOOTLOADER_ESP_IDF
#define IROM_SEG_ORG 0x42000020
#define IROM_SEG_LEN FLASH_SIZE-0x20
#else
#define IROM_SEG_ORG 0x42000000
#define IROM_SEG_LEN FLASH_SIZE
#endif
#define IROM_SEG_ALIGN 0x10000
MEMORY
{
mcuboot_hdr (RX): org = 0x0, len = 0x20
metadata (RX): org = 0x20, len = 0x20
ROM (RX): org = 0x40, len = FLASH_SIZE - 0x40
iram0_0_seg(RX): org = SRAM_IRAM_ORG, len = SRAM_IRAM_SIZE
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.
* MCUboot binary for ESP32 has image header of 0x20 bytes.
* Additional load header of 0x20 bytes are appended to the image.
* Hence, an offset of 0x40 is added to DROM segment origin.
*/
drom0_0_seg(R): org = 0x3C000040, len = FLASH_SIZE - 0x40
/* RTC fast memory (executable). Persists over deep sleep.
*/
rtc_iram_seg(RWX): org = 0x600fe000, len = 0x2000
/* RTC fast memory (same block as above), viewed from data bus
*/
rtc_data_seg(RW): org = 0x600fe000, len = 0x2000
/* RTC slow memory (data accessible). Persists over deep sleep.
*/
rtc_slow_seg(RW): org = 0x50000000, len = 0x2000
#ifdef CONFIG_GEN_ISR_TABLES
IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000
#endif
}
/* Default entry point: */
ENTRY(CONFIG_KERNEL_ENTRY)
SECTIONS
{
/* Reserve space for MCUboot header in the binary */
.mcuboot_header :
{
QUAD(0x0)
QUAD(0x0)
QUAD(0x0)
QUAD(0x0)
} > mcuboot_hdr
.metadata :
{
/* Magic byte for load header */
LONG(0xace637d3)
/* Application entry point address */
KEEP(*(.entry_addr))
/* IRAM metadata:
* - Destination address (VMA) for IRAM region
* - Flash offset (LMA) for start of IRAM region
* - Size of IRAM region
*/
LONG(ADDR(.iram0.vectors))
LONG(LOADADDR(.iram0.vectors))
LONG(LOADADDR(.iram0.text) + SIZEOF(.iram0.text) - LOADADDR(.iram0.vectors))
/* DRAM metadata:
* - Destination address (VMA) for DRAM region
* - Flash offset (LMA) for start of DRAM region
* - Size of DRAM region
*/
LONG(ADDR(.dram0.data))
LONG(LOADADDR(.dram0.data))
LONG(LOADADDR(.dram0.end) + SIZEOF(.dram0.end) - LOADADDR(.dram0.data))
} > metadata
#include <zephyr/linker/rel-sections.ld>
_image_drom_start = LOADADDR(_RODATA_SECTION_NAME);
_image_drom_size = LOADADDR(_RODATA_SECTION_END) + SIZEOF(_RODATA_SECTION_END) - _image_drom_start;
_image_drom_vaddr = ADDR(_RODATA_SECTION_NAME);
/* NOTE: .rodata section should be the first section in the linker script and no
* other section should appear before .rodata section. This is the requirement
* to align ROM section to 64K page offset.
* Adding .rodata as first section helps to reduce size of generated binary by
* few kBs.
*/
SECTION_PROLOGUE(_RODATA_SECTION_NAME,,ALIGN(0x10))
{
_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(RODATA_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) > RODATA_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(0x10))
{
. = ALIGN(16);
_image_rodata_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION)
/* 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 */
. = 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)
_init_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION)
.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)
*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.*)
#if defined(CONFIG_ESP32_WIFI_IRAM_OPT)
*libnet80211.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.*)
*libpp.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiorslpiram .wifiorslpiram.*)
#endif
#if defined(CONFIG_ESP32_WIFI_RX_IRAM_OPT)
*libnet80211.a:( .wifirxiram .wifirxiram.* .wifislprxiram .wifislprxiram.*)
*libpp.a:( .wifirxiram .wifirxiram.* .wifislprxiram .wifislprxiram.*)
#endif
. = ALIGN(4) + 16;
} GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION)
/* Marks the end of IRAM code segment */
.iram0.text_end (NOLOAD) :
{
/* ESP32-S3 memprot requires 16B padding for possible CPU
* prefetch and 256B alignment for PMS split lines */
. = ALIGN(16);
_iram_text_end = ABSOLUTE(.);
} GROUP_LINK_IN(IRAM_REGION)
.iram0.data :
{
. = ALIGN(16);
*(.iram.data)
*(.iram.data*)
} GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION)
.iram0.bss (NOLOAD) :
{
. = ALIGN(16);
*(.iram.bss)
*(.iram.bss*)
. = ALIGN(16);
_iram_end = ABSOLUTE(.);
} GROUP_LINK_IN(IRAM_REGION)
/* This section is required to skip .iram0.text area because iram0_0_seg and
* dram0_0_seg reflect the same address space on different buses.
*/
.dram0.dummy (NOLOAD):
{
. = ALIGN (8);
. = ORIGIN(dram0_0_seg) + MAX(_iram_end, SRAM_DIRAM_I_START) - SRAM_DIRAM_I_START;
} GROUP_LINK_IN(RAMABLE_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)
#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, ROMABLE_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 = .;
__data_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
_image_irom_start = LOADADDR(.flash.text);
_image_irom_size = LOADADDR(.flash.text) + SIZEOF(.flash.text) - _image_irom_start;
_image_irom_vaddr = ADDR(.flash.text);
.flash_text_dummy (NOLOAD): ALIGN(IROM_SEG_ALIGN)
{
. = SIZEOF(_RODATA_SECTION_NAME);
. = ALIGN(IROM_SEG_ALIGN) + 0x20;
_rodata_reserved_start = .;
} GROUP_LINK_IN(FLASH_CODE_REGION)
.flash.text : ALIGN(IROM_SEG_ALIGN)
{
_stext = .;
_text_start = ABSOLUTE(.);
#if !defined(CONFIG_ESP32_WIFI_IRAM_OPT)
*libnet80211.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.*)
*libpp.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiorslpiram .wifiorslpiram.*)
#endif
#if !defined(CONFIG_ESP32_WIFI_RX_IRAM_OPT)
*libnet80211.a:( .wifirxiram .wifirxiram.* .wifislprxiram .wifislprxiram.*)
*libpp.a:( .wifirxiram .wifirxiram.* .wifislprxiram .wifislprxiram.*)
#endif
*(.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.
*/
_flash_cache_start = ABSOLUTE(0);
} GROUP_DATA_LINK_IN(FLASH_CODE_REGION, ROMABLE_REGION)
/* RTC fast memory holds RTC wake stub code,
* including from any source file named rtc_wake_stub*.c
*/
.rtc.text :
{
. = ALIGN(4);
_rtc_text_start = ABSOLUTE(.);
*(.rtc.literal .rtc.text)
*(.rtc.entry.text)
*rtc_wake_stub*.*(.literal .text .literal.* .text.*)
_rtc_text_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION)
/* This section is required to skip rtc.text area because rtc_iram_seg and
* rtc_data_seg are reflect the same address space on different buses.
*/
.rtc.dummy :
{
_rtc_dummy_start = ABSOLUTE(.);
_rtc_fast_start = ABSOLUTE(.);
. = SIZEOF(.rtc.text);
_rtc_dummy_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(rtc_data_seg, ROMABLE_REGION)
/* This section located in RTC FAST Memory area.
* It holds data marked with RTC_FAST_ATTR attribute.
* See the file "esp_attr.h" for more information.
*/
.rtc.force_fast :
{
. = ALIGN(4);
_rtc_force_fast_start = ABSOLUTE(.);
*(.rtc.force_fast .rtc.force_fast.*)
. = ALIGN(4) ;
_rtc_force_fast_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(rtc_data_seg, ROMABLE_REGION)
/* RTC data section holds RTC wake stub
* data/rodata, including from any source file
* named rtc_wake_stub*.c and the data marked with
* RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
*/
.rtc.data :
{
_rtc_data_start = ABSOLUTE(.);
*(.rtc.data)
*(.rtc.rodata)
*rtc_wake_stub*.o(.data .rodata .data.* .rodata.* .bss .bss.*)
_rtc_data_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(rtc_slow_seg, ROMABLE_REGION)
/* RTC bss, from any source file named rtc_wake_stub*.c */
.rtc.bss (NOLOAD) :
{
_rtc_bss_start = ABSOLUTE(.);
*rtc_wake_stub*.*(.bss .bss.*)
*rtc_wake_stub*.*(COMMON)
*(.rtc.data)
*(.rtc.rodata)
_rtc_bss_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(rtc_slow_seg, ROMABLE_REGION)
/* RTC bss, from any source file named rtc_wake_stub*.c */
.rtc.bss (NOLOAD) :
{
_rtc_bss_start = ABSOLUTE(.);
*rtc_wake_stub*.*(.bss .bss.*)
*rtc_wake_stub*.*(COMMON)
_rtc_bss_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(rtc_slow_seg, ROMABLE_REGION)
/* This section holds data that should not be initialized at power up
* and will be retained during deep sleep.
* User data marked with RTC_NOINIT_ATTR will be placed
* into this section. See the file "esp_attr.h" for more information.
*/
.rtc_noinit (NOLOAD):
{
. = ALIGN(4);
_rtc_noinit_start = ABSOLUTE(.);
*(.rtc_noinit .rtc_noinit.*)
. = ALIGN(4) ;
_rtc_noinit_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(rtc_slow_seg, ROMABLE_REGION)
/* This section located in RTC SLOW Memory area.
* It holds data marked with RTC_SLOW_ATTR attribute.
* See the file "esp_attr.h" for more information.
*/
.rtc.force_slow :
{
. = ALIGN(4);
_rtc_force_slow_start = ABSOLUTE(.);
*(.rtc.force_slow .rtc.force_slow.*)
. = ALIGN(4) ;
_rtc_force_slow_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(rtc_slow_seg, ROMABLE_REGION)
/* Get size of rtc slow data based on rtc_data_location alias */
_rtc_slow_length = (_rtc_force_slow_end - _rtc_data_start);
_rtc_fast_length = (_rtc_force_fast_end - _rtc_fast_start);
ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), "RTC_SLOW segment data does not fit.")
ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), "RTC_FAST segment data does not fit.")
#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.")

View file

@ -0,0 +1,20 @@
/*
* Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
*/
#if defined(CONFIG_MCUBOOT)
/* Using mcuboot as ESP32S3 2nd stage bootloader */
#include "mcuboot.ld"
#else
/* Application default linker script */
#include "default.ld"
#endif /* CONFIG_MCUBOOT */

View file

@ -0,0 +1,98 @@
/*
* Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <soc.h>
#include <zephyr/storage/flash_map.h>
#include <esp_log.h>
#include <stdlib.h>
#include <esp32s3/rom/cache.h>
#include "esp32s3/dport_access.h"
#include "soc/cache_memory.h"
#include <soc/dport_reg.h>
#include "soc/extmem_reg.h"
#include <bootloader_flash_priv.h>
#ifdef CONFIG_BOOTLOADER_MCUBOOT
#define BOOT_LOG_INF(_fmt, ...) \
ets_printf("[" CONFIG_SOC "] [INF] " _fmt "\n\r", ##__VA_ARGS__)
#define HDR_ATTR __attribute__((section(".entry_addr"))) __attribute__((used))
extern uint32_t _image_irom_start, _image_irom_size, _image_irom_vaddr;
extern uint32_t _image_drom_start, _image_drom_size, _image_drom_vaddr;
void __start(void);
static HDR_ATTR void (*_entry_point)(void) = &__start;
static int map_rom_segments(void)
{
int rc = 0;
size_t _partition_offset = FIXED_PARTITION_OFFSET(slot0_partition);
uint32_t _app_irom_start = _partition_offset + (uint32_t)&_image_irom_start;
uint32_t _app_irom_size = (uint32_t)&_image_irom_size;
uint32_t _app_irom_vaddr = (uint32_t)&_image_irom_vaddr;
uint32_t _app_drom_start = _partition_offset + (uint32_t)&_image_drom_start;
uint32_t _app_drom_size = (uint32_t)&_image_drom_size;
uint32_t _app_drom_vaddr = (uint32_t)&_image_drom_vaddr;
uint32_t autoload = Cache_Suspend_DCache();
Cache_Invalidate_DCache_All();
/* Clear the MMU entries that are already set up,
* so the new app only has the mappings it creates.
*/
for (size_t i = 0; i < FLASH_MMU_TABLE_SIZE; i++) {
FLASH_MMU_TABLE[i] = MMU_TABLE_INVALID_VAL;
}
uint32_t drom_page_count = bootloader_cache_pages_to_map(_app_drom_size, _app_drom_vaddr);
rc |= esp_rom_Cache_Dbus_MMU_Set(MMU_ACCESS_FLASH,
_app_drom_vaddr & MMU_FLASH_MASK,
_app_drom_start & MMU_FLASH_MASK,
64, drom_page_count, 0);
uint32_t irom_page_count = bootloader_cache_pages_to_map(_app_irom_size, _app_irom_vaddr);
rc |= esp_rom_Cache_Ibus_MMU_Set(MMU_ACCESS_FLASH,
_app_irom_vaddr & MMU_FLASH_MASK,
_app_irom_start & MMU_FLASH_MASK,
64, irom_page_count, 0);
REG_CLR_BIT(EXTMEM_DCACHE_CTRL1_REG, EXTMEM_DCACHE_SHUT_CORE0_BUS);
REG_CLR_BIT(EXTMEM_DCACHE_CTRL1_REG, EXTMEM_DCACHE_SHUT_CORE1_BUS);
Cache_Resume_DCache(autoload);
/* Show map segments continue using same log format as during MCUboot phase */
BOOT_LOG_INF("DROM segment: paddr=%08Xh, vaddr=%08Xh, size=%05Xh (%6d) map",
_app_drom_start, _app_drom_vaddr, _app_drom_size, _app_drom_size);
BOOT_LOG_INF("IROM segment: paddr=%08Xh, vaddr=%08Xh, size=%05Xh (%6d) map\r\n",
_app_irom_start, _app_irom_vaddr, _app_irom_size, _app_irom_size);
esp_rom_uart_tx_wait_idle(0);
return rc;
}
#endif /* CONFIG_BOOTLOADER_MCUBOOT */
void __start(void)
{
#ifdef CONFIG_BOOTLOADER_MCUBOOT
int err = map_rom_segments();
if (err != 0) {
ets_printf("Failed to setup XIP, aborting\n");
abort();
}
#endif
__esp_platform_start();
}

View file

@ -0,0 +1,374 @@
/*
* Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the Xtensa platform.
*/
#include <zephyr/devicetree.h>
#include <zephyr/linker/sections.h>
#include <zephyr/linker/linker-defs.h>
#include <zephyr/linker/linker-tool.h>
#ifdef CONFIG_XIP
#error "Xtensa bootloader cannot use XIP"
#endif /* CONFIG_XIP */
/* Disable all romable LMA */
#undef GROUP_DATA_LINK_IN
#define GROUP_DATA_LINK_IN(vregion, lregion) > vregion
#define RAMABLE_REGION dram_seg
#define RAMABLE_REGION_1 dram_seg
#define RODATA_REGION dram_seg
#define ROMABLE_REGION dram_seg
#define IRAM_REGION iram_seg
#define FLASH_CODE_REGION iram_seg
#define IROM_SEG_ALIGN 16
MEMORY
{
iram_seg(RWX) : org = 0x403B6000, len = 0x8000
iram_loader_seg(RWX) : org = 0x403BE000, len = 0x2000
dram_seg(RW) : org = 0x3FCD0000, len = 0x6000
#ifdef CONFIG_GEN_ISR_TABLES
IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000
#endif
}
/* Default entry point: */
ENTRY(CONFIG_KERNEL_ENTRY)
SECTIONS
{
SECTION_PROLOGUE(_RODATA_SECTION_NAME,,ALIGN(0x10))
{
__rodata_region_start = ABSOLUTE(.);
. = ALIGN(4);
#include <snippets-rodata.ld>
. = ALIGN(4);
*(.rodata)
*(.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(RODATA_REGION, ROMABLE_REGION)
#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-debug.ld>
#include <zephyr/linker/common-rom/common-rom-misc.ld>
#include <snippets-sections.ld>
.dram0.data :
{
__data_start = ABSOLUTE(.);
_btdm_data_start = ABSOLUTE(.);
*libbtdm_app.a:(.data .data.*)
. = ALIGN (4);
_btdm_data_end = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
KEEP(*(.jcr))
*(.dram1 .dram1.*)
. = ALIGN(4);
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_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>
#include <zephyr/linker/common-rom/common-rom-logging.ld>
.dram0.end :
{
. = ALIGN(4);
#include <snippets-rwdata.ld>
. = ALIGN(4);
_end = ABSOLUTE(.);
_heap_sentry = .;
__data_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
/* 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)
_init_end = ABSOLUTE(.);
/* This goes here, not at top of linker script, so addr2line finds it last,
* and uses it in preference to the first symbol in IRAM
*/
_iram_start = ABSOLUTE(0);
} GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION)
.iram_loader.text :
{
. = ALIGN (16);
_loader_text_start = ABSOLUTE(.);
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
*libzephyr.a:bootloader_flash.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_flash_config_esp32s3.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_common_loader.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_init_common.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_flash.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_random.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable)
*libzephyr.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable)
*libzephyr.a:bootloader_efuse_esp32s3.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_utility.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_sha.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_console.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_console_loader.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_panic.*(.literal .text .literal.* .text.*)
*libzephyr.a:bootloader_soc.*(.literal .text .literal.* .text.*)
*libzephyr.a:esp_image_format.*(.literal .text .literal.* .text.*)
*libzephyr.a:flash_encrypt.*(.literal .text .literal.* .text.*)
*libzephyr.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*)
*libzephyr.a:flash_partitions.*(.literal .text .literal.* .text.*)
*libzephyr.a:secure_boot.*(.literal .text .literal.* .text.*)
*libzephyr.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*)
*libzephyr.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*)
*libzephyr.a:wdt_hal_iram.*(.literal .text .literal.* .text.*)
*libzephyr.a:esp_efuse_table.*(.literal .text .literal.* .text.*)
*libzephyr.a:esp_efuse_fields.*(.literal .text .literal.* .text.*)
*libzephyr.a:esp_efuse_api.*(.literal .text .literal.* .text.*)
*libzephyr.a:esp_efuse_utility.*(.literal .text .literal.* .text.*)
*libzephyr.a:esp_efuse_api_key_esp32xx.*(.literal .text .literal.* .text.*)
*libzephyr.a:app_cpu_start.*(.literal .text .literal.* .text.*)
*esp_mcuboot.*(.literal .text .literal.* .text.*)
*esp_loader.*(.literal .text .literal.* .text.*)
*(.fini.literal)
*(.fini)
*(.gnu.version)
_loader_text_end = ABSOLUTE(.);
} > iram_loader_seg
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)
. = ALIGN(16);
_iram_text_end = ABSOLUTE(.); */
_iram_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION)
/* Shared RAM */
SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
{
. = ALIGN (8);
_bss_start = ABSOLUTE(.); /* required by bluetooth library */
__bss_start = ABSOLUTE(.);
_btdm_bss_start = ABSOLUTE(.);
*libbtdm_app.a:(.bss .bss.* COMMON)
. = ALIGN (4);
_btdm_bss_end = ABSOLUTE(.);
/* Buffer for system heap should be placed in dram_seg */
*libkernel.a:mempool.*(.noinit.kheap_buf__system_heap .noinit.*.kheap_buf__system_heap)
*(.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(.);
_bss_end = ABSOLUTE(.);
_end = ABSOLUTE(.);
} GROUP_LINK_IN(RAMABLE_REGION)
ASSERT(((__bss_end - ORIGIN(dram_seg)) <= LENGTH(dram_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 :
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.literal .text .literal.* .text.*)
. = ALIGN(4);
*(.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)
/* 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.
*/
_flash_cache_start = ABSOLUTE(0);
} GROUP_DATA_LINK_IN(FLASH_CODE_REGION, ROMABLE_REGION)
#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.*))
}
#ifdef CONFIG_GEN_ISR_TABLES
#include <zephyr/linker/intlist.ld>
#endif
}
ASSERT(((_iram_end - ORIGIN(IRAM_REGION)) <= LENGTH(IRAM_REGION)),
"IRAM0 segment data does not fit.")

View file

@ -0,0 +1,22 @@
/*
* Copyright (c) 2019, Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/toolchain.h>
#include <stdio.h>
#include <stddef.h>
#include <unistd.h>
#include <sys/stat.h>
#include <reent.h>
int __weak _gettimeofday_r(struct _reent *r, struct timeval *__tp, void *__tzp)
{
ARG_UNUSED(r);
ARG_UNUSED(__tp);
ARG_UNUSED(__tzp);
return -1;
}

View file

@ -0,0 +1,80 @@
/*
* Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* ESP32S3 SoC specific helpers for pinctrl driver
*/
#ifndef ZEPHYR_SOC_XTENSA_ESP32S3_PINCTRL_SOC_H_
#define ZEPHYR_SOC_XTENSA_ESP32S3_PINCTRL_SOC_H_
#include <zephyr/devicetree.h>
#include <zephyr/types.h>
#include <zephyr/dt-bindings/pinctrl/esp-pinctrl-common.h>
/** @cond INTERNAL_HIDDEN */
/** Type for ESP32 pin. */
struct pinctrl_soc_pin {
/** Pinmux settings (pin, direction and signal). */
uint32_t pinmux;
/** Pincfg settings (bias). */
uint32_t pincfg;
};
typedef struct pinctrl_soc_pin pinctrl_soc_pin_t;
/**
* @brief Utility macro to initialize pinmux field in #pinctrl_pin_t.
*
* @param node_id Node identifier.
*/
#define Z_PINCTRL_ESP32_PINMUX_INIT(node_id, prop, idx) DT_PROP_BY_IDX(node_id, prop, idx)
/**
* @brief Utility macro to initialize pincfg field in #pinctrl_pin_t.
*
* @param node_id Node identifier.
*/
#define Z_PINCTRL_ESP32_PINCFG_INIT(node_id) \
(((ESP32_NO_PULL * DT_PROP(node_id, bias_disable)) << ESP32_PIN_BIAS_SHIFT) | \
((ESP32_PULL_UP * DT_PROP(node_id, bias_pull_up)) << ESP32_PIN_BIAS_SHIFT) | \
((ESP32_PULL_DOWN * DT_PROP(node_id, bias_pull_down)) << ESP32_PIN_BIAS_SHIFT) | \
((ESP32_PUSH_PULL * DT_PROP(node_id, drive_push_pull)) << ESP32_PIN_DRV_SHIFT) | \
((ESP32_OPEN_DRAIN * DT_PROP(node_id, drive_open_drain)) << ESP32_PIN_DRV_SHIFT) | \
((ESP32_PIN_OUT_HIGH * DT_PROP(node_id, output_high)) << ESP32_PIN_OUT_SHIFT) | \
((ESP32_PIN_OUT_LOW * DT_PROP(node_id, output_low)) << ESP32_PIN_OUT_SHIFT) | \
((ESP32_PIN_OUT_EN * DT_PROP(node_id, output_enable)) << ESP32_PIN_EN_DIR_SHIFT) | \
((ESP32_PIN_IN_EN * DT_PROP(node_id, input_enable)) << ESP32_PIN_EN_DIR_SHIFT))
/**
* @brief Utility macro to initialize each pin.
*
* @param node_id Node identifier.
* @param prop Property name.
* @param idx Property entry index.
*/
#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \
{.pinmux = Z_PINCTRL_ESP32_PINMUX_INIT(node_id, prop, idx), \
.pincfg = Z_PINCTRL_ESP32_PINCFG_INIT(node_id)},
/**
* @brief Utility macro to initialize state pins contained in a given property.
*
* @param node_id Node identifier.
* @param prop Property name describing state pins.
*/
#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \
{ \
DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, pinmux, \
Z_PINCTRL_STATE_PIN_INIT) \
}
/** @endcond */
#endif /* ZEPHYR_SOC_XTENSA_ESP32S3_PINCTRL_SOC_H_ */

View file

@ -0,0 +1,244 @@
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/* Include esp-idf headers first to avoid redefining BIT() macro */
#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"
#ifdef CONFIG_MCUBOOT
#include "bootloader_init.h"
#endif /* CONFIG_MCUBOOT */
#include <zephyr/sys/printk.h>
extern void z_cstart(void);
#ifndef CONFIG_MCUBOOT
/*
* This function is a container for SoC patches
* that needs to be applied during the startup.
*/
static void IRAM_ATTR esp_errata(void)
{
/* Handle the clock gating fix */
REG_CLR_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_CLKGATE_EN);
/* The clock gating signal of the App core is invalid. We use RUNSTALL and RESETTING
* signals to ensure that the App core stops running in single-core mode.
*/
REG_SET_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_RUNSTALL);
REG_CLR_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_RESETTING);
/* Handle the Dcache case following the IDF startup code */
#if CONFIG_ESP32S3_DATA_CACHE_16KB
Cache_Invalidate_DCache_All();
Cache_Occupy_Addr(SOC_DROM_LOW, 0x4000);
#endif
}
#endif /* CONFIG_MCUBOOT */
/*
* This is written in C rather than assembly since, during the port bring up,
* Zephyr is being booted by the Espressif bootloader. With it, the C stack
* is already set up.
*/
void IRAM_ATTR __esp_platform_start(void)
{
extern uint32_t _init_start;
/* Move the exception vector table to IRAM. */
__asm__ __volatile__("wsr %0, vecbase" : : "r"(&_init_start));
z_bss_zero();
/* 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[0]));
#ifdef CONFIG_MCUBOOT
/* MCUboot early initialisation. */
if (bootloader_init()) {
abort();
}
#else
/* Configure the mode of instruction cache : cache size, cache line size. */
esp_config_instruction_cache_mode();
/* If we need use SPIRAM, we should use data cache.
* Configure the mode of data : cache size, cache line size.
*/
esp_config_data_cache_mode();
/* Apply SoC patches */
esp_errata();
/* ESP-IDF/MCUboot 2nd stage bootloader enables RTC WDT to check on startup sequence
* related issues in application. Hence disable that as we are about to start
* Zephyr environment.
*/
wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL};
wdt_hal_write_protect_disable(&rtc_wdt_ctx);
wdt_hal_disable(&rtc_wdt_ctx);
wdt_hal_write_protect_enable(&rtc_wdt_ctx);
esp_clk_init();
esp_timer_early_init();
#if CONFIG_SOC_FLASH_ESP32
spi_flash_guard_set(&g_flash_guard_default_ops);
#endif
#endif /* CONFIG_MCUBOOT */
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)
{
if (c == '\n') {
esp_rom_uart_tx_one_char('\r');
}
esp_rom_uart_tx_one_char(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();
const uint32_t core_id = cpu_hal_get_core_id();
#if CONFIG_SMP
const uint32_t other_core_id = (core_id == 0) ? 1 : 0;
soc_ll_reset_core(other_core_id);
soc_ll_stall_core(other_core_id);
#endif
/* 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();
/* Reset CPUs */
if (core_id == 0) {
/* Running on PRO CPU: APP CPU is stalled. Can reset both CPUs. */
soc_ll_reset_core(1);
soc_ll_reset_core(0);
} else {
/* 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) {
;
}
}

View file

@ -0,0 +1,81 @@
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __SOC_H__
#define __SOC_H__
#include <soc/dport_reg.h>
#include <soc/rtc_cntl_reg.h>
#include <soc/soc_caps.h>
#include <esp32s3/rom/ets_sys.h>
#include <esp32s3/rom/spi_flash.h>
#include "esp32s3/rom/cache.h"
#include <esp_rom_uart.h>
#include "soc/extmem_reg.h"
#include "soc/cache_memory.h"
#include "hal/cpu_hal.h"
#include "hal/cpu_types.h"
#include <esp_rom_sys.h>
#include <zephyr/types.h>
#include <stdbool.h>
#include <zephyr/arch/xtensa/arch.h>
#include <xtensa/core-macros.h>
#include <esp32s3/clk.h>
void __esp_platform_start(void);
static inline void esp32_set_mask32(uint32_t v, uint32_t mem_addr)
{
sys_write32(sys_read32(mem_addr) | v, mem_addr);
}
static inline void esp32_clear_mask32(uint32_t v, uint32_t mem_addr)
{
sys_write32(sys_read32(mem_addr) & ~v, mem_addr);
}
static inline uint32_t esp_core_id(void)
{
uint32_t id;
__asm__ volatile (
"rsr.prid %0\n"
"extui %0,%0,13,1" : "=r" (id));
return id;
}
extern void esp_rom_intr_matrix_set(int cpu_no, uint32_t model_num, uint32_t intr_num);
extern int esp_rom_gpio_matrix_in(uint32_t gpio, uint32_t signal_index,
bool inverted);
extern int esp_rom_gpio_matrix_out(uint32_t gpio, uint32_t signal_index,
bool out_inverted,
bool out_enabled_inverted);
extern void esp_rom_uart_attach(void);
extern void esp_rom_uart_tx_wait_idle(uint8_t uart_no);
extern int esp_rom_uart_tx_one_char(uint8_t chr);
extern int esp_rom_uart_rx_one_char(uint8_t *chr);
extern void esp_rom_uart_set_clock_baudrate(uint8_t uart_no, uint32_t clock_hz, uint32_t baud_rate);
extern void esp_rom_ets_set_appcpu_boot_addr(void *addr);
void esp_appcpu_start(void *entry_point);
extern int esp_rom_Cache_Dbus_MMU_Set(uint32_t ext_ram, uint32_t vaddr, uint32_t paddr,
uint32_t psize, uint32_t num, uint32_t fixed);
extern int esp_rom_Cache_Ibus_MMU_Set(uint32_t ext_ram, uint32_t vaddr, uint32_t paddr,
uint32_t psize, uint32_t num, uint32_t fixed);
/* ROM functions which read/write internal i2c control bus for PLL, APLL */
extern uint8_t esp_rom_i2c_readReg(uint8_t block, uint8_t host_id, uint8_t reg_add);
extern void esp_rom_i2c_writeReg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data);
/* cache initialization functions */
void esp_config_instruction_cache_mode(void);
void esp_config_data_cache_mode(void);
#endif /* __SOC_H__ */

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc.h"
#ifndef CONFIG_MCUBOOT
extern int _rodata_reserved_start;
extern int _rodata_reserved_end;
extern void rom_config_data_cache_mode(uint32_t cfg_cache_size, uint8_t cfg_cache_ways,
uint8_t cfg_cache_line_size);
extern void rom_config_instruction_cache_mode(uint32_t cfg_cache_size, uint8_t cfg_cache_ways,
uint8_t cfg_cache_line_size);
extern uint32_t Cache_Set_IDROM_MMU_Size(uint32_t irom_size, uint32_t drom_size);
extern void Cache_Set_IDROM_MMU_Info(uint32_t instr_page_num, uint32_t rodata_page_num,
uint32_t rodata_start, uint32_t rodata_end,
int i_off, int ro_off);
extern void Cache_Enable_ICache(uint32_t autoload);
void IRAM_ATTR esp_config_instruction_cache_mode(void)
{
rom_config_instruction_cache_mode(CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE,
CONFIG_ESP32S3_ICACHE_ASSOCIATED_WAYS,
CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_SIZE);
Cache_Suspend_DCache();
}
void IRAM_ATTR esp_config_data_cache_mode(void)
{
int s_instr_flash2spiram_off = 0;
int s_rodata_flash2spiram_off = 0;
rom_config_data_cache_mode(CONFIG_ESP32S3_DATA_CACHE_SIZE,
CONFIG_ESP32S3_DCACHE_ASSOCIATED_WAYS,
CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE);
Cache_Resume_DCache(0);
/* Configure the Cache MMU size for instruction and rodata in flash. */
uint32_t rodata_reserved_start_align =
(uint32_t)&_rodata_reserved_start & ~(MMU_PAGE_SIZE - 1);
uint32_t cache_mmu_irom_size =
((rodata_reserved_start_align - SOC_DROM_LOW) / MMU_PAGE_SIZE) * sizeof(uint32_t);
uint32_t cache_mmu_drom_size =
(((uint32_t)&_rodata_reserved_end - rodata_reserved_start_align + MMU_PAGE_SIZE - 1)
/ MMU_PAGE_SIZE) * sizeof(uint32_t);
Cache_Set_IDROM_MMU_Size(cache_mmu_irom_size, CACHE_DROM_MMU_MAX_END - cache_mmu_irom_size);
Cache_Set_IDROM_MMU_Info(cache_mmu_irom_size / sizeof(uint32_t),
cache_mmu_drom_size / sizeof(uint32_t),
(uint32_t)&_rodata_reserved_start,
(uint32_t)&_rodata_reserved_end,
s_instr_flash2spiram_off,
s_rodata_flash2spiram_off);
}
#endif /* CONFIG_MCUBOOT */