soc: esp32s3: add base source content

This brings esp32s3 linker, DTS and all
necessary files to allow the soc support.

Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
This commit is contained in:
Sylvio Alves 2023-01-02 09:15:18 -03:00 committed by Carles Cufí
parent fde5281541
commit bbd40b85c0
12 changed files with 2073 additions and 1 deletions

View File

@ -0,0 +1,154 @@
/*
* Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <mem.h>
#include <xtensa/xtensa.dtsi>
#include <zephyr/dt-bindings/gpio/gpio.h>
#include <zephyr/dt-bindings/clock/esp32s3_clock.h>
#include <zephyr/dt-bindings/interrupt-controller/esp32s3-xtensa-intmux.h>
#include <dt-bindings/pinctrl/esp32s3-pinctrl.h>
/ {
chosen {
zephyr,flash-controller = &flash;
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu0: cpu@0 {
device_type = "cpu";
compatible = "cdns,tensilica-xtensa-lx7";
reg = <0>;
};
cpu1: cpu@1 {
device_type = "cpu";
compatible = "cdns,tensilica-xtensa-lx7";
reg = <1>;
};
};
pinctrl: pin-controller {
compatible = "espressif,esp32-pinctrl";
status = "okay";
};
soc {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
ranges;
sram0: memory@3fc88000 {
compatible = "mmio-sram";
reg = <0x3fc88000 0x77FFF>;
};
intc: interrupt-controller@600c2000 {
#interrupt-cells = <1>;
compatible = "espressif,esp32-intc";
interrupt-controller;
reg = <0x600c2000 0x1000>;
status = "okay";
};
rtc: rtc@60021000 {
compatible = "espressif,esp32-rtc";
reg = <0x60021000 0x2000>;
xtal-freq = <ESP32_CLK_XTAL_40M>;
#clock-cells = <1>;
status = "okay";
rtc_timer: rtc_timer {
compatible = "espressif,esp32-rtc-timer";
slow-clk-freq = <ESP32_RTC_SLOW_CLK_FREQ_150K>;
interrupts = <RTC_CORE_INTR_SOURCE>;
interrupt-parent = <&intc>;
status = "okay";
};
};
flash: flash-controller@60002000 {
compatible = "espressif,esp32-flash-controller";
reg = <0x60002000 0x1000>;
/* interrupts = <3 0>; */
#address-cells = <1>;
#size-cells = <1>;
flash0: flash@0 {
compatible = "soc-nv-flash";
reg = <0 0x800000>;
erase-block-size = <4096>;
write-block-size = <4>;
};
};
uart0: uart@60000000 {
compatible = "espressif,esp32-uart";
reg = <0x60000000 0x1000>;
interrupts = <UART0_INTR_SOURCE>;
interrupt-parent = <&intc>;
clocks = <&rtc ESP32_UART0_MODULE>;
status = "disabled";
};
uart1: uart@60010000 {
compatible = "espressif,esp32-uart";
reg = <0x60010000 0x1000>;
interrupts = <UART1_INTR_SOURCE>;
interrupt-parent = <&intc>;
clocks = <&rtc ESP32_UART1_MODULE>;
status = "disabled";
};
uart2: uart@6002e000 {
compatible = "espressif,esp32-uart";
reg = <0x6002e000 0x1000>;
interrupts = <UART2_INTR_SOURCE>;
interrupt-parent = <&intc>;
clocks = <&rtc ESP32_UART2_MODULE>;
status = "disabled";
};
gpio: gpio {
compatible = "simple-bus";
gpio-map-mask = <0xffffffe0 0xffffffc0>;
gpio-map-pass-thru = <0x1f 0x3f>;
gpio-map = <
0x00 0x0 &gpio0 0x0 0x0
0x20 0x0 &gpio1 0x0 0x0
>;
#gpio-cells = <2>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
gpio0: gpio@60004000 {
compatible = "espressif,esp32-gpio";
gpio-controller;
#gpio-cells = <2>;
reg = <0x60004000 0x800>;
interrupts = <GPIO_INTR_SOURCE>;
interrupt-parent = <&intc>;
ngpios = <32>;
};
gpio1: gpio@60004800 {
compatible = "espressif,esp32-gpio";
gpio-controller;
#gpio-cells = <2>;
reg = <0x60004800 0x800>;
interrupts = <GPIO_INTR_SOURCE>;
interrupt-parent = <&intc>;
ngpios = <13>;
};
};
};
};

