From 0c4cf75c35c3b1aa26994ca9bfb311a39e6fc749 Mon Sep 17 00:00:00 2001 From: "C.S.M" Date: Wed, 26 Nov 2025 19:34:39 +0800 Subject: [PATCH] feat(esp32s31): Introduce esp32s31 hello world --- .gitlab/ci/default-build-test-rules.yml | 1 + components/bootloader/Kconfig.projbuild | 3 +- .../main/ld/esp32s31/bootloader.ld.in | 334 ++++++++++++++++++ .../main/ld/esp32s31/bootloader.rom.ld | 6 + .../src/bootloader_flash_config_esp32s31.c | 324 +++++++++++++++++ .../include/esp_app_format.h | 1 + .../src/bootloader_clock_init.c | 2 + .../bootloader_support/src/bootloader_efuse.c | 2 + .../src/esp32s31/bootloader_esp32s31.c | 91 +++++ .../src/esp32s31/bootloader_soc.c | 17 + components/esp_driver_uart/src/uart.c | 3 + components/esp_hal_wdt/linker.lf | 9 +- .../esp_mm/port/esp32s31/ext_mem_layout.c | 36 ++ components/esp_pm/CMakeLists.txt | 6 +- components/esp_security/src/esp32s31/.gitkeep | 0 .../src/esp32s31/esp_crypto_clk.h | 16 + .../port/soc/esp32s31/system_internal.c | 4 +- components/hal/esp32s31/include/hal/uart_ll.h | 27 +- components/heap/port/esp32s31/memory_layout.c | 113 ++++++ components/soc/esp32s31/gpio_periph.c | 1 + .../spi_flash/esp32s31/Kconfig.flash_freq | 16 + .../spi_flash/esp32s31/Kconfig.soc_caps.in | 12 + .../spi_flash/esp32s31/flash_vendor_caps.h | 9 + tools/ci/build_template_app.sh | 4 +- 24 files changed, 1012 insertions(+), 25 deletions(-) create mode 100644 components/bootloader/subproject/main/ld/esp32s31/bootloader.ld.in create mode 100644 components/bootloader/subproject/main/ld/esp32s31/bootloader.rom.ld create mode 100644 components/bootloader_support/src/esp32s31/bootloader_esp32s31.c create mode 100644 components/bootloader_support/src/esp32s31/bootloader_soc.c delete mode 100644 components/esp_security/src/esp32s31/.gitkeep create mode 100644 components/esp_security/src/esp32s31/esp_crypto_clk.h create mode 100644 components/spi_flash/esp32s31/Kconfig.flash_freq create mode 100644 components/spi_flash/esp32s31/Kconfig.soc_caps.in create mode 100644 components/spi_flash/esp32s31/flash_vendor_caps.h diff --git a/.gitlab/ci/default-build-test-rules.yml b/.gitlab/ci/default-build-test-rules.yml index 62b2bf09d0..0df40e42c8 100644 --- a/.gitlab/ci/default-build-test-rules.yml +++ b/.gitlab/ci/default-build-test-rules.yml @@ -13,6 +13,7 @@ bypass_check_test_targets: - esp32h21 - esp32h4 - esp32c5 + - esp32s31 # # These lines would diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index 917f04cc8c..b39cb883e5 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -8,7 +8,7 @@ menu "Bootloader config" hex default 0x1000 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 # the first 2 sectors are reserved for the key manager with AES-XTS (flash encryption) purpose - default 0x2000 if IDF_TARGET_ESP32P4 || IDF_TARGET_ESP32C5 || IDF_TARGET_ESP32H4 + default 0x2000 if IDF_TARGET_ESP32P4 || IDF_TARGET_ESP32C5 || IDF_TARGET_ESP32H4 || IDF_TARGET_ESP32S31 default 0x0 help Offset address that 2nd bootloader will be flashed to. @@ -175,6 +175,7 @@ menu "Bootloader config" range 0 30 if IDF_TARGET_ESP32C6 range 0 27 if IDF_TARGET_ESP32H2 range 0 54 if IDF_TARGET_ESP32P4 + range 0 62 if IDF_TARGET_ESP32S31 default 4 help The selected GPIO will be configured as an input with internal pull-up enabled. To trigger a factory diff --git a/components/bootloader/subproject/main/ld/esp32s31/bootloader.ld.in b/components/bootloader/subproject/main/ld/esp32s31/bootloader.ld.in new file mode 100644 index 0000000000..27a8d0276e --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32s31/bootloader.ld.in @@ -0,0 +1,334 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** Simplified memory map for the bootloader. + * Make sure the bootloader can load into main memory without overwriting itself. + * + * ESP32-S31 ROM static data usage is as follows: + * - 0x2f0696b0 - 0x2f07afb0: Shared buffers, used in UART/USB/SPI download mode only + * - 0x2f07afb0 - 0x2f07cfb0: PRO CPU stack, can be reclaimed as heap after RTOS startup + * - 0x2f07cfb0 - 0x2f080000: ROM .bss and .data (not easily reclaimable) + * + * The 2nd stage bootloader can take space up to the end of ROM shared + * buffers area (0x2f07afb0). + */ + +/* We consider 0x2f07afb0 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, + * and work out iram_seg and iram_loader_seg addresses from there, backwards. + */ + + +/* These lengths can be adjusted, if necessary: */ +bootloader_usable_dram_end = 0x2f07afb0; +bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ +bootloader_dram_seg_len = 0x5000; +bootloader_iram_loader_seg_len = 0x7000; +bootloader_iram_seg_len = 0x2D00; + +/* Start of the lower region is determined by region size and the end of the higher region */ +bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; +bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; +bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; +bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; + +MEMORY +{ + iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len + iram_loader_seg (RWX) : 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 +} + +/* The app may use RAM for static allocations up to the start of iram_loader_seg. + * If you have changed something above and this assert fails: + * 1. Check what the new value of bootloader_iram_loader_seg start is. + * 2. Update the value in this assert. + * 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32s31/memory.ld.in to the same value. + */ +ASSERT(bootloader_iram_loader_seg_start == 0x2f06cfb0, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); + +/* Default entry point: */ +ENTRY(call_start_cpu0); + +SECTIONS +{ + + .iram_loader.text : + { + . = ALIGN (16); + _loader_text_start = ABSOLUTE(.); + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ + *liblog.a:(.literal .text .literal.* .text.*) + /* we use either libgcc or compiler-rt, so put similar entries for them here */ + *libgcc.a:(.literal .text .literal.* .text.*) + *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) + *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) + *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) + *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) + *libspi_flash.a:*.*(.literal .text .literal.* .text.*) + *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) + *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) + *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) + *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) + *libhal.a:huk_hal.*(.literal .text .literal.* .text.*) + *libhal.a:key_mgr_hal.*(.literal .text .literal.* .text.*) + *libesp_security.a:esp_key_mgr.*(.literal .text .literal.* .text.*) + *libesp_security.a:esp_crypto_periph_clk.*(.literal .text .literal.* .text.*) + *libesp_security.a:esp_crypto_lock.*(.literal .text .literal.* .text.*) + *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) + *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) + *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) + *libefuse.a:*.*(.literal .text .literal.* .text.*) + *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) + *(.fini.literal) + *(.fini) + *(.gnu.version) + _loader_text_end = ABSOLUTE(.); + } > iram_loader_seg + + .iram.text : + { + . = ALIGN (16); + *(.entry.text) + *(.init.literal) + *(.init) + } > iram_seg + + + /* Shared RAM */ + .dram0.bss (NOLOAD) : + { + . = ALIGN (8); + _dram_start = ABSOLUTE(.); + _bss_start = ABSOLUTE(.); + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + _bss_end = ABSOLUTE(.); + } > dram_seg + + .dram0.bootdesc : ALIGN(0x10) + { + _data_start = ABSOLUTE(.); + *(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */ + } > dram_seg + + .dram0.data : + { + *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + *(.data1) + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.gnu.linkonce.s2.*) + *(.jcr) + _data_end = ABSOLUTE(.); + } > dram_seg + + .dram0.rodata : + { + _rodata_start = ABSOLUTE(.); + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + *(.rodata1) + *(.sdata2 .sdata2.* .srodata .srodata.*) + __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); + *(.xt_except_table) + *(.gcc_except_table) + *(.gnu.linkonce.e.*) + *(.gnu.version_r) + *(.eh_frame_hdr) + *(.eh_frame) + . = (. + 3) & ~ 3; + /* C++ constructor and destructor tables, properly ordered: */ + __init_array_start = ABSOLUTE(.); + KEEP (*crtbegin.*(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __init_array_end = ABSOLUTE(.); + KEEP (*crtbegin.*(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + /* 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_end = ABSOLUTE(.); + /* Literals are also RO data. */ + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + . = ALIGN(4); + _dram_end = ABSOLUTE(.); + } > dram_seg + + .iram.text : + { + _stext = .; + _text_start = ABSOLUTE(.); + *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.iram .iram.*) /* catch stray IRAM_ATTR */ + *(.fini.literal) + *(.fini) + *(.gnu.version) + + /** CPU will try to prefetch up to 16 bytes of + * of instructions. This means that any configuration (e.g. MMU, PMS) must allow + * safe access to up to 16 bytes after the last real instruction, add + * dummy bytes to ensure this + */ + . += 16; + + _text_end = ABSOLUTE(.); + _etext = .; + } > iram_seg + + .riscv.attributes 0: { *(.riscv.attributes) } + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .debug_pubtypes 0 : { *(.debug_pubtypes) } + /* DWARF 3 */ + .debug_ranges 0 : { *(.debug_ranges) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* GNU DWARF 2 extensions */ + .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } + .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } + /* DWARF 4 */ + .debug_types 0 : { *(.debug_types) } + /* DWARF 5 */ + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + + .comment 0 : { *(.comment) } + .note.GNU-stack 0: { *(.note.GNU-stack) } + + /** + * Discarding .rela.* sections results in the following mapping: + * .rela.text.* -> .text.* + * .rela.data.* -> .data.* + * And so forth... + */ + /DISCARD/ : { *(.rela.*) } + + /** + * This section is not included in the binary image; it is only present in the ELF file. + * It is used to keep certain symbols in the ELF file. + */ + .noload 0 (INFO) : + { + /* Reserve first 4 bytes as zero for vars pointed to NULL */ + . = 0; + LONG(0); + _noload_keep_in_elf_start = ABSOLUTE(.); + KEEP(*(.noload_keep_in_elf .noload_keep_in_elf.*)) + _noload_keep_in_elf_end = ABSOLUTE(.); + } +} + + +/** + * Appendix: Memory Usage of ROM bootloader + * + * 0x2f0696b0 ------------------> _dram0_0_start + * | | + * | | + * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h + * | | + * | | + * 0x2f07afb0 ------------------> __stack_sentry + * | | + * | | 2. Startup pro cpu stack (freed when IDF app is running) + * | | + * 0x2f07cfb0 ------------------> __stack (pro cpu) + * | | + * | | Startup app cpu stack + * | | + * 0x2f07efb0 ------------------> __stack_app (app cpu) + * | | + * | | + * | | 3. Shared memory only used in startup code or nonos/early boot* + * | | (can be freed when IDF runs) + * | | + * | | + * 0x2f07fb20 ------------------> _dram0_rtos_reserved_start + * | | + * | | + * | | 4. Shared memory used in startup code and when IDF runs + * | | + * | | + * 0x2f07ff24 ------------------> _dram0_rtos_reserved_end + * | | + * 0x2f07ffac ------------------> _data_start_interface + * | | + * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) + * | | + * 0x2f080000 ------------------> _data_end_interface + */ diff --git a/components/bootloader/subproject/main/ld/esp32s31/bootloader.rom.ld b/components/bootloader/subproject/main/ld/esp32s31/bootloader.rom.ld new file mode 100644 index 0000000000..87ad406e3f --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32s31/bootloader.rom.ld @@ -0,0 +1,6 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* No definition for ESP32-S31 target */ diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s31.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s31.c index e69de29bb2..8c7a113791 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s31.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s31.c @@ -0,0 +1,324 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "string.h" +#include "sdkconfig.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp_rom_gpio.h" +#include "soc/gpio_periph.h" +#include "soc/spi_mem_reg.h" +#include "flash_qio_mode.h" +#include "bootloader_flash_config.h" +#include "bootloader_common.h" +#include "bootloader_flash_priv.h" +#include "bootloader_init.h" +#include "hal/mmu_hal.h" +#include "hal/mmu_ll.h" +#include "hal/mspi_ll.h" +#include "hal/cache_hal.h" +#include "hal/cache_ll.h" +#include "esp_private/bootloader_flash_internal.h" + +void IRAM_ATTR bootloader_flash_update_id(void) +{ + esp_rom_spiflash_chip_t *chip = &rom_spiflash_legacy_data->chip; + chip->device_id = bootloader_read_flash_id(); +} + +void bootloader_flash_update_size(uint32_t size) +{ + rom_spiflash_legacy_data->chip.chip_size = size; +} + +void IRAM_ATTR bootloader_flash_cs_timing_config(void) +{ + SET_PERI_REG_MASK(SPI_MEM_C_USER_REG, SPI_MEM_C_CS_HOLD_M | SPI_MEM_C_CS_SETUP_M); + SET_PERI_REG_BITS(SPI_MEM_C_CTRL2_REG, SPI_MEM_C_CS_HOLD_TIME_V, 0, SPI_MEM_C_CS_HOLD_TIME_S); + SET_PERI_REG_BITS(SPI_MEM_C_CTRL2_REG, SPI_MEM_C_CS_SETUP_TIME_V, 0, SPI_MEM_C_CS_SETUP_TIME_S); +} + +void IRAM_ATTR bootloader_init_mspi_clock(void) +{ + // IDF-14777 +} + +void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t *pfhdr) +{ + bootloader_init_mspi_clock(); + + uint32_t spi_clk_div = 0; + switch (pfhdr->spi_speed) { + case ESP_IMAGE_SPI_SPEED_DIV_1: + spi_clk_div = 1; + break; + case ESP_IMAGE_SPI_SPEED_DIV_2: + spi_clk_div = 2; + break; + case ESP_IMAGE_SPI_SPEED_DIV_3: + spi_clk_div = 3; + break; + case ESP_IMAGE_SPI_SPEED_DIV_4: + spi_clk_div = 4; + break; + default: + break; + } + esp_rom_spiflash_config_clk(spi_clk_div, 0); +} + +ESP_LOG_ATTR_TAG(TAG, "boot.esp32s31"); + +void IRAM_ATTR bootloader_configure_spi_pins(int drv) +{ + uint8_t clk_gpio_num = MSPI_IOMUX_PIN_NUM_CLK; + uint8_t q_gpio_num = MSPI_IOMUX_PIN_NUM_MISO; + uint8_t d_gpio_num = MSPI_IOMUX_PIN_NUM_MOSI; + uint8_t cs0_gpio_num = MSPI_IOMUX_PIN_NUM_CS0; + uint8_t hd_gpio_num = MSPI_IOMUX_PIN_NUM_HD; + uint8_t wp_gpio_num = MSPI_IOMUX_PIN_NUM_WP; + esp_rom_gpio_pad_set_drv(clk_gpio_num, drv); + esp_rom_gpio_pad_set_drv(q_gpio_num, drv); + esp_rom_gpio_pad_set_drv(d_gpio_num, drv); + esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv); + esp_rom_gpio_pad_set_drv(hd_gpio_num, drv); + esp_rom_gpio_pad_set_drv(wp_gpio_num, drv); +} + +static void update_flash_config(const esp_image_header_t *bootloader_hdr) +{ + uint32_t size; + switch (bootloader_hdr->spi_size) { + case ESP_IMAGE_FLASH_SIZE_1MB: + size = 1; + break; + case ESP_IMAGE_FLASH_SIZE_2MB: + size = 2; + break; + case ESP_IMAGE_FLASH_SIZE_4MB: + size = 4; + break; + case ESP_IMAGE_FLASH_SIZE_8MB: + size = 8; + break; + case ESP_IMAGE_FLASH_SIZE_16MB: + size = 16; + break; + case ESP_IMAGE_FLASH_SIZE_32MB: + size = 32; + break; + case ESP_IMAGE_FLASH_SIZE_64MB: + size = 64; + break; + case ESP_IMAGE_FLASH_SIZE_128MB: + size = 128; + break; + default: + size = 2; + } + // Set flash chip size + esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); +} + +static void print_flash_info(const esp_image_header_t *bootloader_hdr) +{ + ESP_EARLY_LOGD(TAG, "magic %02x", bootloader_hdr->magic); + ESP_EARLY_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count); + ESP_EARLY_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode); + ESP_EARLY_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed); + ESP_EARLY_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size); + + const char *str; + switch (bootloader_hdr->spi_speed) { + case ESP_IMAGE_SPI_SPEED_DIV_2: + str = "40MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_3: + str = "26.7MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_4: + str = "20MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_1: + str = "80MHz"; + break; + default: + str = "20MHz"; + break; + } + ESP_EARLY_LOGI(TAG, "SPI Speed : %s", str); + + /* SPI mode could have been set to QIO during boot already, + so test the SPI registers not the flash header */ + esp_rom_spiflash_read_mode_t spi_mode = bootloader_flash_get_spi_mode(); + switch (spi_mode) { + case ESP_ROM_SPIFLASH_QIO_MODE: + str = "QIO"; + break; + case ESP_ROM_SPIFLASH_QOUT_MODE: + str = "QOUT"; + break; + case ESP_ROM_SPIFLASH_DIO_MODE: + str = "DIO"; + break; + case ESP_ROM_SPIFLASH_DOUT_MODE: + str = "DOUT"; + break; + case ESP_ROM_SPIFLASH_FASTRD_MODE: + str = "FAST READ"; + break; + default: + str = "SLOW READ"; + break; + } + ESP_EARLY_LOGI(TAG, "SPI Mode : %s", str); + + switch (bootloader_hdr->spi_size) { + case ESP_IMAGE_FLASH_SIZE_1MB: + str = "1MB"; + break; + case ESP_IMAGE_FLASH_SIZE_2MB: + str = "2MB"; + break; + case ESP_IMAGE_FLASH_SIZE_4MB: + str = "4MB"; + break; + case ESP_IMAGE_FLASH_SIZE_8MB: + str = "8MB"; + break; + case ESP_IMAGE_FLASH_SIZE_16MB: + str = "16MB"; + break; + case ESP_IMAGE_FLASH_SIZE_32MB: + str = "32MB"; + break; + case ESP_IMAGE_FLASH_SIZE_64MB: + str = "64MB"; + break; + case ESP_IMAGE_FLASH_SIZE_128MB: + str = "128MB"; + break; + default: + str = "2MB"; + break; + } + ESP_EARLY_LOGI(TAG, "SPI Flash Size : %s", str); +} + +static void IRAM_ATTR bootloader_init_flash_configure(void) +{ + bootloader_configure_spi_pins(1); + bootloader_flash_cs_timing_config(); +} + +static void bootloader_spi_flash_resume(void) +{ + bootloader_execute_flash_command(CMD_RESUME, 0, 0, 0); + esp_rom_spiflash_wait_idle(&g_rom_flashchip); +} + +esp_err_t bootloader_init_spi_flash(void) +{ + bootloader_init_flash_configure(); + +#if CONFIG_BOOTLOADER_FLASH_DC_AWARE + // Reset flash, clear volatile bits DC[0:1]. Make it work under default mode to boot. + bootloader_spi_flash_reset(); +#endif + + bootloader_spi_flash_resume(); + if ((void*)bootloader_flash_unlock != (void*)bootloader_flash_unlock_default) { + ESP_EARLY_LOGD(TAG, "Using overridden bootloader_flash_unlock"); + } + bootloader_flash_unlock(); + +#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT + bootloader_enable_qio_mode(); +#endif +#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH + bootloader_flash_32bits_address_map_enable(bootloader_flash_get_spi_mode()); +#endif + + print_flash_info(&bootloader_image_hdr); + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + update_flash_config(&bootloader_image_hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + + //ensure the flash is write-protected + bootloader_enable_wp(); + return ESP_OK; +} + +#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +static void bootloader_flash_set_spi_mode(const esp_image_header_t* pfhdr) +{ + esp_rom_spiflash_read_mode_t mode; + switch(pfhdr->spi_mode) { + case ESP_IMAGE_SPI_MODE_QIO: + mode = ESP_ROM_SPIFLASH_QIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_QOUT: + mode = ESP_ROM_SPIFLASH_QOUT_MODE; + break; + case ESP_IMAGE_SPI_MODE_DIO: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_FAST_READ: + mode = ESP_ROM_SPIFLASH_FASTRD_MODE; + break; + case ESP_IMAGE_SPI_MODE_SLOW_READ: + mode = ESP_ROM_SPIFLASH_SLOWRD_MODE; + break; + default: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + } + esp_rom_spiflash_config_readmode(mode); +} + +void bootloader_flash_hardware_init(void) +{ + esp_rom_spiflash_attach(0, false); + + //init cache hal + // cache_hal_init(); // IDF-14651 + //reset mmu + // mmu_hal_init(); // IDF-14669 + // update flash ID + bootloader_flash_update_id(); + // Check and run XMC startup flow + esp_err_t ret = bootloader_flash_xmc_startup(); + assert(ret == ESP_OK); + + /* Alternative of bootloader_init_spi_flash */ + // RAM app doesn't have headers in the flash. Make a default one for it. + esp_image_header_t WORD_ALIGNED_ATTR hdr = { + .spi_mode = ESP_IMAGE_SPI_MODE_DIO, + .spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2, + .spi_size = ESP_IMAGE_FLASH_SIZE_2MB, + }; + + bootloader_configure_spi_pins(1); + bootloader_flash_set_spi_mode(&hdr); + bootloader_flash_clock_config(&hdr); + bootloader_flash_cs_timing_config(); + + bootloader_spi_flash_resume(); + bootloader_flash_unlock(); + +#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH + bootloader_flash_32bits_address_map_enable(bootloader_flash_get_spi_mode()); +#endif + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + update_flash_config(&hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + + //ensure the flash is write-protected + bootloader_enable_wp(); +} +#endif //CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP diff --git a/components/bootloader_support/include/esp_app_format.h b/components/bootloader_support/include/esp_app_format.h index 7eeeeda13b..de007d02dd 100644 --- a/components/bootloader_support/include/esp_app_format.h +++ b/components/bootloader_support/include/esp_app_format.h @@ -29,6 +29,7 @@ typedef enum { ESP_CHIP_ID_ESP32C61= 0x0014, /*!< chip ID: ESP32-C61 */ ESP_CHIP_ID_ESP32H21= 0x0019, /*!< chip ID: ESP32-H21 */ ESP_CHIP_ID_ESP32H4 = 0x001C, /*!< chip ID: ESP32-H4 */ + ESP_CHIP_ID_ESP32S31 = 0x0020, /*!< chip ID: ESP32-S31 */ ESP_CHIP_ID_INVALID = 0xFFFF /*!< Invalid chip ID (we defined it to make sure the esp_chip_id_t is 2 bytes size) */ } __attribute__((packed)) esp_chip_id_t; diff --git a/components/bootloader_support/src/bootloader_clock_init.c b/components/bootloader_support/src/bootloader_clock_init.c index 5ee52afd3d..da34d7ab37 100644 --- a/components/bootloader_support/src/bootloader_clock_init.c +++ b/components/bootloader_support/src/bootloader_clock_init.c @@ -162,6 +162,8 @@ __attribute__((weak)) void bootloader_clock_configure(void) SET_PERI_REG_MASK(LP_WDT_INT_CLR_REG, LP_WDT_SUPER_WDT_INT_CLR); /* SWD */ SET_PERI_REG_MASK(LP_ANALOG_PERI_LP_INT_CLR_REG, LP_ANALOG_PERI_LP_INT_CLR_REG); /* BROWN_OUT */ SET_PERI_REG_MASK(LP_WDT_INT_CLR_REG, LP_WDT_LP_WDT_INT_CLR); /* WDT */ +#elif CONFIG_IDF_TARGET_ESP32S31 + //ESP32S31-TODO IDF-14696 #else REG_WRITE(RTC_CNTL_INT_ENA_REG, 0); REG_WRITE(RTC_CNTL_INT_CLR_REG, UINT32_MAX); diff --git a/components/bootloader_support/src/bootloader_efuse.c b/components/bootloader_support/src/bootloader_efuse.c index af5ca63119..691c73d009 100644 --- a/components/bootloader_support/src/bootloader_efuse.c +++ b/components/bootloader_support/src/bootloader_efuse.c @@ -58,5 +58,7 @@ int bootloader_clock_get_rated_freq_mhz(void) #elif CONFIG_IDF_TARGET_ESP32S3 return 240; +#elif CONFIG_IDF_TARGET_ESP32S31 + return 300; #endif } diff --git a/components/bootloader_support/src/esp32s31/bootloader_esp32s31.c b/components/bootloader_support/src/esp32s31/bootloader_esp32s31.c new file mode 100644 index 0000000000..e7c74dc617 --- /dev/null +++ b/components/bootloader_support/src/esp32s31/bootloader_esp32s31.c @@ -0,0 +1,91 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "sdkconfig.h" +#include "esp_attr.h" +#include "esp_log.h" +#include "esp_image_format.h" +#include "flash_qio_mode.h" +#include "bootloader_common.h" +#include "bootloader_init.h" +#include "bootloader_clock.h" +#include "bootloader_flash_config.h" +#include "bootloader_mem.h" +#include "bootloader_console.h" +#include "bootloader_flash_priv.h" +#include "bootloader_soc.h" +#include "esp_private/bootloader_flash_internal.h" + +static const char *TAG = "boot.esp32s31"; + +esp_err_t bootloader_init(void) +{ + esp_err_t ret = ESP_OK; + + // bootloader_hardware_init(); // TODO: IDF-14696 + // bootloader_super_wdt_auto_feed(); // TODO: IDF-14656 + +// In RAM_APP, memory will be initialized in `call_start_cpu0` +#if !CONFIG_APP_BUILD_TYPE_RAM + // protect memory region + bootloader_init_mem(); + /* check that static RAM is after the stack */ + assert(&_bss_start <= &_bss_end); + assert(&_data_start <= &_data_end); + // clear bss section + bootloader_clear_bss_section(); +#endif // !CONFIG_APP_BUILD_TYPE_RAM + + // init eFuse virtual mode (read eFuses to RAM) +#ifdef CONFIG_EFUSE_VIRTUAL + ESP_EARLY_LOGW(TAG, "eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!"); +#ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH + esp_efuse_init_virtual_mode_in_ram(); +#endif +#endif + + // config clock + bootloader_clock_configure(); + // initialize console, from now on, we can use esp_log + bootloader_console_init(); + /* print 2nd bootloader banner */ + bootloader_print_banner(); + +#if !CONFIG_APP_BUILD_TYPE_RAM + //init cache hal + // cache_hal_init(); IDF-14651 + //reset mmu + // mmu_hal_init(); IDF-14669 + // update flash ID + bootloader_flash_update_id(); + // Check and run XMC startup flow + if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) { + ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); + return ret; + } + // read bootloader header + if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { + return ret; + } + // read chip revision and check if it's compatible to bootloader + if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { + return ret; + } + // initialize spi flash + if ((ret = bootloader_init_spi_flash()) != ESP_OK) { + return ret; + } +#endif // !CONFIG_APP_BUILD_TYPE_RAM + + // check whether a WDT reset happened + // bootloader_check_wdt_reset(); // TODO: IDF-14656 + // config WDT + bootloader_config_wdt(); + // enable RNG early entropy source + bootloader_enable_random(); + + return ret; +} diff --git a/components/bootloader_support/src/esp32s31/bootloader_soc.c b/components/bootloader_support/src/esp32s31/bootloader_soc.c new file mode 100644 index 0000000000..025fd5b59a --- /dev/null +++ b/components/bootloader_support/src/esp32s31/bootloader_soc.c @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "soc/lp_analog_peri_reg.h" + +void bootloader_ana_super_wdt_reset_config(bool enable) +{ + //TODO: IDF-14656 +} + +void bootloader_ana_clock_glitch_reset_config(bool enable) +{ + (void)enable; +} diff --git a/components/esp_driver_uart/src/uart.c b/components/esp_driver_uart/src/uart.c index 22b4defbfa..d7a2051cb7 100644 --- a/components/esp_driver_uart/src/uart.c +++ b/components/esp_driver_uart/src/uart.c @@ -215,6 +215,9 @@ static esp_err_t uart_create_sleep_retention_link_cb(void *arg); static bool uart_module_enable(uart_port_t uart_num) { + if (uart_num >= UART_NUM_MAX) { + return false; + } bool newly_enabled = false; _lock_acquire(&(uart_context[uart_num].mutex)); if (uart_context[uart_num].hw_enabled != true) { diff --git a/components/esp_hal_wdt/linker.lf b/components/esp_hal_wdt/linker.lf index 6a951b1736..2e9b5029c9 100644 --- a/components/esp_hal_wdt/linker.lf +++ b/components/esp_hal_wdt/linker.lf @@ -1,7 +1,8 @@ [mapping:esp_hal_wdt] archive: libesp_hal_wdt.a entries: - if HAL_WDT_USE_ROM_IMPL = y: - rom_patch (noflash) - else: - wdt_hal_iram (noflash) + if SOC_WDT_SUPPORTED = y: + if HAL_WDT_USE_ROM_IMPL = y: + rom_patch (noflash) + else: + wdt_hal_iram (noflash) diff --git a/components/esp_mm/port/esp32s31/ext_mem_layout.c b/components/esp_mm/port/esp32s31/ext_mem_layout.c index e69de29bb2..75faf730e8 100644 --- a/components/esp_mm/port/esp32s31/ext_mem_layout.c +++ b/components/esp_mm/port/esp32s31/ext_mem_layout.c @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "sdkconfig.h" +#include "soc/ext_mem_defs.h" +#include "../ext_mem_layout.h" +#include "hal/mmu_types.h" + +// TODO: Please check this file [ESP32S31] IDF-14669 + +/** + * The start addresses in this list should always be sorted from low to high, as MMU driver will need to + * coalesce adjacent regions + */ +const mmu_mem_region_t g_mmu_mem_regions[SOC_MMU_LINEAR_ADDRESS_REGION_NUM] = { + [0] = { + .start = SOC_MMU_FLASH_LINEAR_ADDRESS_LOW, + .end = SOC_MMU_FLASH_LINEAR_ADDRESS_HIGH, + .size = SOC_BUS_SIZE(SOC_MMU_FLASH_LINEAR), + .bus_id = CACHE_BUS_IBUS0 | CACHE_BUS_DBUS0, + .targets = MMU_TARGET_FLASH0, + .caps = MMU_MEM_CAP_EXEC | MMU_MEM_CAP_READ | MMU_MEM_CAP_WRITE | MMU_MEM_CAP_32BIT | MMU_MEM_CAP_8BIT, + }, + [1] = { + .start = SOC_MMU_PSRAM_LINEAR_ADDRESS_LOW, + .end = SOC_MMU_PSRAM_LINEAR_ADDRESS_HIGH, + .size = SOC_BUS_SIZE(SOC_MMU_PSRAM_LINEAR), + .bus_id = CACHE_BUS_IBUS1 | CACHE_BUS_DBUS1, + .targets = MMU_TARGET_PSRAM0, + .caps = MMU_MEM_CAP_EXEC | MMU_MEM_CAP_READ | MMU_MEM_CAP_WRITE | MMU_MEM_CAP_32BIT | MMU_MEM_CAP_8BIT, + }, +}; diff --git a/components/esp_pm/CMakeLists.txt b/components/esp_pm/CMakeLists.txt index 27ce9ada3c..52e56891f5 100644 --- a/components/esp_pm/CMakeLists.txt +++ b/components/esp_pm/CMakeLists.txt @@ -4,7 +4,11 @@ if(${target} STREQUAL "linux") return() # This component is not supported by the POSIX/Linux simulator endif() -idf_component_register(SRCS "pm_locks.c" "pm_trace.c" "pm_impl.c" +if(CONFIG_SOC_PM_SUPPORTED) + list(APPEND srcs "pm_locks.c" "pm_trace.c" "pm_impl.c") +endif() + +idf_component_register(SRCS "${srcs}" INCLUDE_DIRS include PRIV_REQUIRES esp_system esp_driver_gpio esp_timer LDFRAGMENTS linker.lf) diff --git a/components/esp_security/src/esp32s31/.gitkeep b/components/esp_security/src/esp32s31/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/components/esp_security/src/esp32s31/esp_crypto_clk.h b/components/esp_security/src/esp32s31/esp_crypto_clk.h new file mode 100644 index 0000000000..77e24f772a --- /dev/null +++ b/components/esp_security/src/esp32s31/esp_crypto_clk.h @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "soc/soc.h" +#include "soc/hp_sys_clkrst_reg.h" + +#pragma once + +static inline void esp_crypto_clk_init(void) +{ + // Set crypto clock (`clk_sec`) to use 240M PLL clock + // TODO: ["ESP32S31"] IDF-14629 + // REG_SET_FIELD(HP_SYS_CLKRST_CRYPTO_CTRL0_REG, HP_SYS_CLKRST_REG_CRYPTO_CLK_SRC_SEL, 0x2); +} diff --git a/components/esp_system/port/soc/esp32s31/system_internal.c b/components/esp_system/port/soc/esp32s31/system_internal.c index 9936088e7f..bcc1776c4c 100644 --- a/components/esp_system/port/soc/esp32s31/system_internal.c +++ b/components/esp_system/port/soc/esp32s31/system_internal.c @@ -31,7 +31,7 @@ // TODO: [ESP32S31] IDF-14841 -void IRAM_ATTR esp_system_reset_modules_on_exit(void) +void esp_system_reset_modules_on_exit(void) { // Flush any data left in UART FIFOs for (int i = 0; i < SOC_UART_HP_NUM; ++i) { @@ -45,7 +45,7 @@ void IRAM_ATTR esp_system_reset_modules_on_exit(void) * core are already stopped. Stalls other core, resets hardware, * triggers restart. */ -void IRAM_ATTR esp_restart_noos(void) +void esp_restart_noos(void) { // Disable interrupts rv_utils_intr_global_disable(); diff --git a/components/hal/esp32s31/include/hal/uart_ll.h b/components/hal/esp32s31/include/hal/uart_ll.h index 23abc22c9b..27e4d93132 100644 --- a/components/hal/esp32s31/include/hal/uart_ll.h +++ b/components/hal/esp32s31/include/hal/uart_ll.h @@ -245,9 +245,6 @@ static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable) HP_SYS_CLKRST.uart3_ctrl0.reg_uart3_apb_clk_en = enable; HP_SYS_CLKRST.uart3_ctrl0.reg_uart3_sys_clk_en = enable; break; - case 4: - // LP_UART port having its own enable_bus_clock function: lp_uart_ll_enable_bus_clock - break;; default: abort(); break; @@ -277,9 +274,6 @@ static inline void uart_ll_reset_register(uart_port_t uart_num) HP_SYS_CLKRST.uart3_ctrl0.reg_uart3_apb_rst_en = 1; HP_SYS_CLKRST.uart3_ctrl0.reg_uart3_apb_rst_en = 0; break; - case 4: - // LP_UART port having its own enable_bus_clock function: lp_uart_ll_reset_register - break;; default: abort(); break; @@ -567,6 +561,18 @@ FORCE_INLINE_ATTR uint32_t uart_ll_get_intr_ena_status(uart_dev_t *hw) return hw->int_ena.val; } +/** + * @brief Get reg address of interrupt. + * + * @param hw Beginning address of the peripheral registers. + * + * @return reg address + */ +FORCE_INLINE_ATTR volatile void* uart_ll_get_intr_status_reg(uart_dev_t *hw) +{ + return &hw->int_st.val; +} + /** * @brief Read the UART rxfifo. * @@ -1022,9 +1028,6 @@ FORCE_INLINE_ATTR void uart_ll_set_char_seq_wk_char(uart_dev_t *hw, uint32_t cha case 3: HAL_FORCE_MODIFY_U32_REG_FIELD(hw->sleep_conf0, wk_char3, value); break; - case 4: - HAL_FORCE_MODIFY_U32_REG_FIELD(hw->sleep_conf0, wk_char4, value); - break; default: abort(); break; @@ -1527,9 +1530,6 @@ FORCE_INLINE_ATTR void uart_ll_memory_lp_enable(uart_port_t uart_num) case 3: HP_SYSTEM.sys_uart3_mem_lp_ctrl.sys_uart3_mem_lp_en = 1; break; - case 4: - LP_SYS.uart_mem_lp_ctrl.uart_mem_lp_en = 1; - break;; default: abort(); break; @@ -1558,9 +1558,6 @@ FORCE_INLINE_ATTR void uart_ll_memory_lp_disable(uart_port_t uart_num) case 3: HP_SYSTEM.sys_uart3_mem_lp_ctrl.sys_uart3_mem_lp_en = 0; break; - case 4: - LP_SYS.uart_mem_lp_ctrl.uart_mem_lp_en = 0; - break;; default: abort(); break; diff --git a/components/heap/port/esp32s31/memory_layout.c b/components/heap/port/esp32s31/memory_layout.c index e69de29bb2..67ea4deb26 100644 --- a/components/heap/port/esp32s31/memory_layout.c +++ b/components/heap/port/esp32s31/memory_layout.c @@ -0,0 +1,113 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "esp_attr.h" +#include "sdkconfig.h" +#include "soc/soc.h" +#include "heap_memory_layout.h" +#include "esp_heap_caps.h" + +/* TODO: ["ESP32S31"] IDF-14840 */ + +/** + * @brief Memory type descriptors. These describe the capabilities of a type of memory in the SoC. + * Each type of memory map consists of one or more regions in the address space. + * Each type contains an array of prioritized capabilities. + * Types with later entries are only taken if earlier ones can't fulfill the memory request. + * + * - For a normal malloc (MALLOC_CAP_DEFAULT), give away the DRAM-only memory first, then pass off any dual-use IRAM regions, finally eat into the application memory. + * - For a malloc where 32-bit-aligned-only access is okay, first allocate IRAM, then DRAM, finally application IRAM. + * - Most other malloc caps only fit in one region anyway. + * + */ + +/* Index of memory in `soc_memory_types[]` */ +enum { + SOC_MEMORY_TYPE_RAM = 0, + SOC_MEMORY_TYPE_RTCRAM = 1, + SOC_MEMORY_TYPE_SPIRAM = 2, + SOC_MEMORY_TYPE_NUM, +}; + +/* COMMON_CAPS is the set of attributes common to all types of memory on this chip */ +#ifdef CONFIG_ESP_SYSTEM_MEMPROT +#define ESP32S31_MEM_COMMON_CAPS (MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL | MALLOC_CAP_32BIT | MALLOC_CAP_8BIT) +#else +#define ESP32S31_MEM_COMMON_CAPS (MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL | MALLOC_CAP_32BIT | MALLOC_CAP_8BIT | MALLOC_CAP_EXEC) +#endif + +/** + * Defined the attributes and allocation priority of each memory on the chip, + * The heap allocator will traverse all types of memory types in column High Priority Matching and match the specified caps at first, + * if no memory caps matched or the allocation is failed, it will go to columns Medium Priority Matching and Low Priority Matching + * in turn to continue matching. + */ +const soc_memory_type_desc_t soc_memory_types[SOC_MEMORY_TYPE_NUM] = { + /* Mem Type Name High Priority Matching Medium Priority Matching Low Priority Matching */ + [SOC_MEMORY_TYPE_RAM] = { "RAM", { ESP32S31_MEM_COMMON_CAPS | MALLOC_CAP_DMA, 0, 0 }}, + [SOC_MEMORY_TYPE_RTCRAM] = { "RTCRAM", { MALLOC_CAP_RTCRAM, ESP32S31_MEM_COMMON_CAPS, 0 }}, + [SOC_MEMORY_TYPE_SPIRAM] = { "SPIRAM", { MALLOC_CAP_SPIRAM | MALLOC_CAP_DEFAULT, 0, MALLOC_CAP_8BIT | MALLOC_CAP_32BIT}}, +}; + +const size_t soc_memory_type_count = sizeof(soc_memory_types) / sizeof(soc_memory_type_desc_t); + +/** + * @brief Region descriptors. These describe all regions of memory available, and map them to a type in the above type. + * + * @note Because of requirements in the coalescing code which merges adjacent regions, + * this list should always be sorted from low to high by start address. + * + */ + +/** + * Register the shared buffer area of the last memory block into the heap during heap initialization + */ +#define APP_USABLE_DRAM_END (SOC_ROM_STACK_START - SOC_ROM_STACK_SIZE) + + +const soc_memory_region_t soc_memory_regions[] = { +#ifdef CONFIG_SPIRAM + { SOC_EXTRAM_LOW, SOC_EXTRAM_SIZE, SOC_MEMORY_TYPE_SPIRAM, 0, false}, //PSRAM, if available +#endif + { SOC_DIRAM_DRAM_LOW, (APP_USABLE_DRAM_END - SOC_DIRAM_DRAM_LOW), SOC_MEMORY_TYPE_RAM, SOC_DIRAM_IRAM_LOW, false}, //D/IRAM, can be used as trace memory + { APP_USABLE_DRAM_END, (SOC_DIRAM_DRAM_HIGH - APP_USABLE_DRAM_END), SOC_MEMORY_TYPE_RAM, APP_USABLE_DRAM_END, true}, //D/IRAM, can be used as trace memory (ROM reserved area) +#ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP + { SOC_LP_RAM_LOW, (SOC_LP_RAM_HIGH - SOC_LP_RAM_LOW), SOC_MEMORY_TYPE_RTCRAM, 0, false}, //LPRAM +#endif +}; + +const size_t soc_memory_region_count = sizeof(soc_memory_regions) / sizeof(soc_memory_region_t); + + +extern int _data_start, _heap_start, _iram_start, _iram_end, _rtc_force_slow_end; +extern int _rtc_reserved_start, _rtc_reserved_end; +extern int _rtc_ulp_memory_start; + +/** + * Reserved memory regions. + * These are removed from the soc_memory_regions array when heaps are created. + * + */ + +// Static data region. DRAM used by data+bss and possibly rodata +SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_data); + +// Target has a shared D/IRAM virtual address, no need to calculate I_D_OFFSET like previous chips +SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start, (intptr_t)&_iram_end, iram_code); + +#ifdef CONFIG_SPIRAM +SOC_RESERVE_MEMORY_REGION( SOC_EXTRAM_LOW, SOC_EXTRAM_HIGH, extram_region); +#endif + + +#ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP +SOC_RESERVE_MEMORY_REGION((intptr_t)&_rtc_reserved_start, (intptr_t)&_rtc_reserved_end, rtc_reserved_data); +/* This includes any memory reserved for ULP RAM */ +SOC_RESERVE_MEMORY_REGION((intptr_t)&_rtc_reserved_end, (intptr_t)&_rtc_force_slow_end, rtcram_data); + +#endif diff --git a/components/soc/esp32s31/gpio_periph.c b/components/soc/esp32s31/gpio_periph.c index 510b686217..394b2a7ea2 100644 --- a/components/soc/esp32s31/gpio_periph.c +++ b/components/soc/esp32s31/gpio_periph.c @@ -6,6 +6,7 @@ #include "soc/gpio_periph.h" #include "esp_assert.h" +#include "soc/io_mux_reg.h" const uint32_t GPIO_PIN_MUX_REG[] = { IO_MUX_GPIO0_REG, diff --git a/components/spi_flash/esp32s31/Kconfig.flash_freq b/components/spi_flash/esp32s31/Kconfig.flash_freq new file mode 100644 index 0000000000..13efd6e5d2 --- /dev/null +++ b/components/spi_flash/esp32s31/Kconfig.flash_freq @@ -0,0 +1,16 @@ +choice ESPTOOLPY_FLASHFREQ + prompt "Flash SPI speed" + default ESPTOOLPY_FLASHFREQ_40M + config ESPTOOLPY_FLASHFREQ_80M + bool "80 MHz" + config ESPTOOLPY_FLASHFREQ_40M + bool "40 MHz" + config ESPTOOLPY_FLASHFREQ_20M + bool "20 MHz" +endchoice + +config ESPTOOLPY_FLASHFREQ_VAL + int + default 20 if ESPTOOLPY_FLASHFREQ_20M + default 40 if ESPTOOLPY_FLASHFREQ_40M + default 80 if ESPTOOLPY_FLASHFREQ_80M diff --git a/components/spi_flash/esp32s31/Kconfig.soc_caps.in b/components/spi_flash/esp32s31/Kconfig.soc_caps.in new file mode 100644 index 0000000000..443f776e07 --- /dev/null +++ b/components/spi_flash/esp32s31/Kconfig.soc_caps.in @@ -0,0 +1,12 @@ +##################################################### +# This file is auto-generated from SoC caps +# using gen_soc_caps_kconfig.py, do not edit manually +##################################################### + +config SPI_FLASH_VENDOR_XMC_SUPPORT_ENABLED + bool + default y + +config SPI_FLASH_VENDOR_GD_SUPPORT_ENABLED + bool + default y diff --git a/components/spi_flash/esp32s31/flash_vendor_caps.h b/components/spi_flash/esp32s31/flash_vendor_caps.h new file mode 100644 index 0000000000..a93d0376d2 --- /dev/null +++ b/components/spi_flash/esp32s31/flash_vendor_caps.h @@ -0,0 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#define SPI_FLASH_VENDOR_XMC_SUPPORT_ENABLED (1) +#define SPI_FLASH_VENDOR_GD_SUPPORT_ENABLED (1) diff --git a/tools/ci/build_template_app.sh b/tools/ci/build_template_app.sh index 14f7ab0bc0..15109e8dd3 100755 --- a/tools/ci/build_template_app.sh +++ b/tools/ci/build_template_app.sh @@ -67,7 +67,7 @@ build_stage2() { --work-dir ${BUILD_PATH}/cmake \ --build-dir ${BUILD_DIR} \ --build-log ${BUILD_LOG_CMAKE} \ - --default-build-targets esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c5 esp32c6 esp32h2 esp32p4 esp32c61 esp32h21 esp32h4 + --default-build-targets esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c5 esp32c6 esp32h2 esp32p4 esp32c61 esp32h21 esp32h4 esp32s31 } build_stage1() { @@ -78,7 +78,7 @@ build_stage1() { --work-dir ${BUILD_PATH}/cmake \ --build-dir ${BUILD_DIR} \ --build-log ${BUILD_LOG_CMAKE} \ - --default-build-targets esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c5 esp32c6 esp32h2 esp32p4 esp32c61 esp32h21 esp32h4 + --default-build-targets esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c5 esp32c6 esp32h2 esp32p4 esp32c61 esp32h21 esp32h4 esp32s31 } # Default arguments