diff --git a/soc/espressif/common/Kconfig.defconfig b/soc/espressif/common/Kconfig.defconfig index e451dfaae64..381a7e357d4 100644 --- a/soc/espressif/common/Kconfig.defconfig +++ b/soc/espressif/common/Kconfig.defconfig @@ -1,7 +1,7 @@ # Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_ESP32C3 +if SOC_SERIES_ESP32C3 || SOC_SERIES_ESP32C6 config GEN_ISR_TABLES default y diff --git a/soc/espressif/common/Kconfig.flash b/soc/espressif/common/Kconfig.flash index 2ed5d3f1b65..71eb970a2a9 100644 --- a/soc/espressif/common/Kconfig.flash +++ b/soc/espressif/common/Kconfig.flash @@ -94,7 +94,7 @@ config BOOTLOADER_FLASH_XMC_SUPPORT choice BOOTLOADER_VDDSDIO_BOOST bool "VDDSDIO LDO voltage" default BOOTLOADER_VDDSDIO_BOOST_1_9V - depends on !SOC_SERIES_ESP32C3 + depends on !SOC_SERIES_ESP32C3 && !SOC_SERIES_ESP32C6 help If this option is enabled, and VDDSDIO LDO is set to 1.8V (using eFuse or MTDI bootstrapping pin), bootloader will change LDO settings to diff --git a/soc/espressif/esp32c6/CMakeLists.txt b/soc/espressif/esp32c6/CMakeLists.txt new file mode 100644 index 00000000000..279a373adc1 --- /dev/null +++ b/soc/espressif/esp32c6/CMakeLists.txt @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources( + vectors.S + soc_irq.S + soc_irq.c + soc.c + ../common/loader.c + ) + +zephyr_include_directories(.) + +zephyr_library_sources_ifdef(CONFIG_PM power.c) +zephyr_library_sources_ifdef(CONFIG_POWEROFF poweroff.c) + +# get flash size to use in esptool as string +math(EXPR esptoolpy_flashsize "${CONFIG_FLASH_SIZE} / 0x100000") + +if(NOT CONFIG_BOOTLOADER_MCUBOOT) + + if(CONFIG_BUILD_OUTPUT_BIN) + # make ESP ROM loader compatible image + message("ESP-IDF path: ${ESP_IDF_PATH}") + + set(ESPTOOL_PY ${ESP_IDF_PATH}/tools/esptool_py/esptool.py) + message("esptool path: ${ESPTOOL_PY}") + + set(ELF2IMAGE_ARG "") + if(NOT CONFIG_MCUBOOT) + set(ELF2IMAGE_ARG "--ram-only-header") + endif() + + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${ESPTOOL_PY} + ARGS --chip esp32c6 elf2image ${ELF2IMAGE_ARG} + --flash_mode dio --flash_freq 40m --flash_size ${esptoolpy_flashsize}MB + -o ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin + ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.elf) + endif() + +endif() + +# 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}) + +if(CONFIG_ESP_SIMPLE_BOOT) + board_finalize_runner_args(esp32 "--esp-app-address=${boot_off}") +else() + board_finalize_runner_args(esp32 "--esp-app-address=${img_0_off}") +endif() + +if(CONFIG_MCUBOOT) + # search from cross references between bootloader sections + message("check_callgraph using: ${ESP_IDF_PATH}/tools/ci/check_callgraph.py") + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND + ${PYTHON_EXECUTABLE} ${ESP_IDF_PATH}/tools/ci/check_callgraph.py + ARGS + --rtl-dirs ${CMAKE_BINARY_DIR}/zephyr + --elf-file ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.elf + find-refs --from-section=.iram0.iram_loader --to-section=.iram0.text + --exit-code) +endif() + +if(CONFIG_MCUBOOT) + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/mcuboot.ld CACHE INTERNAL "") +else() + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/default.ld CACHE INTERNAL "") +endif() diff --git a/soc/espressif/esp32c6/Kconfig b/soc/espressif/esp32c6/Kconfig new file mode 100644 index 00000000000..48aad9c0a4b --- /dev/null +++ b/soc/espressif/esp32c6/Kconfig @@ -0,0 +1,47 @@ +# Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_ESP32C6 + select RISCV + select RISCV_GP + select DYNAMIC_INTERRUPTS + select CLOCK_CONTROL + select PINCTRL + select RISCV_ISA_RV32I + select RISCV_ISA_EXT_M + select RISCV_ISA_EXT_C + select RISCV_ISA_EXT_ZICSR + select HAS_ESPRESSIF_HAL + select XIP if !MCUBOOT + select HAS_PM + select HAS_POWEROFF + +if SOC_SERIES_ESP32C6 + +config IDF_TARGET_ESP32C6 + bool "ESP32C6 as target board" + default y + +config ESP32_PHY_MAX_WIFI_TX_POWER + int "Max WiFi 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 + +config MAC_BB_PD + bool "Power down MAC and baseband of Wi-Fi and Bluetooth when PHY is disabled" + depends on SOC_SERIES_ESP32C6 && 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 approximately 4 KB(Wi-Fi only), + 2 KB(Bluetooth only) or 5.3 KB(Wi-Fi + Bluetooth). + +endif # SOC_SERIES_ESP32C6 diff --git a/soc/espressif/esp32c6/Kconfig.defconfig b/soc/espressif/esp32c6/Kconfig.defconfig new file mode 100644 index 00000000000..498f486b75c --- /dev/null +++ b/soc/espressif/esp32c6/Kconfig.defconfig @@ -0,0 +1,17 @@ +# ESP32C3 board configuration + +# Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_ESP32C6 + +config NUM_IRQS + default 77 + +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_ESP32C6 diff --git a/soc/espressif/esp32c6/Kconfig.mac b/soc/espressif/esp32c6/Kconfig.mac new file mode 100644 index 00000000000..5078bef8352 --- /dev/null +++ b/soc/espressif/esp32c6/Kconfig.mac @@ -0,0 +1,48 @@ +# Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_ESP32C6 + +choice ESP32C6_UNIVERSAL_MAC_ADDRESSES + bool "Number of universally administered (by IEEE) MAC address" + default ESP32C6_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.) + Note that ESP32-C6 has no integrated Ethernet MAC. Although it's possible to use the esp_read_mac() + API to return a MAC for Ethernet, this can only be used with an external MAC peripheral. + +config ESP32C6_UNIVERSAL_MAC_ADDRESSES_TWO + bool "Two" + select ESP_MAC_UNIVERSAL_MAC_ADDRESSES_TWO + select ESP_MAC_ADDR_UNIVERSE_WIFI_STA + select ESP_MAC_ADDR_UNIVERSE_BT + +config ESP32C6_UNIVERSAL_MAC_ADDRESSES_FOUR + bool "Four" + select ESP_MAC_UNIVERSAL_MAC_ADDRESSES_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 # ESP32C6_UNIVERSAL_MAC_ADDRESSES + +config ESP32C6_UNIVERSAL_MAC_ADDRESSES + int + default 2 if ESP32C6_UNIVERSAL_MAC_ADDRESSES_TWO + default 4 if ESP32C6_UNIVERSAL_MAC_ADDRESSES_FOUR + +endif # SOC_SERIES_ESP32C6 diff --git a/soc/espressif/esp32c6/Kconfig.rtc b/soc/espressif/esp32c6/Kconfig.rtc new file mode 100644 index 00000000000..2a9a864d01b --- /dev/null +++ b/soc/espressif/esp32c6/Kconfig.rtc @@ -0,0 +1,50 @@ +# Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_ESP32C6 + +choice RTC_CLK_SRC + prompt "RTC clock source" + default RTC_CLK_SRC_INT_RC + help + Choose which clock is used as RTC clock source. + +config RTC_CLK_SRC_INT_RC + bool "Internal 136kHz RC oscillator" + +config RTC_CLK_SRC_EXT_CRYS + bool "External 32kHz crystal" + select ESP_SYSTEM_RTC_EXT_XTAL + +config RTC_CLK_SRC_EXT_OSC + bool "External 32kHz oscillator at 32K_XP pin" + select ESP_SYSTEM_RTC_EXT_OSC + +config RTC_CLK_SRC_INT_8MD256 + bool "Internal 17.5MHz oscillator, divided by 256" + +endchoice # ESP32C6_RTC_CLK_SRC + +config RTC_CLK_CAL_CYCLES + int "Number of cycles for RTC_SLOW_CLK calibration" + default 3000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_8MD256 + default 1024 if RTC_CLK_SRC_INT_RC + range 0 27000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_8MD256 + range 0 32766 if 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. + +endif # SOC_SERIES_ESP32C6 diff --git a/soc/espressif/esp32c6/Kconfig.soc b/soc/espressif/esp32c6/Kconfig.soc new file mode 100644 index 00000000000..7e2e3295ebc --- /dev/null +++ b/soc/espressif/esp32c6/Kconfig.soc @@ -0,0 +1,29 @@ +# Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_ESP32C6 + bool + select SOC_FAMILY_ESPRESSIF_ESP32 + +config SOC_ESP32_C6_WROOM_1U_N4 + bool + select SOC_ESP32C6 + +config SOC_ESP32_C6_WROOM_1U_N8 + bool + select SOC_ESP32C6 + +config SOC_ESP32C6 + bool + select SOC_SERIES_ESP32C6 + +config SOC_SERIES + default "esp32c6" if SOC_SERIES_ESP32C6 + +config SOC + default "esp32c6" if SOC_SERIES_ESP32C6 + +config SOC_PART_NUMBER + default "ESP32_C6_WROOM_1U_N4" if SOC_ESP32_C6_WROOM_1U_N4 + default "ESP32_C6_WROOM_1U_N8" if SOC_ESP32_C6_WROOM_1U_N8 + default "ESP32C6" if SOC_ESP32C6 diff --git a/soc/espressif/esp32c6/default.ld b/soc/espressif/esp32c6/default.ld new file mode 100644 index 00000000000..eda13818884 --- /dev/null +++ b/soc/espressif/esp32c6/default.ld @@ -0,0 +1,807 @@ +/* + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include "memory.h" + +/* The "user_sram_end" represents the 2nd stage bootloader + * "iram_loader_seg" start address (that should not be overlapped). + * If no bootloader is used, we can extend it to gain more user ram. + */ +#ifdef CONFIG_ESP_SIMPLE_BOOT +user_sram_end = DRAM_BUFFERS_START; +#else +user_sram_end = BOOTLOADER_IRAM_LOADER_SEG_START; +#endif + +/* User available memory segments */ +user_sram_org = HPSRAM_START; +user_sram_size = (user_sram_end - user_sram_org); + +/* Aliases */ +#define CACHED_REGION mmap0_0_seg +#define RAMABLE_REGION sram0_0_seg +#define ROMABLE_REGION FLASH + +/* Flash segments (rodata and text) should be mapped in the virtual address spaces. + * Executing directly from LMA is not possible. */ +#undef GROUP_ROM_LINK_IN +#define GROUP_ROM_LINK_IN(vregion, lregion) > CACHED_REGION AT > lregion + +/* TODO: add RTC support */ +#define RESERVE_RTC_MEM 0 + +/* Global symbols required for espressif hal build */ +MEMORY +{ +#ifdef CONFIG_BOOTLOADER_MCUBOOT + mcuboot_hdr (R): org = 0x0, len = 0x20 + metadata (R): org = 0x20, len = 0x20 + FLASH (R): org = 0x40, len = FLASH_SIZE - 0x40 +#else + /* Make safety margin in the FLASH memory size so the + * (esp_img_header + (n*esp_seg_headers)) would fit */ + FLASH (R): org = 0x0, len = FLASH_SIZE - 0x100 +#endif + + sram0_0_seg(RW): org = user_sram_org, len = user_sram_size + + mmap0_0_seg (R): org = CACHED_ORG, len = CACHED_SIZE + + lp_ram_seg(RW): org = LPSRAM_IRAM_START, + len = 0x4000 - RESERVE_RTC_MEM + + lp_reserved_seg(RW) : org = LPSRAM_IRAM_START + 0x4000 - RESERVE_RTC_MEM, + len = RESERVE_RTC_MEM + +#ifdef CONFIG_GEN_ISR_TABLES + IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000 +#endif +} + +/* The lines below define location alias for .rtc.data section + * C6 has no distinguished LP(RTC) fast and slow memory sections, + * instead, there is a unified LP_RAM section + * Thus, the following region segments are + * not configurable like on other targets + */ +REGION_ALIAS("rtc_iram_seg", lp_ram_seg ); +REGION_ALIAS("rtc_data_seg", rtc_iram_seg ); +REGION_ALIAS("rtc_slow_seg", rtc_iram_seg ); +REGION_ALIAS("rtc_data_location", rtc_iram_seg ); +REGION_ALIAS("rtc_reserved_seg", lp_reserved_seg ); + +/* Default entry point: */ +ENTRY(CONFIG_KERNEL_ENTRY) + +SECTIONS +{ +#ifdef CONFIG_BOOTLOADER_MCUBOOT + /* Reserve space for MCUboot header in the binary */ + .mcuboot_header : + { + QUAD(0x0) + QUAD(0x0) + QUAD(0x0) + QUAD(0x0) + } > mcuboot_hdr + .metadata : + { + /* 0. Magic byte for load header */ + LONG(0xace637d3) + + /* 1. Application entry point address */ + KEEP(*(.entry_addr)) + + /* IRAM metadata: + * 2. Destination address (VMA) for IRAM region + * 3. Flash offset (LMA) for start of IRAM region + * 4. Size of IRAM region + */ + LONG(ADDR(.iram0.text)) + LONG(LOADADDR(.iram0.text)) + LONG(LOADADDR(.iram0.data) - LOADADDR(.iram0.text)) + + /* DRAM metadata: + * 5. Destination address (VMA) for DRAM region + * 6. Flash offset (LMA) for start of DRAM region + * 7. Size of DRAM region + */ + LONG(ADDR(.dram0.data)) + LONG(LOADADDR(.dram0.data)) + LONG(LOADADDR(.dram0.end) - LOADADDR(.dram0.data)) + } > metadata +#endif /* CONFIG_BOOTLOADER_MCUBOOT */ + + #include + + /* --- START OF RTC --- */ + + .rtc.text : + { + . = ALIGN(4); + *(.rtc.literal .rtc.text) + *rtc_wake_stub*.o(.literal .text .literal.* .text.*) + } GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION) + + /* This section is required to skip rtc.text area because the text and + * data segments reflect the same address space on different buses. + */ + .rtc.dummy (NOLOAD): + { + . = SIZEOF(.rtc.text); + } GROUP_LINK_IN(rtc_iram_seg) + + .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_iram_seg, ROMABLE_REGION) + + .rtc.bss (NOLOAD) : + { + _rtc_bss_start = ABSOLUTE(.); + *rtc_wake_stub*.o(.bss .bss.*) + *rtc_wake_stub*.o(COMMON) + _rtc_bss_end = ABSOLUTE(.); + } GROUP_LINK_IN(rtc_iram_seg) + + /* 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(.); + } > rtc_slow_seg + + /* Get size of rtc slow data */ + _rtc_slow_length = (_rtc_force_slow_end - _rtc_data_start); + + /* --- END OF RTC --- */ + + /* --- START OF IRAM --- */ + + .iram0.text : ALIGN(4) + { + /* Vectors go to IRAM */ + _iram_start = ABSOLUTE(.); + _init_start = ABSOLUTE(.); + + KEEP(*(.exception_vectors.text)); + . = ALIGN(256); + + _invalid_pc_placeholder = ABSOLUTE(.); + + KEEP(*(.exception.entry*)); /* contains _isr_wrapper */ + *(.exception.other*) + . = ALIGN(4); + + *(.entry.text) + *(.init.literal) + *(.init) + . = ALIGN(4); + + _init_end = ABSOLUTE(.); + _iram_text_start = ABSOLUTE(.); + + *(.iram1 .iram1.*) + *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text) + *libzephyr.a:panic.*(.literal .text .literal.* .text.*) + *libzephyr.a:loader.*(.literal .text .literal.* .text.*) + *libarch__riscv__core.a:(.literal .text .literal.* .text.*) + *libsubsys__net__l2__ethernet.a:(.literal .text .literal.* .text.*) + *libsubsys__net__lib__config.a:(.literal .text .literal.* .text.*) + *libsubsys__net__ip.a:(.literal .text .literal.* .text.*) + *libsubsys__net.a:(.literal .text .literal.* .text.*) + *libkernel.a:(.literal .text .literal.* .text.*) + *libgcc.a:lib2funcs.*(.literal .text .literal.* .text.*) + *libdrivers__flash.a:flash_esp32.*(.literal .text .literal.* .text.*) + *libzephyr.a:spi_flash_rom_patch.*(.literal .text .literal.* .text.*) + *libzephyr.a:log_noos.*(.literal .text .literal.* .text.*) + *libdrivers__timer.a:esp32c6_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:rtc_*.*(.literal .text .literal.* .text.*) + *liblib__libc__newlib.a:string.*(.literal .text .literal.* .text.*) + *liblib__libc__minimal.a:string.*(.literal .text .literal.* .text.*) + *liblib__libc__picolib.a:string.*(.literal .text .literal.* .text.*) + *libzephyr.a:periph_ctrl.*(.literal .text .literal.* .text.*) + *libgcov.a:(.literal .text .literal.* .text.*) + *libphy.a:( .phyiram .phyiram.*) + *libc.a:*(.literal .text .literal.* .text.*) + + /* [mapping:hal] */ + *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*) + *libzephyr.a:spi_flash_hal_iram.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_encrypt_hal_iram.*(.literal .text .literal.* .text.*) + *libzephyr.a:cache_hal.*(.literal .text .literal.* .text.*) + *libzephyr.a:ledc_hal_iram.*(.literal .text .literal.* .text.*) + *libzephyr.a:i2c_hal_iram.*(.literal .text .literal.* .text.*) + *libzephyr.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) + *libzephyr.a:systimer_hal.*(.literal .text .literal.* .text.*) + *libzephyr.a:spi_flash_hal_gpspi.*(.literal .literal.* .text .text.*) + + /* [mapping:soc] */ + *libzephyr.a:lldesc.*(.literal .literal.* .text .text.*) + + /* [mapping:log] */ + *(.literal.esp_log_write .text.esp_log_write) + *(.literal.esp_log_timestamp .text.esp_log_timestamp) + *(.literal.esp_log_early_timestamp .text.esp_log_early_timestamp) + *(.literal.esp_log_impl_lock .text.esp_log_impl_lock) + *(.literal.esp_log_impl_lock_timeout .text.esp_log_impl_lock_timeout) + *(.literal.esp_log_impl_unlock .text.esp_log_impl_unlock) + + /* [mapping:spi_flash] */ + *libzephyr.a:spi_flash_chip_boya.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_gd.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_generic.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_issi.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_mxic.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_mxic_opi.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_th.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_winbond.*(.literal .literal.* .text .text.*) + *libzephyr.a:memspi_host_driver.*(.literal .literal.* .text .text.*) + *libzephyr.a:flash_brownout_hook.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_wrap.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_hpm_enable.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_oct_flash_init*(.literal .literal.* .text .text.*) + + /* [mapping:esp_system] */ + *libzephyr.a:reset_reason.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_err.*(.literal .literal.* .text .text.*) + *(.literal.esp_system_abort .text.esp_system_abort) + + /* [mapping:esp_hw_support] */ + *(.literal.esp_cpu_stall .text.esp_cpu_stall) + *(.literal.esp_cpu_unstall .text.esp_cpu_unstall) + *(.literal.esp_cpu_reset .text.esp_cpu_reset) + *(.literal.esp_cpu_wait_for_intr .text.esp_cpu_wait_for_intr) + *(.literal.esp_cpu_compare_and_set .text.esp_cpu_compare_and_set) + *(.literal.esp_gpio_reserve_pins .text.esp_gpio_reserve_pins) + *(.literal.esp_gpio_is_pin_reserved .text.esp_gpio_is_pin_reserved) + *(.literal.rtc_vddsdio_get_config .text.rtc_vddsdio_get_config) + *(.literal.rtc_vddsdio_set_config .text.rtc_vddsdio_set_config) + *libzephyr.a:esp_memory_utils.*(.literal .literal.* .text .text.*) + *libzephyr.a:pmu_init.*(.literal .literal.* .text .text.*) + *libzephyr.a:rtc_clk.*(.literal .literal.* .text .text.*) + *libzephyr.a:rtc_clk_init.*(.literal .literal.* .text .text.*) + *libzephyr.a:rtc_time.*(.literal .literal.* .text .text.*) + *libzephyr.a:rtc_sleep.*(.literal .literal.* .text .text.*) + *libzephyr.a:systimer.*(.literal .literal.* .text .text.*) + *libzephyr.a:mspi_timing_config.*(.literal .literal.* .text .text.*) + *libzephyr.a:mspi_timing_tuning.*(.literal .literal.* .text .text.*) + *(.literal.sar_periph_ctrl_power_enable .text.sar_periph_ctrl_power_enable) + + /* [mapping:soc_pm] */ + *(.literal.GPIO_HOLD_MASK .text.GPIO_HOLD_MASK) + + /* [mapping:esp_rom] */ + *libzephyr.a:esp_rom_spiflash.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_systimer.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_wdt.*(.literal .literal.* .text .text.*) + + *libzephyr.a:esp_rom_crc.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_sys.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_uart.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_spiflash.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_efuse.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_systimer.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_regi2c_esp32c6.*(.literal .literal.* .text .text.*) + *libzephyr.a:efuse_hal.*(.literal .literal.* .text .text.*) + + /* [mapping:esp_mm] */ + *libzephyr.a:esp_cache.*(.literal .literal.* .text .text.*) + *libzephyr.a:cache_utils.*(.literal .text .literal.* .text.*) + +#if defined(CONFIG_ESP32_WIFI_IRAM_OPT) + *libnet80211.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.*) + *libpp.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.*) + *libcoexist.a:(.wifi_slp_iram .wifi_slp_iram.*) + + /* [mapping:esp_wifi] */ + *(.literal.wifi_clock_enable_wrapper .text.wifi_clock_enable_wrapper) + *(.literal.wifi_clock_disable_wrapper .text.wifi_clock_disable_wrapper) + + /* [mapping:esp_phy] */ + *(.literal.esp_phy_enable .text.esp_phy_enable) + *(.literal.esp_phy_disable .text.esp_phy_disable) + *(.literal.esp_wifi_bt_power_domain_off .text.esp_wifi_bt_power_domain_off) +#endif /* CONFIG_ESP32_WIFI_IRAM_OPT */ + +#if defined(CONFIG_ESP32_WIFI_RX_IRAM_OPT) + *libnet80211.a:( .wifirxiram .wifirxiram.* .wifislprxiram .wifislprxiram.*) + *libpp.a:( .wifirxiram .wifirxiram.* .wifislprxiram .wifislprxiram.*) +#endif /* CONFIG_ESP32_WIFI_RX_IRAM_OPT */ + + . = ALIGN(4) + 16; + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + +#ifdef CONFIG_ESP_SIMPLE_BOOT + .loader.text : + { + . = ALIGN(4); + _loader_text_start = ABSOLUTE(.); + *libzephyr.a:bootloader_soc.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_init.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_esp32c6.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_clock_init.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_wdt.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_flash.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_flash_config_esp32c6.*(.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_panic.*(.literal .text .literal.* .text.*) + *libzephyr.a:bootloader_mem.*(.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.*(.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:esp_image_format.*(.literal .text .literal.* .text.*) + *libzephyr.a:flash_ops.*(.literal .text .literal.* .text.*) + *libzephyr.a:flash_ops_esp32c6.*(.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:spi_flash_hal.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_hal_common.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_flash_api.*(.literal .text .literal.* .text.*) + *libzephyr.a:esp_flash_spi_init.*(.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: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:cpu_region_protect.*(.literal .text .literal.* .text.*) + + /* TODO: optimise */ + *libzephyr.a:esp_gpio_reserve.*(.literal .text .literal.* .text.*) + + . = ALIGN(4) + 16; + _loader_text_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) +#endif /* CONFIG_ESP_SIMPLE_BOOT */ + + .iram0.text_end (NOLOAD) : + { + /* C3 memprot requires 512 B alignment for split lines */ + . = ALIGN(16); + _iram_text_end = ABSOLUTE(.); + } GROUP_LINK_IN(RAMABLE_REGION) + + .iram0.data : + { + . = ALIGN(16); + *(.iram.data) + *(.iram.data*) + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + + .iram0.bss (NOLOAD) : + { + . = ALIGN(16); + *(.iram.bss) + *(.iram.bss*) + + . = ALIGN(16); + _iram_end = ABSOLUTE(.); + . = ALIGN(16) + 16; + } GROUP_LINK_IN(RAMABLE_REGION) + + /* --- END OF IRAM --- */ + + /* --- START OF DRAM --- */ + + .dram0.data : + { + . = ALIGN(4); + _data_start = ABSOLUTE(.); + __data_start = ABSOLUTE(.); + + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + *(.data1) + +#ifdef CONFIG_RISCV_GP + . = ALIGN(8); + __global_pointer$ = . + 0x800; +#endif /* CONFIG_RISCV_GP */ + + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + + /* All dependent functions should be placed in DRAM to avoid issue + * when flash cache is disabled */ + *libkernel.a:fatal.*(.rodata .rodata.* .srodata .srodata.*) + *libkernel.a:init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:cbprintf_complete*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:log_core.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:log_backend_uart.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:log_output.*(.rodata .rodata.* .srodata .srodata.*) + *libdrivers__flash.a:flash_esp32.*(.rodata .rodata.* .srodata .srodata.*) + *libdrivers__serial.a:uart_esp32.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_rom_patch.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:periph_ctrl.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:loader.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:cache_utils.*(.rodata .rodata.* .srodata .srodata.*) + + /* [mapping:hal] */ + *libzephyr.a:mmu_hal.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_hal_iram.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_encrypt_hal_iram.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:cache_hal.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:ledc_hal_iram.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:i2c_hal_iram.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:wdt_hal_iram.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:systimer_hal.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_hal_gpspi.*(.rodata .rodata.* .srodata .srodata.*) + + /* [mapping:soc] */ + *libzephyr.a:lldesc.*(.rodata .rodata.* .srodata .srodata.*) + + /* [mapping:log] */ + *(.rodata.esp_log_write) + *(.rodata.esp_log_timestamp) + *(.rodata.esp_log_early_timestamp) + *(.rodata.esp_log_impl_lock) + *(.rodata.esp_log_impl_lock_timeout) + *(.rodata.esp_log_impl_unlock) + + /* [mapping:spi_flash] */ + *libzephyr.a:spi_flash_chip_boya.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_chip_gd.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_chip_generic.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_chip_issi.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_chip_mxic.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_chip_mxic_opi.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_chip_th.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_chip_winbond.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:memspi_host_driver.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:flash_brownout_hook.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_wrap.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_hpm_enable.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_oct_flash_init.*(.rodata .rodata.* .srodata .srodata.*) + + /* [mapping:esp_mm] */ + *libzephyr.a:esp_cache.*(.rodata .rodata.* .srodata .srodata.*) + + /* [mapping:esp_hw_support] */ + *(.rodata.esp_cpu_stall) + *(.rodata.esp_cpu_unstall) + *(.rodata.esp_cpu_reset) + *(.rodata.esp_cpu_wait_for_intr) + *(.rodata.esp_cpu_compare_and_set) + *(.rodata.esp_gpio_reserve_pins) + *(.rodata.esp_gpio_is_pin_reserved) + *(.rodata.rtc_vddsdio_get_config) + *(.rodata.rtc_vddsdio_set_config) + *libzephyr.a:esp_memory_utils.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:rtc_clk.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:rtc_clk_init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:systimer.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:mspi_timing_config.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:mspi_timing_tuning.*(.rodata .rodata.* .srodata .srodata.*) + *(.rodata.sar_periph_ctrl_power_enable) + *libzephyr.a:pmu_init.*(.rodata .rodata.* .srodata .srodata.*) + + /* [mapping:esp_system] */ + *libzephyr.a:reset_reason.*(.rodata .rodata.*) + *libzephyr.a:esp_err.*(.rodata .rodata.*) + *(.rodata.esp_system_abort) + + /* [mapping:esp_rom] */ + *libzephyr.a:esp_rom_crc.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_rom_sys.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_rom_uart.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_rom_spiflash.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_rom_efuse.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_rom_systimer.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_rom_regi2c_esp32c6.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:efuse_hal.*(.rodata .rodata.* .srodata .srodata.*) + + . = ALIGN(4); + #include + . = ALIGN(4); + + KEEP(*(.jcr)) + *(.dram1 .dram1.*) + . = ALIGN(4); + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + +#ifdef CONFIG_ESP_SIMPLE_BOOT + /* Secondary loader sections */ + .loader.data : + { + . = ALIGN(4); + _loader_data_start = ABSOLUTE(.); + *libzephyr.a:bootloader_soc.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:bootloader_init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:bootloader_esp32c6.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:bootloader_clock_init.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:bootloader_wdt.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:bootloader_flash.*(.srodata .srodata.* .rodata .rodata.*) + *libzephyr.a:bootloader_flash_config_esp32c6.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:bootloader_clock_loader.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:bootloader_common_loader.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:bootloader_panic.*(.rodata .rodata.* .srodata .srodata.*) + + *libzephyr.a:cpu_region_protect.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:clk.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_clk.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:flash_mmap.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:flash_ops.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:flash_ops_esp32c6.*(.rodata .rodata.* .srodata .srodata.*) + + *libzephyr.a:esp_gpio_reserve.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_hal.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:spi_flash_hal_common.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_flash_api.*(.rodata .rodata.* .srodata .srodata.*) + *libzephyr.a:esp_flash_spi_init.*(.rodata .rodata.* .srodata .srodata.*) + + . = ALIGN(16); + _loader_data_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) +#endif /* CONFIG_ESP_SIMPLE_BOOT */ + + #include + #include + #include + #include + + /* 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 + #pragma pop_macro("GROUP_ROM_LINK_IN") + + .dram0.end : + { + . = ALIGN(4); + _data_end = ABSOLUTE(.); + __data_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + + .dram0.noinit (NOLOAD): + { + . = ALIGN(4); + *(.noinit) + *(.noinit.*) + . = ALIGN(4); + } GROUP_LINK_IN(RAMABLE_REGION) + + /* Shared RAM */ + .dram0.bss (NOLOAD) : + { + . = ALIGN (8); + __bss_start = ABSOLUTE(.); + _bss_start = ABSOLUTE(.); + + /* bluetooth library requires this symbol to be defined */ + _btdm_bss_start = ABSOLUTE(.); + *libbtdm_app.a:(.bss .bss.* COMMON) + . = ALIGN (4); + _btdm_bss_end = ABSOLUTE(.); + + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.bss) + *(.bss.*) + *(.share.mem) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (16); + __bss_end = ABSOLUTE(.); + _bss_end = ABSOLUTE(.); + } GROUP_LINK_IN(RAMABLE_REGION) + + /* Provide total SRAM usage, including IRAM and DRAM */ + _image_ram_start = _iram_start; + #include + + ASSERT(((__bss_end - ORIGIN(sram0_0_seg)) <= LENGTH(sram0_0_seg)), "DRAM segment data does not fit.") + + /* --- END OF DRAM --- */ + + /* --- START OF .flash.text --- */ + + .flash.align_text (NOLOAD): + { + /* Subsequent segment lma align */ + . = ALIGN(CACHE_ALIGN); + } GROUP_LINK_IN(ROMABLE_REGION) + + /* Symbols used during the application memory mapping */ + _image_irom_start = LOADADDR(.flash.text); + _image_irom_size = SIZEOF(.flash.text); + _image_irom_vaddr = ADDR(.flash.text); + + .flash.text : ALIGN(0x10) + { + _stext = .; + _instruction_reserved_start = ABSOLUTE(.); + _text_start = ABSOLUTE(.); + _instruction_reserved_start = ABSOLUTE(.); + +#if !defined(CONFIG_ESP32_WIFI_IRAM_OPT) + *libnet80211.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.*) + *libpp.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.*) +#endif /* CONFIG_ESP32_WIFI_IRAM_OPT */ + +#if !defined(CONFIG_ESP32_WIFI_RX_IRAM_OPT) + *libnet80211.a:( .wifirxiram .wifirxiram.* .wifislprxiram .wifislprxiram.*) + *libpp.a:( .wifirxiram .wifirxiram.* .wifislprxiram .wifislprxiram.*) +#endif /* CONFIG_ESP32_WIFI_RX_IRAM_OPT */ + + *(.literal .text .literal.* .text.*) + *(.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; + + _instruction_reserved_end = ABSOLUTE(.); + _text_end = ABSOLUTE(.); + _instruction_reserved_end = ABSOLUTE(.); + _etext = .; + + } GROUP_DATA_LINK_IN(CACHED_REGION, ROMABLE_REGION) + + /* --- END OF .flash.text --- */ + + /* --- START OF .rodata --- */ + + /* Align next section to 64k to allow mapping */ + .flash.align_rodata (NOLOAD) : + { + /* Subsequent segment lma and vma align */ + . = ALIGN(CACHE_ALIGN); + } GROUP_DATA_LINK_IN(CACHED_REGION, ROMABLE_REGION) + + .flash.align_rom (NOLOAD) : + { + . = ALIGN(CACHE_ALIGN); + } GROUP_LINK_IN(ROMABLE_REGION) + + /* Symbols used during the application memory mapping */ + _image_drom_start = LOADADDR(.flash.rodata); + _image_drom_size = _image_rodata_end - _image_rodata_start; + _image_drom_vaddr = ADDR(.flash.rodata); + + .flash.rodata : ALIGN(0x10) + { + _rodata_reserved_start = ABSOLUTE(.); + _image_rodata_start = ABSOLUTE(.); + _rodata_start = ABSOLUTE(.); + + *(.rodata_desc .rodata_desc.*) + *(.rodata_custom_desc .rodata_custom_desc.*) + + __rodata_region_start = ABSOLUTE(.); + + . = ALIGN(4); + #include + + *(.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) + __rodata_region_end = .; + _rodata_end = ABSOLUTE(.); + /* Literals are also RO data. */ + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + . = ALIGN(4); + *(.srodata) + *(.srodata.*) + *(.rodata) + *(.rodata.*) + *(.rodata_wlog) + *(.rodata_wlog*) + . = ALIGN(4); + } GROUP_DATA_LINK_IN(CACHED_REGION, ROMABLE_REGION) + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + /* 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 */ + .flash.rodata_end : ALIGN(0x10) + { + . = ALIGN(4); + _rodata_reserved_end = ABSOLUTE(.); + _image_rodata_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(CACHED_REGION, ROMABLE_REGION) + + /* --- END OF .rodata --- */ + +#ifdef CONFIG_GEN_ISR_TABLES + #include +#endif + + #include + /DISCARD/ : { *(.note.GNU-stack) } + + SECTION_PROLOGUE(.riscv.attributes, 0,) + { + KEEP(*(.riscv.attributes)) + KEEP(*(.gnu.attributes)) + } +} diff --git a/soc/espressif/esp32c6/idle.c b/soc/espressif/esp32c6/idle.c new file mode 100644 index 00000000000..a42691c540f --- /dev/null +++ b/soc/espressif/esp32c6/idle.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/** + * @brief Power save idle routine + * + * This function will be called by the kernel idle loop or possibly within + * an implementation of _pm_save_idle in the kernel when the + * '_pm_save_flag' variable is non-zero. + */ +void arch_cpu_idle(void) +{ + /* curiously it arrives here with the interrupts masked + * so umask it before wait for an event + */ + arch_irq_unlock(MSTATUS_IEN); + + /* Wait for interrupt */ + __asm__ volatile("wfi"); +} diff --git a/soc/espressif/esp32c6/mcuboot.ld b/soc/espressif/esp32c6/mcuboot.ld new file mode 100644 index 00000000000..ac87f871847 --- /dev/null +++ b/soc/espressif/esp32c6/mcuboot.ld @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include "memory.h" + +/* Disable all romable LMA */ +#undef GROUP_DATA_LINK_IN +#define GROUP_DATA_LINK_IN(vregion, lregion) > vregion + +#define RAMABLE_REGION dram_seg +#define RODATA_REGION dram_seg +#define ROMABLE_REGION dram_seg + +/* Global symbols required for espressif hal build */ +MEMORY +{ + iram_seg (RX) : org = BOOTLOADER_IRAM_SEG_START, + len = BOOTLOADER_IRAM_SEG_LEN + iram_loader_seg (RX) : org = BOOTLOADER_IRAM_LOADER_SEG_START, + len = BOOTLOADER_IRAM_LOADER_SEG_LEN + dram_seg (RW) : org = BOOTLOADER_DRAM_SEG_START, + len = BOOTLOADER_DRAM_SEG_LEN + +#ifdef CONFIG_GEN_ISR_TABLES + IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000 +#endif +} + +/* Default entry point: */ +ENTRY(CONFIG_KERNEL_ENTRY) + +SECTIONS +{ + .iram0.loader_text : + { + . = ALIGN (16); + _loader_text_start = ABSOLUTE(.); + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + + *libapp.a:flash_map_extended.*(.literal .text .literal.* .text.*) + *libzephyr.a:cbprintf_nano.*(.literal .text .literal.* .text.*) + *libzephyr.a:cpu.*(.literal .text .literal.* .text.*) + *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*) + *libzephyr.a:cache_hal.*(.literal .text .literal.* .text.*) + *libzephyr.a:flash_map.*(.literal .text .literal.* .text.*) + *libzephyr.a:esp_rom_spiflash.*(.literal .text .literal.* .text.*) + + *libzephyr.a:heap.*(.literal .text .literal.* .text.*) + + *libkernel.a:kheap.*(.literal .text .literal.* .text.*) + *libkernel.a:mempool.*(.literal .text .literal.* .text.*) + + *(.literal.bootloader_mmap .text.bootloader_mmap) + *(.literal.bootloader_munmap .text.bootloader_munmap) + + *libzephyr.a:esp_loader.*(.literal .text .literal.* .text.*) + *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*) + + *(.literal.esp_intr_disable .literal.esp_intr_disable.* .text.esp_intr_disable .text.esp_intr_disable.*) + *(.literal.default_intr_handler .text.default_intr_handler .iram1.*.default_intr_handler) + *(.literal.esp_log_timestamp .text.esp_log_timestamp) + *(.literal.esp_log_early_timestamp .text.esp_log_early_timestamp) + *(.literal.esp_system_abort .text.esp_system_abort) + + *(.fini.literal) + *(.fini) + *(.gnu.version) + _loader_text_end = ABSOLUTE(.); + _iram_end = ABSOLUTE(.); + } > iram_loader_seg + + .iram0.text : + { + /* Vectors go to IRAM */ + _iram_start = ABSOLUTE(.); + _init_start = ABSOLUTE(.); + __text_region_start = ABSOLUTE(.); + + KEEP(*(.exception_vectors.text)); + . = ALIGN(256); + + _invalid_pc_placeholder = ABSOLUTE(.); + + _iram_text_start = ABSOLUTE(.); + + KEEP(*(.exception.entry*)); /* contains _isr_wrapper */ + *(.exception.other*) + . = ALIGN(4); + + *(.entry.text) + *(.init.literal) + *(.init) + . = ALIGN(4); + *(.iram1 .iram1.*) + *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text) + + /* C3 memprot requires 512 B alignment for split lines */ + . = ALIGN (16); + _init_end = ABSOLUTE(.); + . = ALIGN(16); + *(.iram.data) + *(.iram.data*) + . = ALIGN(16); + *(.iram.bss) + *(.iram.bss*) + + . = ALIGN(16); + + *(.literal .text .literal.* .text.*) + *(.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(.); + __text_region_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); + } > iram_seg + + .dram0.data : + { + . = ALIGN(4); + __data_start = ABSOLUTE(.); + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + *(.data1) +#ifdef CONFIG_RISCV_GP + __global_pointer$ = . + 0x800; +#endif /* CONFIG_RISCV_GP */ + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + *libzephyr.a:mmu_hal.*(.rodata .rodata.*) + *libzephyr.a:rtc_clk.*(.rodata .rodata.*) + KEEP(*(.jcr)) + *(.dram1 .dram1.*) + . = ALIGN(4); + + #include + . = ALIGN(4); + + *(.rodata_desc .rodata_desc.*) + *(.rodata_custom_desc .rodata_custom_desc.*) + + . = ALIGN(4); + #include + . = 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) + __rodata_region_end = .; + _rodata_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.*) + *(.srodata) + *(.srodata.*) + *(.rodata) + *(.rodata.*) + *(.rodata_wlog) + *(.rodata_wlog*) + _thread_local_end = ABSOLUTE(.); + /* _rodata_reserved_end = ABSOLUTE(.); */ + . = ALIGN(4); + } > dram_seg + + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + + #include + + .noinit (NOLOAD): + { + . = ALIGN(4); + *(.noinit) + *(.noinit.*) + . = ALIGN(4); + } > dram_seg + + /* Shared RAM */ + .bss (NOLOAD): + { + . = ALIGN (8); + _bss_start = ABSOLUTE(.); + __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(.); + _bss_end = ABSOLUTE(.); + } > dram_seg + + /* linker rel sections*/ + #include + +#ifdef CONFIG_GEN_ISR_TABLES + #include +#endif + +#include + /DISCARD/ : { *(.note.GNU-stack) } + + SECTION_PROLOGUE(.riscv.attributes, 0,) + { + KEEP(*(.riscv.attributes)) + KEEP(*(.gnu.attributes)) + } +} diff --git a/soc/espressif/esp32c6/memory.h b/soc/espressif/esp32c6/memory.h new file mode 100644 index 00000000000..500325545f0 --- /dev/null +++ b/soc/espressif/esp32c6/memory.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +/* LP-SRAM (16kB) memory */ +#define LPSRAM_IRAM_START 0x50000000 +#define LPSRAM_SIZE 0x4000 +/* HP-SRAM (512kB) memory */ +#define HPSRAM_START 0x40800000 +#define HPSRAM_SIZE 0x80000 +#define HPSRAM_DRAM_START 0x40800000 +#define HPSRAM_IRAM_START 0x40800000 +/* ICache size is fixed to 32KB on ESP32-C6 */ +#define ICACHE_SIZE 0x8000 + +/** Simplified memory map for the bootloader. + * Make sure the bootloader can load into main memory without overwriting itself. + * + * ESP32-C6 ROM static data usage is as follows: + * - 0x4086ad08 - 0x4087c610: Shared buffers, used in UART/USB/SPI download mode only + * - 0x4087c610 - 0x4087e610: PRO CPU stack, can be reclaimed as heap after RTOS startup + * - 0x4087e610 - 0x40880000: ROM .bss and .data (not easily reclaimable) + * + * The 2nd stage bootloader can take space up to the end of ROM shared + * buffers area (0x4087c610). + */ + +#define DRAM_BUFFERS_START 0x4086ad08 +#define DRAM_STACK_START 0x4087c610 +#define DRAM_ROM_BSS_DATA_START 0x4087e610 + +/* For safety margin between bootloader data section and startup stacks */ +#define BOOTLOADER_STACK_OVERHEAD 0x0 +/* These lengths can be adjusted, if necessary: FIXME: optimize ram usage */ +#define BOOTLOADER_DRAM_SEG_LEN 0xA000 +#define BOOTLOADER_IRAM_LOADER_SEG_LEN 0x3000 +#define BOOTLOADER_IRAM_SEG_LEN 0xC000 + +/* Base address used for calculating memory layout + * counted from Dbus backwards and back to the Ibus + */ +#define BOOTLOADER_USER_SRAM_END (DRAM_BUFFERS_START - BOOTLOADER_STACK_OVERHEAD) + +/* Start of the lower region is determined by region size and the end of the higher region */ +#define BOOTLOADER_IRAM_LOADER_SEG_START \ + (BOOTLOADER_USER_SRAM_END - BOOTLOADER_IRAM_LOADER_SEG_LEN) +#define BOOTLOADER_IRAM_SEG_START (BOOTLOADER_IRAM_LOADER_SEG_START - BOOTLOADER_IRAM_SEG_LEN) +#define BOOTLOADER_DRAM_SEG_START (BOOTLOADER_IRAM_SEG_START - BOOTLOADER_DRAM_SEG_LEN) + +/* Flash */ +#ifdef CONFIG_FLASH_SIZE +#define FLASH_SIZE CONFIG_FLASH_SIZE +#else +#define FLASH_SIZE 0x400000 +#endif + +/* Cached memory */ +#define CACHE_ALIGN CONFIG_MMU_PAGE_SIZE +#define CACHED_ORG 0x42000000 +#define CACHED_SIZE FLASH_SIZE diff --git a/soc/espressif/esp32c6/pinctrl_soc.h b/soc/espressif/esp32c6/pinctrl_soc.h new file mode 100644 index 00000000000..2a92315fc9e --- /dev/null +++ b/soc/espressif/esp32c6/pinctrl_soc.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * ESP32C6 SoC specific helpers for pinctrl driver + */ + +#ifndef ZEPHYR_SOC_RISCV_ESP32C6_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_RISCV_ESP32C6_PINCTRL_SOC_H_ + +#include +#include + +#include + +/** @cond INTERNAL_HIDDEN */ + +/** Type for ESP32 pin. */ +typedef struct pinctrl_soc_pin { + /** Pinmux settings (pin, direction and signal). */ + uint32_t pinmux; + /** Pincfg settings (bias). */ + uint32_t pincfg; +} 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_RISCV_ESP32C6_PINCTRL_SOC_H_ */ diff --git a/soc/espressif/esp32c6/soc.c b/soc/espressif/esp32c6/soc.c new file mode 100644 index 00000000000..4bdfacbc057 --- /dev/null +++ b/soc/espressif/esp32c6/soc.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Include esp-idf headers first to avoid redefining BIT() macro */ +#include +#include +#include +#include +#include "hal/wdt_hal.h" +#include "esp_cpu.h" +#include "hal/soc_hal.h" +#include "hal/cpu_hal.h" +#include "esp_timer.h" +#include "esp_private/system_internal.h" +#include "esp_clk_internal.h" +#include +#include +#include "esp_private/esp_mmu_map_private.h" + +#include + +#include +#include +#include +#include +#include + +/* + * 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) +{ + __asm__ __volatile__("la t0, _esp32c6_vector_table\n" + "csrw mtvec, t0\n"); + + z_bss_zero(); + + /* Disable normal interrupts. */ + csr_read_clear(mstatus, MSTATUS_MIE); + + esp_reset_reason_init(); + +#ifndef CONFIG_MCUBOOT + /* ESP-IDF 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 = &LP_WDT}; + + wdt_hal_write_protect_disable(&rtc_wdt_ctx); + wdt_hal_disable(&rtc_wdt_ctx); + wdt_hal_write_protect_enable(&rtc_wdt_ctx); + + /* Configures the CPU clock, RTC slow and fast clocks, and performs + * RTC slow clock calibration. + */ + esp_clk_init(); + + esp_timer_early_init(); + +#if CONFIG_SOC_FLASH_ESP32 + spi_flash_guard_set(&g_flash_guard_default_ops); +#endif + + esp_mmu_map_init(); + +#endif /* !CONFIG_MCUBOOT */ + + /*Initialize the esp32c6 interrupt controller */ + 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(); +} diff --git a/soc/espressif/esp32c6/soc.h b/soc/espressif/esp32c6/soc.h new file mode 100644 index 00000000000..bfa56449777 --- /dev/null +++ b/soc/espressif/esp32c6/soc.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __SOC_H__ +#define __SOC_H__ + +#ifndef _ASMLANGUAGE +#include +#include +#include +#include +#include +#include +#endif + +/* ECALL Exception numbers */ +#define SOC_MCAUSE_ECALL_EXP 11 /* Machine ECALL instruction */ +#define SOC_MCAUSE_USER_ECALL_EXP 8 /* User ECALL instruction */ + +/* Interrupt Mask */ +#define SOC_MCAUSE_IRQ_MASK (1 << 31) +/* Exception code Mask */ +#define SOC_MCAUSE_EXP_MASK 0x7FFFFFFF + +#ifndef _ASMLANGUAGE + +void __esp_platform_start(void); + +static inline uint32_t esp_core_id(void) +{ + return 0; +} + +extern void esp_reset_reason_init(void); +extern void esp_rom_route_intr_matrix(int cpu_no, uint32_t model_num, uint32_t intr_num); +extern void esp_rom_intr_matrix_set(int cpu_no, uint32_t model_num, uint32_t intr_num); +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_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_ets_set_user_start(uint32_t start); +extern void esprv_intc_int_set_threshold(int priority_threshold); +uint32_t soc_intr_get_next_source(void); +extern void esp_rom_Cache_Resume_ICache(uint32_t autoload); +extern int esp_rom_Cache_Invalidate_Addr(uint32_t addr, uint32_t size); +extern uint32_t esp_rom_Cache_Suspend_ICache(void); +extern void esp_rom_Cache_Invalidate_ICache_All(void); +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); + +#endif /* _ASMLANGUAGE */ + +#endif /* __SOC_H__ */ diff --git a/soc/espressif/esp32c6/soc_irq.S b/soc/espressif/esp32c6/soc_irq.S new file mode 100644 index 00000000000..c1ad164c153 --- /dev/null +++ b/soc/espressif/esp32c6/soc_irq.S @@ -0,0 +1,26 @@ +/* Copyright 2021 Espressif Systems (Shanghai) PTE LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/* Exports */ +GTEXT(__soc_is_irq) +GTEXT(__soc_handle_irq) +GTEXT(soc_intr_get_next_source) + +SECTION_FUNC(exception.other, __soc_is_irq) + csrr a0, mcause + srli a0, a0, 31 + ret + +SECTION_FUNC(exception.other, __soc_handle_irq) + addi sp, sp,-4 + sw ra, 0x00(sp) + la t1, soc_intr_get_next_source + jalr ra, t1, 0 + lw ra, 0x00(sp) + addi sp, sp, 4 + ret diff --git a/soc/espressif/esp32c6/soc_irq.c b/soc/espressif/esp32c6/soc_irq.c new file mode 100644 index 00000000000..42e5e47eaf2 --- /dev/null +++ b/soc/espressif/esp32c6/soc_irq.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define ESP32C6_INTSTATUS_SLOT1_THRESHOLD 32 + +void arch_irq_enable(unsigned int irq) +{ + esp_intr_enable(irq); +} + +void arch_irq_disable(unsigned int irq) +{ + esp_intr_disable(irq); +} + +int arch_irq_is_enabled(unsigned int irq) +{ + bool res = false; + uint32_t key = irq_lock(); + + if (irq < 32) { + res = esp_intr_get_enabled_intmask(0) & BIT(irq); + } else { + res = esp_intr_get_enabled_intmask(1) & BIT(irq - 32); + } + + irq_unlock(key); + + return res; +} + +uint32_t soc_intr_get_next_source(void) +{ + uint32_t status; + uint32_t source; + + status = REG_READ(INTMTX_CORE0_INT_STATUS_REG_0_REG) & + esp_intr_get_enabled_intmask(0); + + if (status) { + source = __builtin_ffs(status) - 1; + } else { + status = REG_READ(INTMTX_CORE0_INT_STATUS_REG_1_REG) & + esp_intr_get_enabled_intmask(1); + source = (__builtin_ffs(status) - 1 + ESP32C6_INTSTATUS_SLOT1_THRESHOLD); + } + + return source; +} diff --git a/soc/espressif/esp32c6/vectors.S b/soc/espressif/esp32c6/vectors.S new file mode 100644 index 00000000000..d248c0b49b5 --- /dev/null +++ b/soc/espressif/esp32c6/vectors.S @@ -0,0 +1,35 @@ +/* Copyright 2023 Espressif Systems (Shanghai) PTE LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/soc.h" +#include "soc/interrupt_reg.h" +#include "riscv/rvruntime-frames.h" +#include "soc/soc_caps.h" +#include + +/* Imports */ +GTEXT(_isr_wrapper) + + /* This is the vector table. MTVEC points here. + * + * Use 4-byte intructions here. 1 instruction = 1 entry of the table. + * The CPU jumps to MTVEC (i.e. the first entry) in case of an exception, + * and (MTVEC & 0xfffffffc) + (mcause & 0x7fffffff) * 4, in case of an interrupt. + * + * Note: for our CPU, we need to place this on a 256-byte boundary, as CPU + * only uses the 24 MSBs of the MTVEC, i.e. (MTVEC & 0xffffff00). + */ + + .global _esp32c6_vector_table + .section .exception_vectors.text + .balign 0x100 + .type _esp32c6_vector_table, @function + +_esp32c6_vector_table: + .option push + .option norvc + .rept (32) + j _isr_wrapper /* 32 identical entries, all pointing to the interrupt handler */ + .endr diff --git a/soc/espressif/soc.yml b/soc/espressif/soc.yml index 13f6092e311..c553b3e9aed 100644 --- a/soc/espressif/soc.yml +++ b/soc/espressif/soc.yml @@ -19,3 +19,6 @@ family: - name: esp32c3 socs: - name: esp32c3 + - name: esp32c6 + socs: + - name: esp32c6