View File

@ -0,0 +1,83 @@
# SPDX-License-Identifier: Apache-2.0
zephyr_sources(
soc.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}
-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 ""
)
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()
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()
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,44 @@
# ESP32 board configuration
# Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd.
# SPDX-License-Identifier: Apache-2.0
if SOC_ESP32S3
if BOOTLOADER_MCUBOOT
config HAS_FLASH_LOAD_OFFSET
default y
config MCUBOOT_GENERATE_UNSIGNED_IMAGE
default y
config MCUBOOT_GENERATE_CONFIRMED_IMAGE
default y
config ROM_START_OFFSET
default 0x20
config HAS_DYNAMIC_DEVICE_HANDLES
default y
endif
config SOC
default "esp32s3"
config SOC_TOOLCHAIN_NAME
string
default "espressif_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
endif

View File

@ -0,0 +1,266 @@
# Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd.
# SPDX-License-Identifier: Apache-2.0
config SOC_ESP32S3
bool "ESP32S3"
select XTENSA
select CLOCK_CONTROL
select DYNAMIC_INTERRUPTS
select ARCH_SUPPORTS_COREDUMP
select PINCTRL
select XIP
select HAS_ESPRESSIF_HAL
if SOC_ESP32S3
config IDF_TARGET_ESP32S3
bool "ESP32S3 as target board"
default y
config ESPTOOLPY_FLASHFREQ_80M
bool
default y
config FLASH_SIZE
int
default $(dt_node_reg_size_int,/soc/flash-controller@60002000/flash@0,0)
config FLASH_BASE_ADDRESS
hex
default $(dt_node_reg_addr_hex,/soc/flash-controller@60002000/flash@0)
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.
endmenu # Cache config
endif # SOC_ESP32S3

View File

@ -0,0 +1,371 @@
/*
* Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT.
*
* Functions here are designed to produce efficient code to
* search an Xtensa bitmask of interrupts, inspecting only those bits
* declared to be associated with a given interrupt level. Each
* dispatcher will handle exactly one flagged interrupt, in numerical
* order (low bits first) and will return a mask of that bit that can
* then be cleared by the calling code. Unrecognized bits for the
* level will invoke an error handler.
*/
#include <xtensa/config/core-isa.h>
#include <zephyr/sys/util.h>
#include <zephyr/sw_isr_table.h>
#if !defined(XCHAL_INT0_LEVEL) || XCHAL_INT0_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT1_LEVEL) || XCHAL_INT1_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT2_LEVEL) || XCHAL_INT2_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT3_LEVEL) || XCHAL_INT3_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT4_LEVEL) || XCHAL_INT4_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT5_LEVEL) || XCHAL_INT5_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT6_LEVEL) || XCHAL_INT6_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT7_LEVEL) || XCHAL_INT7_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT8_LEVEL) || XCHAL_INT8_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT9_LEVEL) || XCHAL_INT9_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT10_LEVEL) || XCHAL_INT10_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT12_LEVEL) || XCHAL_INT12_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT13_LEVEL) || XCHAL_INT13_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT17_LEVEL) || XCHAL_INT17_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT18_LEVEL) || XCHAL_INT18_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT11_LEVEL) || XCHAL_INT11_LEVEL != 3
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT15_LEVEL) || XCHAL_INT15_LEVEL != 3
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT22_LEVEL) || XCHAL_INT22_LEVEL != 3
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT23_LEVEL) || XCHAL_INT23_LEVEL != 3
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT27_LEVEL) || XCHAL_INT27_LEVEL != 3
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT29_LEVEL) || XCHAL_INT29_LEVEL != 3
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT14_LEVEL) || XCHAL_INT14_LEVEL != 7
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT16_LEVEL) || XCHAL_INT16_LEVEL != 5
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT26_LEVEL) || XCHAL_INT26_LEVEL != 5
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT31_LEVEL) || XCHAL_INT31_LEVEL != 5
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT19_LEVEL) || XCHAL_INT19_LEVEL != 2
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT20_LEVEL) || XCHAL_INT20_LEVEL != 2
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT21_LEVEL) || XCHAL_INT21_LEVEL != 2
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT24_LEVEL) || XCHAL_INT24_LEVEL != 4
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT25_LEVEL) || XCHAL_INT25_LEVEL != 4
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT28_LEVEL) || XCHAL_INT28_LEVEL != 4
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT30_LEVEL) || XCHAL_INT30_LEVEL != 4
#error core-isa.h interrupt level does not match dispatcher!
#endif
static inline int _xtensa_handle_one_int1(unsigned int mask)
{
int irq;
if (mask & 0x7f) {
if (mask & 0x7) {
if (mask & BIT(0)) {
mask = BIT(0);
irq = 0;
goto handle_irq;
}
if (mask & BIT(1)) {
mask = BIT(1);
irq = 1;
goto handle_irq;
}
if (mask & BIT(2)) {
mask = BIT(2);
irq = 2;
goto handle_irq;
}
} else {
if (mask & 0x18) {
if (mask & BIT(3)) {
mask = BIT(3);
irq = 3;
goto handle_irq;
}
if (mask & BIT(4)) {
mask = BIT(4);
irq = 4;
goto handle_irq;
}
} else {
if (mask & BIT(5)) {
mask = BIT(5);
irq = 5;
goto handle_irq;
}
if (mask & BIT(6)) {
mask = BIT(6);
irq = 6;
goto handle_irq;
}
}
}
} else {
if (mask & 0x780) {
if (mask & 0x180) {
if (mask & BIT(7)) {
mask = BIT(7);
irq = 7;
goto handle_irq;
}
if (mask & BIT(8)) {
mask = BIT(8);
irq = 8;
goto handle_irq;
}
} else {
if (mask & BIT(9)) {
mask = BIT(9);
irq = 9;
goto handle_irq;
}
if (mask & BIT(10)) {
mask = BIT(10);
irq = 10;
goto handle_irq;
}
}
} else {
if (mask & 0x3000) {
if (mask & BIT(12)) {
mask = BIT(12);
irq = 12;
goto handle_irq;
}
if (mask & BIT(13)) {
mask = BIT(13);
irq = 13;
goto handle_irq;
}
} else {
if (mask & BIT(17)) {
mask = BIT(17);
irq = 17;
goto handle_irq;
}
if (mask & BIT(18)) {
mask = BIT(18);
irq = 18;
goto handle_irq;
}
}
}
}
return 0;
handle_irq:
_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
return mask;
}
static inline int _xtensa_handle_one_int3(unsigned int mask)
{
int irq;
if (mask & 0x408800) {
if (mask & BIT(11)) {
mask = BIT(11);
irq = 11;
goto handle_irq;
}
if (mask & BIT(15)) {
mask = BIT(15);
irq = 15;
goto handle_irq;
}
if (mask & BIT(22)) {
mask = BIT(22);
irq = 22;
goto handle_irq;
}
} else {
if (mask & BIT(23)) {
mask = BIT(23);
irq = 23;
goto handle_irq;
}
if (mask & BIT(27)) {
mask = BIT(27);
irq = 27;
goto handle_irq;
}
if (mask & BIT(29)) {
mask = BIT(29);
irq = 29;
goto handle_irq;
}
}
return 0;
handle_irq:
_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
return mask;
}
static inline int _xtensa_handle_one_int7(unsigned int mask)
{
int irq;
if (mask & BIT(14)) {
mask = BIT(14);
irq = 14;
goto handle_irq;
}
return 0;
handle_irq:
_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
return mask;
}
static inline int _xtensa_handle_one_int5(unsigned int mask)
{
int irq;
if (mask & BIT(16)) {
mask = BIT(16);
irq = 16;
goto handle_irq;
}
if (mask & BIT(26)) {
mask = BIT(26);
irq = 26;
goto handle_irq;
}
if (mask & BIT(31)) {
mask = BIT(31);
irq = 31;
goto handle_irq;
}
return 0;
handle_irq:
_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
return mask;
}
static inline int _xtensa_handle_one_int2(unsigned int mask)
{
int irq;
if (mask & BIT(19)) {
mask = BIT(19);
irq = 19;
goto handle_irq;
}
if (mask & BIT(20)) {
mask = BIT(20);
irq = 20;
goto handle_irq;
}
if (mask & BIT(21)) {
mask = BIT(21);
irq = 21;
goto handle_irq;
}
return 0;
handle_irq:
_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
return mask;
}
static inline int _xtensa_handle_one_int4(unsigned int mask)
{
int irq;
if (mask & 0x3000000) {
if (mask & BIT(24)) {
mask = BIT(24);
irq = 24;
goto handle_irq;
}
if (mask & BIT(25)) {
mask = BIT(25);
irq = 25;
goto handle_irq;
}
} else {
if (mask & BIT(28)) {
mask = BIT(28);
irq = 28;
goto handle_irq;
}
if (mask & BIT(30)) {
mask = BIT(30);
irq = 30;
goto handle_irq;
}
}
return 0;
handle_irq:
_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
return mask;
}
static inline int _xtensa_handle_one_int0(unsigned int mask)
{
return 0;
}
static inline int _xtensa_handle_one_int6(unsigned int mask)
{
return 0;
}

View File

@ -0,0 +1,643 @@
/*
* Copyright (c) 2022 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>
#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
#define IROM_SEG_ALIGN 0x4
#else
#define IROM_SEG_ORG 0x42000000
#define IROM_SEG_LEN FLASH_SIZE
#define IROM_SEG_ALIGN 0x10000
#endif
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)
_diram_i_start = 0x40378000;
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(_TEXT_SECTION_NAME) + SIZEOF(_TEXT_SECTION_NAME) - 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>
/* 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.")
/* 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)
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.*)
*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: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.*)
*libgcov.a:(.literal .text .literal.* .text.*)
} GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION)
_image_dram_start = LOADADDR(.dram0.data);
_image_dram_size = LOADADDR(.dram0.end) + SIZEOF(.dram0.end) - _image_dram_start;
_image_dram_vaddr = ADDR(.dram0.data);
/**
* 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):
{
. = ORIGIN(dram0_0_seg) + MAX(_iram_end - _iram_start, 0);
} GROUP_LINK_IN(RAMABLE_REGION)
#include <snippets-sections.ld>
.dram0.data :
{
__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: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.*)
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)
SECTION_DATA_PROLOGUE(_NOINIT_SECTION_NAME, (NOLOAD),)
{
. = ALIGN(4);
*(.noinit .noinit.*)
. = ALIGN(4) ;
} 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.")
.flash.text :
{
_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.
*/
_flash_cache_start = ABSOLUTE(0);
} GROUP_DATA_LINK_IN(FLASH_CODE_REGION, ROMABLE_REGION)
/**
* This dummy section represents the .flash.text section but in default_rodata_seg.
* Thus, it must have its alignment and (at least) its size.
*/
.flash_rodata_dummy (NOLOAD):
{
_flash_rodata_dummy_start = .;
/* Start at the same alignment constraint than .flash.text */
. = ALIGN(ALIGNOF(.flash.text));
/* Create an empty gap as big as .flash.text section */
. = . + SIZEOF(.flash.text);
/* Prepare the alignment of the section above. Few bytes (0x20) must be
* added for the mapping header. */
. = ALIGN(0x10000) + 0x20;
_rodata_reserved_start = .;
} GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION)
.flash.appdesc : 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! */
/* Create an empty gap within this section. Thanks to this, the end of this
* section will match .flah.rodata's begin address. Thus, both sections
* will be merged when creating the final bin image. */
. = ALIGN(ALIGNOF(_RODATA_SECTION_NAME));
} GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION)
SECTION_PROLOGUE(_RODATA_SECTION_NAME,,ALIGN(0x10))
{
__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(4);
_image_rodata_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION)
_image_iram_start = LOADADDR(.iram0.vectors);
_image_iram_size = LOADADDR(_TEXT_SECTION_NAME) + SIZEOF(_TEXT_SECTION_NAME) - _image_iram_start;
_image_iram_vaddr = ADDR(.iram0.vectors);
/* 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)
_image_irom_start = LOADADDR(.flash.text);
_image_irom_size = LOADADDR(.flash.text) + SIZEOF(.flash.text) - _image_irom_start;
_image_irom_vaddr = ADDR(.flash.text);
#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(iram0_0_seg)) <= LENGTH(iram0_0_seg)),
"IRAM0 segment data does not fit.")

View File

@ -0,0 +1,96 @@
/*
* 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 <esp32s3/rom/cache.h>
#include <soc/dport_reg.h>
#include <bootloader_flash_priv.h>
#ifdef CONFIG_BOOTLOADER_MCUBOOT
#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;
Cache_Read_Disable(0);
Cache_Flush(0);
/* Clear the MMU entries that are already set up,
* so the new app only has the mappings it creates.
*/
for (int i = 0; i < DPORT_FLASH_MMU_TABLE_SIZE; i++) {
DPORT_PRO_FLASH_MMU_TABLE[i] =
DPORT_FLASH_MMU_TABLE_INVALID_VAL;
}
uint32_t drom_vaddr_addr_aligned = _app_drom_vaddr & MMU_FLASH_MASK;
uint32_t drom_page_count = bootloader_cache_pages_to_map(_app_drom_size,
_app_drom_vaddr);
rc = cache_flash_mmu_set(0, 0, drom_vaddr_addr_aligned, _app_drom_start
& MMU_FLASH_MASK, 64, drom_page_count);
rc |= cache_flash_mmu_set(1, 0, drom_vaddr_addr_aligned, _app_drom_start
& MMU_FLASH_MASK, 64, drom_page_count);
uint32_t irom_vaddr_addr_aligned = _app_irom_vaddr & MMU_FLASH_MASK;
uint32_t irom_page_count = bootloader_cache_pages_to_map(_app_irom_size,
_app_irom_vaddr);
rc |= cache_flash_mmu_set(0, 0, irom_vaddr_addr_aligned, _app_irom_start
& MMU_FLASH_MASK, 64, irom_page_count);
rc |= cache_flash_mmu_set(1, 0, irom_vaddr_addr_aligned, _app_irom_start
& MMU_FLASH_MASK, 64, irom_page_count);
DPORT_REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG,
(DPORT_PRO_CACHE_MASK_IRAM0) |
(DPORT_PRO_CACHE_MASK_IRAM1 & 0) |
(DPORT_PRO_CACHE_MASK_IROM0 & 0) |
DPORT_PRO_CACHE_MASK_DROM0 |
DPORT_PRO_CACHE_MASK_DRAM1);
DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG,
(DPORT_APP_CACHE_MASK_IRAM0) |
(DPORT_APP_CACHE_MASK_IRAM1 & 0) |
(DPORT_APP_CACHE_MASK_IROM0 & 0) |
DPORT_APP_CACHE_MASK_DROM0 |
DPORT_APP_CACHE_MASK_DRAM1);
esp_rom_Cache_Read_Enable(0);
return rc;
}
#endif
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,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,78 @@
/*
* 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))
/**
* @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_ */

243
soc/xtensa/esp32s3/soc.c Normal file
View File

@ -0,0 +1,243 @@
/*
* 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 "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"
#include <zephyr/sys/printk.h>
extern void z_cstart(void);
extern void rom_config_instruction_cache_mode(uint32_t cfg_cache_size,
uint8_t cfg_cache_ways, uint8_t cfg_cache_line_size);
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 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 uint32_t Cache_Set_IDROM_MMU_Size(uint32_t irom_size, uint32_t drom_size);
extern int _rodata_reserved_start;
extern int _rodata_reserved_end;
/*
* 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();
/*
* Configure the mode of instruction cache :
* cache size, cache associated ways, cache line size.
*/
rom_config_instruction_cache_mode(CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE,
CONFIG_ESP32S3_ICACHE_ASSOCIATED_WAYS,
CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_SIZE);
/* configure the mode of data: cache size, cache line size.*/
Cache_Suspend_DCache();
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_start_align = (uint32_t)&_rodata_reserved_start & ~(MMU_PAGE_SIZE - 1);
uint32_t cache_mmu_irom_size = ((rodata_start_align - SOC_DROM_LOW) / MMU_PAGE_SIZE)
* sizeof(uint32_t);
uint32_t cache_mmu_drom_size = (((uint32_t)&_rodata_reserved_end - rodata_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, 0, 0);
#if CONFIG_ESP32S3_DATA_CACHE_16KB
Cache_Invalidate_DCache_All();
Cache_Occupy_Addr(SOC_DROM_LOW, 0x4000);
#endif
/* 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]));
/* 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_feed(&rtc_wdt_ctx);
wdt_hal_write_protect_enable(&rtc_wdt_ctx);
esp_clk_init();
esp_timer_early_init();
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) {
;
}
}

72
soc/xtensa/esp32s3/soc.h Normal file
View File

@ -0,0 +1,72 @@
/*
* 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);
/* 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);
#endif /* __SOC_H__ */

View File

@ -57,7 +57,7 @@ manifest:
groups:
- hal
- name: hal_espressif
revision: 73e7af1e2ed64571ce49ff9f07dc02690b9f2df5
revision: a06af2476671160f19e813c86570a17541f3b07e
path: modules/hal/espressif
west-commands: west/west-commands.yml
groups: