diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS index 7a2d85a1668..6c93de2b46c 100644 --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -114,6 +114,7 @@ /components/esp_libc/ @esp-idf-codeowners/system @esp-idf-codeowners/toolchain /components/esp_local_ctrl/ @esp-idf-codeowners/app-utilities /components/esp_mm/ @esp-idf-codeowners/peripherals +/components/esp_mspi/ @esp-idf-codeowners/peripherals /components/esp_netif/ @esp-idf-codeowners/network /components/esp_netif_stack/ @esp-idf-codeowners/network /components/esp_partition/ @esp-idf-codeowners/storage diff --git a/components/README.md b/components/README.md index 6517fb68d1f..f226e397fcd 100644 --- a/components/README.md +++ b/components/README.md @@ -10,7 +10,7 @@ The core components are organized into two groups. The first group (referred to as `G0`) includes `hal`, `arch` (where `arch` is either `riscv` or `xtensa` depending on the chip), `esp_rom`, `esp_common`, and `soc`. This group contains information about and provides low-level access to the underlying hardware. In the case of `esp_common`, it contains hardware-agnostic code and utilities. These components may have dependencies on each other within the group, but outside dependencies should be minimized. The reason for this approach is that these components are fundamental, and many other components may require them. Ideally, the dependency relationship only goes one way, making it easier for this group to be usable in other projects. -The second group (referred to as `G1`) operates at a higher level than the first group. `G1` includes the components `esp_hw_support`, `esp_system`, `esp_libc`, `spi_flash`, `freertos`, `log`, and `heap`. Like the first group, circular dependencies within this group are allowed, and these components can have dependencies on the first group. G1 components represent essential software mechanisms for building other components. +The second group (referred to as `G1`) operates at a higher level than the first group. `G1` includes the components `esp_hw_support`, `esp_mspi`, `esp_system`, `esp_libc`, `freertos`, `log`, and `heap`. Like the first group, circular dependencies within this group are allowed, and these components can have dependencies on the first group. G1 components represent essential software mechanisms for building other components. ## Descriptions @@ -69,10 +69,6 @@ Example: ### `G1` Components -#### `spi_flash` - -SPI flash device access implementation. - #### `freertos` FreeRTOS port to targets supported by ESP-IDF. @@ -131,6 +127,14 @@ merely as facilitator to hardware access. Currently, this encompasses the follow - CPU utilities - MAC settings +#### `esp_mspi` + +Contains the CPU XiP related MSPI (Memory SPI) implementation for the external SPI flash and PSRAM controller. Currently, this encompasses the following, but not limited to: + +- MSPI timing tuning +- MSPI interrupt handling +- XiP on OPI/Octal flash support + ### `esp_hw_support` vs `esp_system` This section details list some implementations and the reason for placing it in either `esp_hw_support` or `esp_system`. diff --git a/components/bootloader_support/CMakeLists.txt b/components/bootloader_support/CMakeLists.txt index a729ed05125..9ab4564f8fd 100644 --- a/components/bootloader_support/CMakeLists.txt +++ b/components/bootloader_support/CMakeLists.txt @@ -100,8 +100,8 @@ else() set(priv_requires spi_flash efuse heap esp_bootloader_format esp_app_format esptool_py) # `esp_hal_ana_conv` is required by bootloader_random_esp32xx.c - list(APPEND priv_requires esp_hal_wdt esp_hal_gpio esp_hal_uart esp_hal_ana_conv esp_hal_rtc_timer - esp_hal_clock esp_hal_security esp_hal_debug_assist) + list(APPEND priv_requires esp_mspi esp_hal_wdt esp_hal_gpio esp_hal_uart esp_hal_ana_conv + esp_hal_rtc_timer esp_hal_clock esp_hal_security esp_hal_debug_assist) endif() # src/flash_encrypt.c includes esp_security/esp_key_mgr.h on diff --git a/components/bootloader_support/bootloader_flash/include/bootloader_flash.h b/components/bootloader_support/bootloader_flash/include/bootloader_flash.h index 4cb38564141..d2f118e2907 100644 --- a/components/bootloader_support/bootloader_flash/include/bootloader_flash.h +++ b/components/bootloader_support/bootloader_flash/include/bootloader_flash.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,8 +7,7 @@ #include #include -#include "spi_flash_mmap.h" /* including in bootloader for error values */ -#include "esp_private/spi_flash_os.h" +#include "esp_rom_spiflash.h" #include "sdkconfig.h" #include "soc/soc_caps.h" #include "bootloader_flash_override.h" @@ -59,6 +58,7 @@ esp_err_t bootloader_flash_reset_chip(void); * * @return True if flash is in octal mode, false else */ +__attribute__((deprecated("in favor of spi_flash_is_octal_mode_enabled"))) bool bootloader_flash_is_octal_mode_enabled(void); /** diff --git a/components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h b/components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h index 936b2ab144c..10a8141d5ab 100644 --- a/components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h +++ b/components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h @@ -1,46 +1,22 @@ /* - * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ -#ifndef __BOOTLOADER_FLASH_H -#define __BOOTLOADER_FLASH_H +#pragma once #include #include #include #include -#include /* including in bootloader for error values */ #include "sdkconfig.h" #include "bootloader_flash.h" -#include "soc/ext_mem_defs.h" +#include "bootloader_flash_override.h" -#ifdef __cplusplus -extern "C" { -#endif - -#define FLASH_SECTOR_SIZE 0x1000 -#define FLASH_BLOCK_SIZE 0x10000 - -#define MMAP_ALIGNED_MASK (SPI_FLASH_MMU_PAGE_SIZE - 1) -#define MMU_FLASH_MASK (~(SPI_FLASH_MMU_PAGE_SIZE - 1)) -#define MMU_FLASH_MASK_FROM_VAL(PAGE_SZ) (~((PAGE_SZ) - 1)) -#define MMU_DROM_END_ENTRY_VADDR_FROM_VAL(PAGE_SZ) (SOC_DRAM_FLASH_ADDRESS_HIGH - (PAGE_SZ)) - -/** - * MMU mapping must always be in the unit of a SPI_FLASH_MMU_PAGE_SIZE - * This macro is a helper for you to get needed page nums to be mapped. e.g.: - * Let's say SPI_FLASH_MMU_PAGE_SIZE is 64KB. - * - v_start = 0x4200_0004 - * - size = 4 * 64KB - * - * You should map from 0x4200_0000, then map 5 pages. +/* + * SPI commands + * These are deprecated, use the ones in spi_flash_defs.h instead. */ -#define GET_REQUIRED_MMU_PAGES(size, v_start) ((size + (v_start - (v_start & MMU_FLASH_MASK)) + SPI_FLASH_MMU_PAGE_SIZE - 1) / SPI_FLASH_MMU_PAGE_SIZE) - -/* SPI commands (actual on-wire commands not SPI controller bitmasks) - Suitable for use with the bootloader_execute_flash_command static function. -*/ #define CMD_RDID 0x9F #define CMD_WRSR 0x01 #define CMD_WRSR2 0x31 /* Not all SPI flash uses this command */ @@ -62,146 +38,3 @@ extern "C" { #define CMD_FASTRD_DUAL_4B 0x3C #define CMD_FASTRD_4B 0x0C #define CMD_SLOWRD_4B 0x13 - - -/* Provide a Flash API for bootloader_support code, - that can be used from bootloader or app code. - - This header is available to source code in the bootloader & - bootloader_support components only. -*/ - -/** - * @brief Get number of free pages - * - * @return Number of free pages - */ -uint32_t bootloader_mmap_get_free_pages(void); - -/** - * @brief Map a region of flash to data memory - * - * @important In bootloader code, only one region can be bootloader_mmaped at once. The previous region must be bootloader_munmapped before another region is mapped. - * - * @important In app code, these functions are not thread safe. - * - * Call bootloader_munmap once for each successful call to bootloader_mmap. - * - * In esp-idf app, this function maps directly to spi_flash_mmap with the @ref - * spi_flash_mmap_flag_t::SPI_FLASH_MMAP_FLAG_BLOCKS_WRITE flag set. When XIP on PSRAM (`CONFIG_SPIRAM_XIP_FROM_PSRAM`) enabled, flash erasing/writing - * will be blocked until unmap. - * - * @param offset - Starting flash offset to map to memory. - * @param length - Length of data to map. - * - * @return Pointer to mapped data memory (at src_addr), or NULL - * if an allocation error occurred. - */ -const void *bootloader_mmap(uint32_t src_addr, uint32_t size); - - -/** - * @brief Unmap a previously mapped region of flash - * - * Call bootloader_munmap once for each successful call to bootloader_mmap. - */ -void bootloader_munmap(const void *mapping); - -/** - * @brief Read data from Flash. - * - * - * @note All of src, dest and size have to be 4-byte aligned. - * - * @param src source address of the data in Flash. - * @param dest pointer to the destination buffer - * @param size length of data - * @param allow_decrypt If true and flash encryption is enabled, data on flash - * will be decrypted transparently as part of the read. - * - * @return ESP_OK on success, ESP_ERR_FLASH_OP_FAIL on SPI failure, - * ESP_ERR_FLASH_OP_TIMEOUT on SPI timeout. - */ -esp_err_t bootloader_flash_read(size_t src_addr, void *dest, size_t size, bool allow_decrypt); - - -/** - * @brief Write data to Flash. - * - * @note All of dest_addr, src and size have to be 4-byte aligned. If write_encrypted is set, dest_addr and size must be 32-byte aligned. - * - * @note In bootloader, when write_encrypted == true, the src buffer is encrypted in place. - * - * @note [ESP-TEE] Using this API from the TEE will return an error if the dest_addr lies - * within the active TEE partition range. - * - * @param dest_addr Destination address to write in Flash. - * @param src Pointer to the data to write to flash - * @param size Length of data in bytes. - * @param write_encrypted If true, data will be written encrypted on flash. - * - * @return ESP_OK on success, ESP_ERR_FLASH_OP_FAIL on SPI failure, - * ESP_ERR_FLASH_OP_TIMEOUT on SPI timeout. - */ -esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool write_encrypted); - -/** - * @brief Erase the Flash sector. - * - * @param sector Sector number, the count starts at sector 0, 4KB per sector. - * - * @return esp_err_t - */ -esp_err_t bootloader_flash_erase_sector(size_t sector); - -/** - * @brief Erase the Flash range. - * - * @note [ESP-TEE] Using this API from the TEE will return an error if the start_addr lies - * within the active TEE partition range. - * - * @param start_addr start address of flash offset - * @param size sector aligned size to be erased - * - * @return esp_err_t - */ -esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size); - -/** - * @brief Execute a user command on the flash - * - * @param command The command value to execute. - * @param mosi_data MOSI data to send - * @param mosi_len Length of MOSI data, in bits - * @param miso_len Length of MISO data to receive, in bits - * @return Received MISO data - */ -uint32_t bootloader_execute_flash_command(uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len); - -/** - * @brief Read the SFDP of the flash - * - * @param sfdp_addr Address of the parameter to read - * @param miso_byte_num Bytes to read - * @return The read SFDP, little endian, 4 bytes at most - */ -uint32_t bootloader_flash_read_sfdp(uint32_t sfdp_addr, unsigned int miso_byte_num); - -/** - * @brief Enable the flash write protect (WEL bit). - */ -void bootloader_enable_wp(void); - -/** - * @brief Once this function is called, - * any on-going internal operations will be terminated and the device will return to its default power-on - * state and lose all the current volatile settings, such as Volatile Status Register bits, Write Enable Latch - * (WEL) status, Program/Erase Suspend status, etc. - */ -void bootloader_spi_flash_reset(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c index b9c24ea354d..a2032ae8eee 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c @@ -4,17 +4,22 @@ * SPDX-License-Identifier: Apache-2.0 */ #include - -#include -#include -#include "esp_efuse.h" #include "sdkconfig.h" +#include "esp_efuse.h" +#include "esp_log.h" +#include "esp_flash_encrypt.h" +#include "esp_private/bootloader_flash_internal.h" #include "soc/soc_caps.h" #include "hal/efuse_ll.h" #include "hal/efuse_hal.h" +#include "hal/spi_flash_types.h" +#include "hal/esp_flash_err.h" +#include "spi_flash_defs.h" #if !NON_OS_BUILD #include "spi_flash_mmap.h" +// This dependency will be removed in the future. IDF-5025 +#include "esp_flash.h" #endif #include "hal/spi_flash_ll.h" #include "rom/spi_flash.h" @@ -23,9 +28,6 @@ #include "hal/spimem_flash_ll.h" #endif -// This dependency will be removed in the future. IDF-5025 -#include "esp_flash.h" - #include "esp_rom_spiflash.h" #ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH @@ -64,7 +66,7 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size) return NULL; /* existing mapping in use... */ } const void *result = NULL; - uint32_t src_page = src_addr & ~(SPI_FLASH_MMU_PAGE_SIZE - 1); + uint32_t src_page = src_addr & ~(CONFIG_MMU_PAGE_SIZE - 1); size += (src_addr - src_page); esp_err_t err = spi_flash_mmap(src_page, size, SPI_FLASH_MMAP_FLAG_DATA | SPI_FLASH_MMAP_FLAG_BLOCKS_WRITE, &result, &map); if (err != ESP_OK) { @@ -123,7 +125,6 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size) #include "hal/mmu_ll.h" #include "hal/cache_hal.h" #include "hal/cache_ll.h" -#include "esp_flash_chips/spi_flash_defs.h" #if ESP_TEE_BUILD #include "esp_fault.h" @@ -362,7 +363,7 @@ const void *bootloader_mmap(uint32_t src_paddr, uint32_t size) #if CONFIG_IDF_TARGET_ESP32 uint32_t count = GET_REQUIRED_MMU_PAGES(size, src_paddr); int e = cache_flash_mmu_set(0, 0, FLASH_MMAP_VADDR, src_paddr_aligned, 64, count); - ESP_EARLY_LOGV(TAG, "after mapping, starting from paddr=0x%08" PRIx32 " and vaddr=0x%08" PRIx32 ", 0x%" PRIx32 " bytes are mapped", src_paddr_aligned, (uint32_t)FLASH_MMAP_VADDR, count * SPI_FLASH_MMU_PAGE_SIZE); + ESP_EARLY_LOGV(TAG, "after mapping, starting from paddr=0x%08" PRIx32 " and vaddr=0x%08" PRIx32 ", 0x%" PRIx32 " bytes are mapped", src_paddr_aligned, (uint32_t)FLASH_MMAP_VADDR, count * CONFIG_MMU_PAGE_SIZE); if (e != 0) { ESP_EARLY_LOGE(TAG, "cache_flash_mmu_set failed: %d", e); Cache_Read_Enable(0); @@ -491,20 +492,20 @@ static esp_err_t bootloader_flash_read_allow_decrypt(size_t src_addr, void *dest #else cache_hal_suspend(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); //---------------Invalidating entries at to-be-mapped v_addr------------------------ - cache_hal_invalidate_addr(FLASH_READ_VADDR, SPI_FLASH_MMU_PAGE_SIZE); + cache_hal_invalidate_addr(FLASH_READ_VADDR, CONFIG_MMU_PAGE_SIZE); #endif #endif //---------------Do mapping------------------------ ESP_EARLY_LOGD(TAG, "mmu set block paddr=0x%08" PRIx32 " (was 0x%08" PRIx32 ")", map_at, current_read_mapping); #if CONFIG_IDF_TARGET_ESP32 - //Should never fail if we only map a SPI_FLASH_MMU_PAGE_SIZE to the vaddr starting from FLASH_READ_VADDR + //Should never fail if we only map a CONFIG_MMU_PAGE_SIZE to the vaddr starting from FLASH_READ_VADDR // Return value unused if asserts are disabled int e __attribute__((unused)) = cache_flash_mmu_set(0, 0, FLASH_READ_VADDR, map_at, 64, 1); assert(e == 0); #else uint32_t actual_mapped_len = 0; - mmu_hal_map_region(0, MMU_TARGET_FLASH0, FLASH_READ_VADDR, map_at, SPI_FLASH_MMU_PAGE_SIZE - 1, &actual_mapped_len); + mmu_hal_map_region(0, MMU_TARGET_FLASH0, FLASH_READ_VADDR, map_at, CONFIG_MMU_PAGE_SIZE - 1, &actual_mapped_len); #endif current_read_mapping = map_at; @@ -1017,15 +1018,6 @@ esp_err_t IRAM_ATTR bootloader_flash_reset_chip(void) return ESP_OK; } -bool IRAM_ATTR bootloader_flash_is_octal_mode_enabled(void) -{ -#if SOC_SPI_MEM_SUPPORT_FLASH_OPI_MODE - return efuse_ll_get_flash_type(); -#else - return false; -#endif -} - esp_rom_spiflash_read_mode_t bootloader_flash_get_spi_mode(void) { esp_rom_spiflash_read_mode_t spi_mode = ESP_ROM_SPIFLASH_FASTRD_MODE; diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c index 47a86f8c896..0d44ba5ed56 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,7 +20,8 @@ #include "soc/soc_caps.h" #include "flash_qio_mode.h" #include "bootloader_flash_config.h" -#include "bootloader_flash_priv.h" +#include "esp_private/bootloader_flash_internal.h" +#include "spi_flash_defs.h" #include "bootloader_common.h" #include "bootloader_flash.h" #include "bootloader_init.h" @@ -28,6 +29,7 @@ #include "hal/mmu_ll.h" #include "hal/cache_hal.h" #include "hal/cache_ll.h" +#include "hal/efuse_ll.h" #define FLASH_IO_MATRIX_DUMMY_40M 0 #define FLASH_IO_MATRIX_DUMMY_80M 0 @@ -50,7 +52,7 @@ void bootloader_flash_update_size(uint32_t size) void IRAM_ATTR bootloader_flash_cs_timing_config() { //SPI0/1 share the cs_hold / cs_setup, cd_hold_time / cd_setup_time, cs_hold_delay registers for FLASH, so we only need to set SPI0 related registers here - if (bootloader_flash_is_octal_mode_enabled()) { + if (efuse_ll_get_flash_type()) { SET_PERI_REG_MASK(SPI_MEM_USER_REG(0), SPI_MEM_CS_HOLD_M | SPI_MEM_CS_SETUP_M); SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_TIME_V, FLASH_CS_HOLD_TIME, SPI_MEM_CS_HOLD_TIME_S); @@ -286,7 +288,7 @@ esp_err_t bootloader_init_spi_flash(void) bootloader_flash_unlock(); #if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT - if (!bootloader_flash_is_octal_mode_enabled()) { + if (!efuse_ll_get_flash_type()) { bootloader_enable_qio_mode(); } #endif diff --git a/components/bootloader_support/src/bootloader_common_loader.c b/components/bootloader_support/src/bootloader_common_loader.c index 6716f4336f1..8d794ba275f 100644 --- a/components/bootloader_support/src/bootloader_common_loader.c +++ b/components/bootloader_support/src/bootloader_common_loader.c @@ -19,9 +19,10 @@ #include "soc/efuse_reg.h" #include "soc/chip_revision.h" #include "hal/efuse_hal.h" +#include "hal/misc.h" #include "esp_image_format.h" #include "sys/param.h" -#include "bootloader_flash_priv.h" +#include "esp_private/bootloader_flash_internal.h" #include "esp_rom_caps.h" #include "esp_macros.h" diff --git a/components/bootloader_support/src/bootloader_utility.c b/components/bootloader_support/src/bootloader_utility.c index 6063b06a8e9..b4cade22c97 100644 --- a/components/bootloader_support/src/bootloader_utility.c +++ b/components/bootloader_support/src/bootloader_utility.c @@ -38,7 +38,7 @@ #include "esp_secure_boot.h" #include "esp_flash_encrypt.h" #include "esp_flash_partitions.h" -#include "bootloader_flash_priv.h" +#include "esp_private/bootloader_flash_internal.h" #include "bootloader_random.h" #include "bootloader_config.h" #include "bootloader_common.h" @@ -1067,12 +1067,12 @@ static void set_cache_and_start_app( //The addr is aligned, so we add the mask off length to the size, to make sure the corresponding buses are enabled. drom_size = (drom_load_addr - drom_load_addr_aligned) + drom_size; #if CONFIG_IDF_TARGET_ESP32 - uint32_t drom_page_count = (drom_size + SPI_FLASH_MMU_PAGE_SIZE - 1) / SPI_FLASH_MMU_PAGE_SIZE; + uint32_t drom_page_count = (drom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE; rc = cache_flash_mmu_set(0, 0, drom_load_addr_aligned, drom_addr_aligned, 64, drom_page_count); ESP_EARLY_LOGV(TAG, "rc=%d", rc); rc = cache_flash_mmu_set(1, 0, drom_load_addr_aligned, drom_addr_aligned, 64, drom_page_count); ESP_EARLY_LOGV(TAG, "rc=%d", rc); - ESP_EARLY_LOGV(TAG, "after mapping rodata, starting from paddr=0x%08" PRIx32 " and vaddr=0x%08" PRIx32 ", 0x%" PRIx32 " bytes are mapped", drom_addr_aligned, drom_load_addr_aligned, drom_page_count * SPI_FLASH_MMU_PAGE_SIZE); + ESP_EARLY_LOGV(TAG, "after mapping rodata, starting from paddr=0x%08" PRIx32 " and vaddr=0x%08" PRIx32 ", 0x%" PRIx32 " bytes are mapped", drom_addr_aligned, drom_load_addr_aligned, drom_page_count * CONFIG_MMU_PAGE_SIZE); #else uint32_t actual_mapped_len = 0; if (s_flash_seg_needs_map(drom_load_addr_aligned)) { @@ -1091,12 +1091,12 @@ static void set_cache_and_start_app( //The addr is aligned, so we add the mask off length to the size, to make sure the corresponding buses are enabled. irom_size = (irom_load_addr - irom_load_addr_aligned) + irom_size; #if CONFIG_IDF_TARGET_ESP32 - uint32_t irom_page_count = (irom_size + SPI_FLASH_MMU_PAGE_SIZE - 1) / SPI_FLASH_MMU_PAGE_SIZE; + uint32_t irom_page_count = (irom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE; rc = cache_flash_mmu_set(0, 0, irom_load_addr_aligned, irom_addr_aligned, 64, irom_page_count); ESP_EARLY_LOGV(TAG, "rc=%d", rc); rc = cache_flash_mmu_set(1, 0, irom_load_addr_aligned, irom_addr_aligned, 64, irom_page_count); ESP_LOGV(TAG, "rc=%d", rc); - ESP_EARLY_LOGV(TAG, "after mapping text, starting from paddr=0x%08" PRIx32 " and vaddr=0x%08" PRIx32 ", 0x%" PRIx32 " bytes are mapped", irom_addr_aligned, irom_load_addr_aligned, irom_page_count * SPI_FLASH_MMU_PAGE_SIZE); + ESP_EARLY_LOGV(TAG, "after mapping text, starting from paddr=0x%08" PRIx32 " and vaddr=0x%08" PRIx32 ", 0x%" PRIx32 " bytes are mapped", irom_addr_aligned, irom_load_addr_aligned, irom_page_count * CONFIG_MMU_PAGE_SIZE); #else if (s_flash_seg_needs_map(irom_load_addr_aligned)) { mmu_hal_map_region(0, MMU_TARGET_FLASH0, irom_load_addr_aligned, irom_addr_aligned, irom_size, &actual_mapped_len); diff --git a/components/bootloader_support/src/esp32s31/bootloader_esp32s31.c b/components/bootloader_support/src/esp32s31/bootloader_esp32s31.c index d29f0e9f629..12cc192fb72 100644 --- a/components/bootloader_support/src/esp32s31/bootloader_esp32s31.c +++ b/components/bootloader_support/src/esp32s31/bootloader_esp32s31.c @@ -33,6 +33,7 @@ #include "hal/assist_debug_ll.h" #include "esp_rom_sys.h" #include "soc/regi2c_bias.h" +#include "soc/regi2c_mpll.h" #include "hal/regi2c_ctrl.h" #include "hal/psram_ctrlr_ll.h" diff --git a/components/efuse/CMakeLists.txt b/components/efuse/CMakeLists.txt index 38517b25842..a99e8b8a9ed 100644 --- a/components/efuse/CMakeLists.txt +++ b/components/efuse/CMakeLists.txt @@ -32,15 +32,15 @@ list(APPEND srcs "src/esp_efuse_api.c" if(non_os_build) idf_component_register(SRCS "${srcs}" - PRIV_REQUIRES bootloader_support soc spi_flash esp_hal_security + PRIV_REQUIRES bootloader_support soc esp_hal_security INCLUDE_DIRS "${include_dirs}" PRIV_INCLUDE_DIRS "${private_include}") else() list(APPEND srcs "src/esp_efuse_startup.c") if(${target} STREQUAL "linux") - set(priv_requires soc spi_flash esp_system esp_partition esp_hal_security) + set(priv_requires soc esp_system esp_partition esp_hal_security) else() - set(priv_requires bootloader_support soc spi_flash esp_system esp_partition esp_app_format esp_hal_security) + set(priv_requires bootloader_support soc esp_system esp_partition esp_app_format esp_hal_security) endif() idf_component_register(SRCS "${srcs}" PRIV_REQUIRES "${priv_requires}" diff --git a/components/esp_driver_i2s/CMakeLists.txt b/components/esp_driver_i2s/CMakeLists.txt index 6c1cabc023b..199dd919fa9 100644 --- a/components/esp_driver_i2s/CMakeLists.txt +++ b/components/esp_driver_i2s/CMakeLists.txt @@ -6,7 +6,7 @@ endif() set(srcs) set(include "include") -set(priv_requires esp_driver_gpio esp_driver_dma esp_pm esp_mm esp_hal_clock) +set(priv_requires esp_driver_gpio esp_driver_dma esp_pm esp_mm esp_hal_clock esp_mspi) # TODO(IDF-15984): potentially remove __ULP_BUILDV2 handling from esp_driver_i2s if(__ULP_BUILDV2) diff --git a/components/esp_driver_i2s/test_apps/i2s/main/CMakeLists.txt b/components/esp_driver_i2s/test_apps/i2s/main/CMakeLists.txt index 69eef6dfa2e..55300fc66f4 100644 --- a/components/esp_driver_i2s/test_apps/i2s/main/CMakeLists.txt +++ b/components/esp_driver_i2s/test_apps/i2s/main/CMakeLists.txt @@ -11,6 +11,6 @@ if(CONFIG_SOC_LIGHT_SLEEP_SUPPORTED) endif() idf_component_register(SRCS ${srcs} - PRIV_REQUIRES unity esp_driver_pcnt spi_flash - esp_driver_gpio esp_driver_i2s esp_driver_uart esp_psram esp_driver_gptimer + PRIV_REQUIRES unity esp_driver_pcnt esp_driver_gpio esp_driver_i2s esp_driver_uart + esp_psram esp_mspi esp_driver_gptimer WHOLE_ARCHIVE) diff --git a/components/esp_driver_spi/CMakeLists.txt b/components/esp_driver_spi/CMakeLists.txt index f4a6f3df23b..3d8b1856426 100644 --- a/components/esp_driver_spi/CMakeLists.txt +++ b/components/esp_driver_spi/CMakeLists.txt @@ -30,6 +30,6 @@ idf_component_register( SRCS ${srcs} INCLUDE_DIRS ${public_include} REQUIRES esp_pm esp_hal_gpspi esp_driver_dma - PRIV_REQUIRES esp_timer esp_mm esp_driver_gpio spi_flash + PRIV_REQUIRES esp_timer esp_mm esp_driver_gpio spi_flash esp_mspi LDFRAGMENTS "linker.lf" ) diff --git a/components/esp_driver_spi/test_apps/slave/main/CMakeLists.txt b/components/esp_driver_spi/test_apps/slave/main/CMakeLists.txt index aaca16eead7..b7c1d8ec6da 100644 --- a/components/esp_driver_spi/test_apps/slave/main/CMakeLists.txt +++ b/components/esp_driver_spi/test_apps/slave/main/CMakeLists.txt @@ -11,6 +11,6 @@ set(srcs idf_component_register( SRCS ${srcs} # esp_psram is required for CONFIG_SPIRAM, used by the release configs - PRIV_REQUIRES esp_driver_spi spi_flash esp_driver_gpio esp_psram + PRIV_REQUIRES esp_driver_spi esp_driver_gpio esp_mspi esp_psram WHOLE_ARCHIVE ) diff --git a/components/esp_hal_dma/CMakeLists.txt b/components/esp_hal_dma/CMakeLists.txt index f905fad0b3d..c13b6770e33 100644 --- a/components/esp_hal_dma/CMakeLists.txt +++ b/components/esp_hal_dma/CMakeLists.txt @@ -1,7 +1,4 @@ idf_build_get_property(target IDF_TARGET) -if(${target} STREQUAL "linux") - return() # This component is not supported by the POSIX/Linux simulator -endif() set(srcs) set(public_include "include") diff --git a/components/esp_hal_mspi/CMakeLists.txt b/components/esp_hal_mspi/CMakeLists.txt index afe56677597..720149c7850 100644 --- a/components/esp_hal_mspi/CMakeLists.txt +++ b/components/esp_hal_mspi/CMakeLists.txt @@ -1,14 +1,15 @@ idf_build_get_property(target IDF_TARGET) idf_build_get_property(esp_tee_build ESP_TEE_BUILD) -if(${target} STREQUAL "linux") - idf_component_register(INCLUDE_DIRS "include" - REQUIRES soc hal) - return() -endif() - set(srcs) set(includes "include" "${target}/include") +set(requires soc hal esp_hal_gpspi) +set(priv_requires esp_hal_gpio) + +if(NOT "${target}" STREQUAL "linux") + # TODO: IDF-15106 remove esp_hal_clock dependency + list(APPEND requires "esp_hal_clock") +endif() if(esp_tee_build) if(CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1) @@ -35,6 +36,6 @@ list(APPEND srcs "${target}/mspi_periph.c") idf_component_register( SRCS ${srcs} INCLUDE_DIRS ${includes} - REQUIRES soc hal esp_hal_gpspi esp_hal_clock # TODO: IDF-15106 remove esp_hal_clock dependency - PRIV_REQUIRES esp_hal_gpio + REQUIRES ${requires} + PRIV_REQUIRES ${priv_requires} ) diff --git a/components/esp_hal_mspi/esp32h21/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32h21/include/hal/mspi_ll.h index 1f83b4c3d4d..f9b41ccfb28 100644 --- a/components/esp_hal_mspi/esp32h21/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32h21/include/hal/mspi_ll.h @@ -25,6 +25,7 @@ #include "soc/pcr_struct.h" #include "hal/misc.h" #include "hal/assert.h" +#include "soc/spi_mem_c_reg.h" #ifdef __cplusplus extern "C" { diff --git a/components/esp_hal_mspi/include/hal/spi_flash_types.h b/components/esp_hal_mspi/include/hal/spi_flash_types.h index c669e0733ce..d529950cd5f 100644 --- a/components/esp_hal_mspi/include/hal/spi_flash_types.h +++ b/components/esp_hal_mspi/include/hal/spi_flash_types.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/esp_hal_mspi/linux/include/hal/.gitkeep b/components/esp_hal_mspi/linux/include/hal/.gitkeep deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/components/esp_hal_mspi/linux/mspi_periph.c b/components/esp_hal_mspi/linux/mspi_periph.c new file mode 100644 index 00000000000..a5d1863c141 --- /dev/null +++ b/components/esp_hal_mspi/linux/mspi_periph.c @@ -0,0 +1,5 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index 9df70371b2b..2c0fcfad34d 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -14,8 +14,6 @@ endif() set(public_include_dirs "include" "include/soc" "ldo/include" "debug_probe/include" "etm/include" - "mspi/mspi_timing_tuning/include" "mspi/mspi_timing_tuning/tuning_scheme_impl/include" - "mspi/mspi_intr/include" "mspi/esp_mspi_align/include" "mspi/mspi_mem_barrier/include" "power_supply/include" "modem/include") @@ -44,7 +42,7 @@ endif() set(requires esp_hal_gpio esp_hal_usb esp_hal_pmu esp_hal_regi2c esp_hal_uart esp_hal_debug_assist) set(priv_requires efuse # only esp_hw_support/adc_share_hw_ctrl.c requires efuse component - spi_flash + esp_mspi bootloader_support esp_hal_wdt esp_hal_rtc_timer @@ -156,27 +154,6 @@ if(NOT non_os_build) "port/regdma_link.c") endif() - if(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) - list(APPEND srcs "mspi/mspi_timing_tuning/mspi_timing_tuning.c") - if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY AND NOT CONFIG_IDF_TARGET_ESP32S3) - set(mspi_delay_file - "${CMAKE_CURRENT_LIST_DIR}/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c" - ) - if(EXISTS "${mspi_delay_file}") - list(APPEND srcs "mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c") - endif() - endif() - - if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_DQS) - list(APPEND srcs "mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c") - endif() - if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_FLASH_DELAY) - list(APPEND srcs "mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_flash_delay.c") - endif() - - list(APPEND srcs "mspi/mspi_intr/mspi_intr.c") - endif() - if(CONFIG_SOC_RTC_FAST_MEM_SUPPORTED AND CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB) list(APPEND srcs "sleep_wake_stub.c") endif() @@ -196,18 +173,6 @@ if(NOT non_os_build) else() if(ESP_TEE_BUILD) list(APPEND srcs "esp_clk.c" "hw_random.c") - if(CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1) - list(APPEND srcs "mspi/mspi_timing_tuning/mspi_timing_tuning.c") - if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY) - list(APPEND srcs "mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c") - endif() - if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_DQS) - list(APPEND srcs "mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c") - endif() - if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_FLASH_DELAY) - list(APPEND srcs "mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_flash_delay.c") - endif() - endif() endif() # Requires "_esp_error_check_failed()" function @@ -230,9 +195,6 @@ idf_define_esp_err_codes(HEADERS include/esp_memprot_err.h) idf_build_get_property(target IDF_TARGET) add_subdirectory(port/${target}) -if(CONFIG_SOC_SPI_MEM_SUPPORT_TIMING_TUNING) - add_subdirectory(mspi/mspi_timing_tuning/port/${target}) -endif() add_subdirectory(lowpower) add_subdirectory(modem) diff --git a/components/esp_hw_support/README.md b/components/esp_hw_support/README.md index a0fc88dddf5..b15a1b06813 100644 --- a/components/esp_hw_support/README.md +++ b/components/esp_hw_support/README.md @@ -86,7 +86,7 @@ This document describes the implementation differences of MSPI interrupt handlin | File | Description | |------|-------------| -| `components/esp_hw_support/mspi/mspi_intr/mspi_intr.c` | Shared MSPI interrupt management | +| `components/esp_mspi/mspi_intr/mspi_intr.c` | Shared MSPI interrupt management | | `components/esp_psram/system_layer/esp_psram_mspi.c` | PSRAM specific interrupt handling | --- diff --git a/components/esp_hw_support/mspi/linker.lf b/components/esp_hw_support/mspi/linker.lf index b64138f4b4d..2264f9f6072 100644 --- a/components/esp_hw_support/mspi/linker.lf +++ b/components/esp_hw_support/mspi/linker.lf @@ -4,19 +4,3 @@ entries: if APP_BUILD_TYPE_PURE_RAM_APP = n: esp_mspi_align:esp_mspi_get_alignment (noflash) esp_mspi_align:esp_mspi_buffer_alignment_satisfied (noflash) - -[mapping:mspi_timing_tuning_driver] -archive: libesp_hw_support.a -entries: - -if APP_BUILD_TYPE_PURE_RAM_APP = n: - mspi_timing_tuning (noflash) - if SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY = y: - mspi_timing_by_mspi_delay (noflash) - mspi_timing_config (noflash) - if SOC_MEMSPI_TIMING_TUNING_BY_DQS = y: - mspi_timing_by_dqs (noflash) - if SOC_MEMSPI_TIMING_TUNING_BY_FLASH_DELAY = y: - mspi_timing_by_flash_delay (noflash) - if SOC_MEMSPI_TIMING_TUNING_BY_DQS = y || SOC_MEMSPI_TIMING_TUNING_BY_FLASH_DELAY = y: - mspi_timing_config (noflash) diff --git a/components/esp_hw_support/sleep_gpio.c b/components/esp_hw_support/sleep_gpio.c index de4b23f5b5d..d67bb74a8c2 100644 --- a/components/esp_hw_support/sleep_gpio.c +++ b/components/esp_hw_support/sleep_gpio.c @@ -40,7 +40,6 @@ #include "esp_private/sleep_gpio.h" #include "esp_private/spi_flash_os.h" #include "esp_private/startup_internal.h" -#include "bootloader_flash.h" ESP_LOG_ATTR_TAG(TAG, "sleep_gpio"); @@ -152,7 +151,7 @@ void esp_sleep_config_gpio_isolate(void) gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_HD), GPIO_PULLUP_ONLY); gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_WP), GPIO_PULLUP_ONLY); #if SOC_SPI_MEM_SUPPORT_FLASH_OPI_MODE - bool octal_mspi_required = bootloader_flash_is_octal_mode_enabled(); + bool octal_mspi_required = spi_flash_is_octal_mode_enabled(); #if CONFIG_SPIRAM_MODE_OCT octal_mspi_required |= true; #endif // CONFIG_SPIRAM_MODE_OCT diff --git a/components/esp_hw_support/test_apps/.build-test-rules.yml b/components/esp_hw_support/test_apps/.build-test-rules.yml index d7b2f899479..274a7f6dd3a 100644 --- a/components/esp_hw_support/test_apps/.build-test-rules.yml +++ b/components/esp_hw_support/test_apps/.build-test-rules.yml @@ -22,18 +22,6 @@ components/esp_hw_support/test_apps/host_test_linux: depends_components: - esp_hw_support -components/esp_hw_support/test_apps/mspi: - depends_components: - - esp_hw_support - - spi_flash - - esp_partition - - esp_hal_mspi - - soc - disable: - - if: IDF_TARGET not in ["esp32s3", "esp32p4", "esp32c61", "esp32c5", "esp32s31"] - - if: CONFIG_NAME in ["generic_timing_tuning_log_safe", "generic_timing_tuning_xip"] and IDF_TARGET in ["esp32s31"] - - if: CONFIG_NAME == "120sdr_120sdr" and IDF_TARGET in ["esp32s3", "esp32p4", "esp32s31"] - components/esp_hw_support/test_apps/mspi_psram_with_dfs: depends_components: - esp_hw_support diff --git a/components/esp_image_verify/src/esp_image_format.c b/components/esp_image_verify/src/esp_image_format.c index 4ef6f9d931f..dc63fb4ccc5 100644 --- a/components/esp_image_verify/src/esp_image_format.c +++ b/components/esp_image_verify/src/esp_image_format.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include "bootloader_util.h" @@ -22,7 +22,6 @@ #include "soc/soc_caps.h" #include "hal/mmu_types.h" #include "hal/cache_ll.h" -#include "spi_flash_mmap.h" #include "hal/efuse_hal.h" #include "sdkconfig.h" #include "esp_macros.h" @@ -688,7 +687,7 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme return ESP_ERR_NO_MEM; } uint32_t max_image_len; - if (__builtin_mul_overflow(max_pages, SPI_FLASH_MMU_PAGE_SIZE, &max_image_len)) { + if (__builtin_mul_overflow(max_pages, CONFIG_MMU_PAGE_SIZE, &max_image_len)) { max_image_len = UINT32_MAX; } segment_data.data_len = MIN(data_len_remain, max_image_len); @@ -899,18 +898,18 @@ static esp_err_t verify_segment_header(int index, const esp_image_segment_header metadata->mmu_page_size = (1UL << mmu_page_size); } else { // Fall back to default MMU page size - metadata->mmu_page_size = SPI_FLASH_MMU_PAGE_SIZE; + metadata->mmu_page_size = CONFIG_MMU_PAGE_SIZE; } - if (metadata->mmu_page_size != SPI_FLASH_MMU_PAGE_SIZE) { - ESP_LOGI(TAG, "MMU page size mismatch, configured: 0x%x, found: 0x%"PRIx32, SPI_FLASH_MMU_PAGE_SIZE, metadata->mmu_page_size); + if (metadata->mmu_page_size != CONFIG_MMU_PAGE_SIZE) { + ESP_LOGI(TAG, "MMU page size mismatch, configured: 0x%x, found: 0x%"PRIx32, CONFIG_MMU_PAGE_SIZE, metadata->mmu_page_size); } } else if (index == 0 && is_bootloader(metadata->start_addr)) { // Bootloader always uses the default MMU page size - metadata->mmu_page_size = SPI_FLASH_MMU_PAGE_SIZE; + metadata->mmu_page_size = CONFIG_MMU_PAGE_SIZE; } #else // SOC_MMU_PAGE_SIZE_CONFIGURABLE - metadata->mmu_page_size = SPI_FLASH_MMU_PAGE_SIZE; + metadata->mmu_page_size = CONFIG_MMU_PAGE_SIZE; #endif // !SOC_MMU_PAGE_SIZE_CONFIGURABLE const int mmu_page_size = metadata->mmu_page_size; diff --git a/components/esp_lcd/test_apps/rgb_lcd/main/CMakeLists.txt b/components/esp_lcd/test_apps/rgb_lcd/main/CMakeLists.txt index 7379bc71be0..390393c29b5 100644 --- a/components/esp_lcd/test_apps/rgb_lcd/main/CMakeLists.txt +++ b/components/esp_lcd/test_apps/rgb_lcd/main/CMakeLists.txt @@ -5,5 +5,5 @@ set(srcs "test_app_main.c" # In order for the cases defined by `TEST_CASE` to be linked into the final elf, # the component can be registered as WHOLE_ARCHIVE idf_component_register(SRCS ${srcs} - PRIV_REQUIRES esp_lcd unity esp_timer spi_flash esp_driver_ppa efuse + PRIV_REQUIRES esp_lcd unity esp_timer esp_mspi esp_driver_ppa efuse WHOLE_ARCHIVE) diff --git a/components/esp_libc/CMakeLists.txt b/components/esp_libc/CMakeLists.txt index 84920715ad7..b0c7e0ae9fd 100644 --- a/components/esp_libc/CMakeLists.txt +++ b/components/esp_libc/CMakeLists.txt @@ -82,7 +82,7 @@ else() list(APPEND ldfragments src/picolibc/libc.lf) endif() -set(priv_reqs soc spi_flash) +set(priv_reqs soc esp_mspi) if(IDF_BUILD_V2) if(CONFIG_VFS_SUPPORT_IO) diff --git a/components/esp_libc/test_apps/newlib/main/CMakeLists.txt b/components/esp_libc/test_apps/newlib/main/CMakeLists.txt index 845cd944aeb..410b85d6fee 100644 --- a/components/esp_libc/test_apps/newlib/main/CMakeLists.txt +++ b/components/esp_libc/test_apps/newlib/main/CMakeLists.txt @@ -21,5 +21,5 @@ if(CONFIG_LIBC_OPTIMIZED_MISALIGNED_ACCESS) endif() idf_component_register(SRCS "${srcs}" - PRIV_REQUIRES unity vfs cmock esp_timer spi_flash test_utils pthread esp_psram + PRIV_REQUIRES unity vfs cmock esp_timer esp_mspi test_utils pthread esp_psram WHOLE_ARCHIVE) diff --git a/components/esp_mm/CMakeLists.txt b/components/esp_mm/CMakeLists.txt index b79155fc706..6ad14a87ea3 100644 --- a/components/esp_mm/CMakeLists.txt +++ b/components/esp_mm/CMakeLists.txt @@ -6,8 +6,8 @@ endif() set(includes "include") -# Note: requires spi_flash for cache_utils, will be refactored -set(priv_requires heap spi_flash esp_hal_dma) +# Note: requires esp_mspi for cache_utils +set(priv_requires heap esp_hal_dma esp_mspi) set(srcs) diff --git a/components/esp_mspi/CMakeLists.txt b/components/esp_mspi/CMakeLists.txt new file mode 100644 index 00000000000..6686a3b4826 --- /dev/null +++ b/components/esp_mspi/CMakeLists.txt @@ -0,0 +1,106 @@ +idf_build_get_property(target IDF_TARGET) +idf_build_get_property(non_os_build NON_OS_BUILD) + +if(${target} STREQUAL "linux") + idf_component_register(SRCS "linux/cache_utils.c" + INCLUDE_DIRS include + REQUIRES esp_hal_mspi) + return() +endif() + +if(non_os_build OR CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) + set(priv_requires bootloader_support soc esp_hal_gpio) + set(requires hal esp_hal_mspi) + set(srcs "spi_flash_wrap.c" "spi_flash_os_tee_stub.c") + if(ESP_TEE_BUILD) + if(CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1) + list(APPEND srcs "mspi_timing_tuning/mspi_timing_tuning.c") + if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY) + list(APPEND srcs "mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c") + endif() + if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_DQS) + list(APPEND srcs "mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c") + endif() + if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_FLASH_DELAY) + list(APPEND srcs "mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_flash_delay.c") + endif() + endif() + endif() +else() + set(priv_requires bootloader_support soc esp_hal_gpio esp_mm) + set(requires hal esp_hal_mspi) + + set(srcs "flash_brownout_hook.c" "cache_utils.c" "flash_ops.c" "spi_flash_wrap.c") + + # MSPI0 Octal flash init + if(CONFIG_SOC_SPI_MEM_SUPPORT_FLASH_OPI_MODE) + list(APPEND srcs "${target}/spi_flash_oct_flash_init.c") + endif() + + if(CONFIG_SPI_FLASH_HPM_ON) + list(APPEND srcs "spi_flash_hpm_enable.c") + endif() + + if(CONFIG_ESP_SLEEP_SET_FLASH_DPD) + list(APPEND srcs "spi_flash_dpd_enable.c") + endif() + + # MSPI timing tuning + list(APPEND srcs "mspi_timing_tuning/mspi_timing_tuning.c") + if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY AND NOT CONFIG_IDF_TARGET_ESP32S3) + set(mspi_delay_file + "${CMAKE_CURRENT_LIST_DIR}/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c" + ) + if(EXISTS "${mspi_delay_file}") + list(APPEND srcs "mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c") + endif() + endif() + if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_DQS) + list(APPEND srcs "mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c") + endif() + if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_FLASH_DELAY) + list(APPEND srcs "mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_flash_delay.c") + endif() + + # MSPI intr + list(APPEND srcs "mspi_intr/mspi_intr.c") +endif() + +set(include_dirs include + "mspi_timing_tuning/include" + "mspi_timing_tuning/tuning_scheme_impl/include" + "mspi_intr/include") + +if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${target}") + list(APPEND include_dirs "${target}") +endif() + +set(ldfragments linker.lf) + +idf_component_register(SRCS "${srcs}" + REQUIRES ${requires} + PRIV_REQUIRES "${priv_requires}" + INCLUDE_DIRS ${include_dirs} + LDFRAGMENTS ${ldfragments}) + +# Avoid cache miss by unexpected inlineing when built by -Os +set_source_files_properties(${cache_srcs} PROPERTIES COMPILE_FLAGS "-fno-inline-functions") +if(CMAKE_C_COMPILER_ID MATCHES "GNU") + # These flags are GCC specific + set_property(SOURCE ${cache_srcs} APPEND_STRING PROPERTY COMPILE_FLAGS + " -fno-inline-small-functions -fno-inline-functions-called-once") +endif() + +if(NOT non_os_build AND NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) + if(CONFIG_SPIRAM) + # esp_mspi_get_io() queries esp_psram_io_get_cs_io() for the PSRAM CS pin + idf_component_optional_requires(PRIVATE esp_psram) + endif() + # Force linking init_flash_os ESP_SYSTEM_INIT_FN to ensure it's not discarded by linker + target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_mspi_flash_ops_include_func") +endif() + +idf_build_get_property(target IDF_TARGET) +if(CONFIG_SOC_SPI_MEM_SUPPORT_TIMING_TUNING) + add_subdirectory(mspi_timing_tuning/port/${target}) +endif() diff --git a/components/esp_mspi/Kconfig b/components/esp_mspi/Kconfig new file mode 100644 index 00000000000..b10e74fd1bf --- /dev/null +++ b/components/esp_mspi/Kconfig @@ -0,0 +1,85 @@ +menu "MSPI Flash configuration" + depends on !APP_BUILD_TYPE_PURE_RAM_APP + + menu "SPI Flash behavior when brownout" + + config SPI_FLASH_BROWNOUT_RESET_XMC + bool "Enable sending reset when brownout for XMC flash chips" + default y + select SPI_FLASH_BROWNOUT_RESET + help + When this option is selected, the patch will be enabled for XMC. + Follow the recommended flow by XMC for better stability. + + DO NOT DISABLE UNLESS YOU KNOW WHAT YOU ARE DOING. + + config SPI_FLASH_BROWNOUT_RESET + bool + default y + select ESP_BROWNOUT_USE_INTR + help + When brownout happens during flash erase/write operations, + send reset command to stop the flash operations to improve stability. + + endmenu + + menu "Optional and Experimental MSPI Features (READ DOCS FIRST)" + + comment "Features here require specific hardware (READ DOCS FIRST!)" + + config SPI_FLASH_UNDER_HIGH_FREQ + bool + default y if ESPTOOLPY_FLASHFREQ_120M + help + This is a helper config for HPM. Invisible for users. + + choice SPI_FLASH_HPM + prompt "High Performance Mode (READ DOCS FIRST, > 80MHz)" + depends on SOC_SPI_MEM_FLASH_SUPPORT_HPM && !ESPTOOLPY_OCT_FLASH + default SPI_FLASH_HPM_AUTO + help + Whether the High Performance Mode of Flash is enabled. As an optional feature, user needs to manually + enable this option as a confirmation. To be back-compatible with earlier IDF version, this option is + automatically enabled with warning when Flash running > 80Mhz. + + config SPI_FLASH_HPM_ENA + # Not using name of SPI_FLASH_HPM_ENABLE because it was used as an invisible option and we don't want + # to inherit the value of that one + bool "Enable" + config SPI_FLASH_HPM_AUTO + bool "Auto (Not recommended)" + config SPI_FLASH_HPM_DIS + bool "Disabled" + endchoice + + config SPI_FLASH_HPM_ON + bool + # For ESP32-S3, it's enabled by default. For later chips it should be disabled by default + default y if (IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32P4) && ((SPI_FLASH_HPM_ENA || SPI_FLASH_HPM_AUTO)) || \ + (!IDF_TARGET_ESP32S3 && SPI_FLASH_HPM_ENA) + help + This option is invisible, and will be selected automatically + when ``ESPTOOLPY_FLASHFREQ_120M`` is selected. + + choice SPI_FLASH_HPM_DC + prompt "Support HPM using DC (READ DOCS FIRST)" + depends on SPI_FLASH_HPM_ON + default SPI_FLASH_HPM_DC_AUTO + help + This feature needs your bootloader to be compiled DC-aware (BOOTLOADER_FLASH_DC_AWARE=y). Otherwise the + chip will not be able to boot after a reset. + + config SPI_FLASH_HPM_DC_AUTO + bool "Auto (Enable when bootloader support enabled (BOOTLOADER_FLASH_DC_AWARE))" + config SPI_FLASH_HPM_DC_DISABLE + bool "Disable (READ DOCS FIRST)" + endchoice + + config SPI_FLASH_HPM_DC_ON + bool + default y if SPI_FLASH_HPM_DC_AUTO && BOOTLOADER_FLASH_DC_AWARE + help + This is a helper config for HPM. Whether HPM-DC is enabled is also determined by bootloader. + Invisible for users. + endmenu +endmenu diff --git a/components/esp_mspi/README.md b/components/esp_mspi/README.md new file mode 100644 index 00000000000..a89978c9edc --- /dev/null +++ b/components/esp_mspi/README.md @@ -0,0 +1,8 @@ +# `esp_mspi` + +The `esp_mspi` component provides shared low-level support for flash and PSRAM connected through the MSPI peripheral. + +- Coordinates flash operations, cache handling, and memory access. +- Provides MSPI timing tuning, high-performance mode, and power management support. +- Provides shared alignment and memory-barrier utilities. +- Serves as the common MSPI layer used by `spi_flash` for flash access and by `esp_psram` for external RAM support. diff --git a/components/spi_flash/cache_utils.c b/components/esp_mspi/cache_utils.c similarity index 99% rename from components/spi_flash/cache_utils.c rename to components/esp_mspi/cache_utils.c index d18f81dc474..8e8cb40af28 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/esp_mspi/cache_utils.c @@ -305,7 +305,6 @@ void spi_flash_op_unlock(void) #endif // #if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) ) } - void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu(void) { spi_flash_op_lock(); @@ -350,7 +349,6 @@ void IRAM_ATTR spi_flash_enable_interrupts_caches_no_os(void) #endif // CONFIG_FREERTOS_UNICORE - void IRAM_ATTR spi_flash_enable_cache(uint32_t cpuid) { #if CONFIG_IDF_TARGET_ESP32 @@ -851,7 +849,6 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable ESP_EARLY_LOGW(TAG, "Flash is not in QIO mode, do not support wrap."); #endif - #if (CONFIG_IDF_TARGET_ESP32S3 && CONFIG_SPIRAM) extern bool psram_support_wrap_size(uint32_t wrap_size); if (!psram_support_wrap_size(spiram_wrap_size)) { diff --git a/components/spi_flash/esp32s3/opi_flash_private.h b/components/esp_mspi/esp32s3/esp_private/opi_flash_private.h similarity index 89% rename from components/spi_flash/esp32s3/opi_flash_private.h rename to components/esp_mspi/esp32s3/esp_private/opi_flash_private.h index eb98d04c0bd..eeef0501d25 100644 --- a/components/spi_flash/esp32s3/opi_flash_private.h +++ b/components/esp_mspi/esp32s3/esp_private/opi_flash_private.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/spi_flash/esp32s3/opi_flash_cmd_format_mxic.h b/components/esp_mspi/esp32s3/opi_flash_cmd_format_mxic.h similarity index 96% rename from components/spi_flash/esp32s3/opi_flash_cmd_format_mxic.h rename to components/esp_mspi/esp32s3/opi_flash_cmd_format_mxic.h index 6be9b51ec08..b1f07954761 100644 --- a/components/spi_flash/esp32s3/opi_flash_cmd_format_mxic.h +++ b/components/esp_mspi/esp32s3/opi_flash_cmd_format_mxic.h @@ -1,14 +1,14 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include -#include "esp_flash_chips/spi_flash_defs.h" +#include "spi_flash_defs.h" //MXIC OPI mode needs two bytes of command - 2nd byte is the inversion of the command (1st) byte. S3 HW send LSB first - #define MXIC_CMD16(cmd8) ( (uint8_t)(cmd8) | ((uint8_t)(~(cmd8)) << 8) ) +#define MXIC_CMD16(cmd8) ( (uint8_t)(cmd8) | ((uint8_t)(~(cmd8)) << 8) ) #define OPI_CMD_FORMAT_MXIC_STR() { \ .rdid = { \ diff --git a/components/spi_flash/esp32s3/spi_flash_oct_flash_init.c b/components/esp_mspi/esp32s3/spi_flash_oct_flash_init.c similarity index 99% rename from components/spi_flash/esp32s3/spi_flash_oct_flash_init.c rename to components/esp_mspi/esp32s3/spi_flash_oct_flash_init.c index 2287e96b57a..c27c6de3b37 100644 --- a/components/spi_flash/esp32s3/spi_flash_oct_flash_init.c +++ b/components/esp_mspi/esp32s3/spi_flash_oct_flash_init.c @@ -10,7 +10,7 @@ #include "esp32s3/rom/spi_flash.h" #include "esp32s3/rom/opi_flash.h" #include "esp_private/spi_flash_os.h" -#include "opi_flash_private.h" +#include "esp_private/opi_flash_private.h" #include "soc/spi_mem_reg.h" #include "soc/io_mux_reg.h" #include "opi_flash_cmd_format_mxic.h" @@ -31,11 +31,9 @@ const static char *TAG = "Octal Flash"; extern const spiflash_legacy_funcs_t *rom_spiflash_legacy_funcs; static uint32_t s_chip_id; - static void s_register_rom_function(void) { - static spiflash_legacy_funcs_t rom_func = - { + static spiflash_legacy_funcs_t rom_func = { .read_sub_len = 32, .write_sub_len = 32, .unlock = esp_rom_opiflash_wait_idle, @@ -233,7 +231,6 @@ static void s_mxic_set_required_regs(uint32_t chip_id) } #endif - /*---------------------------------------------------------------------------------------------------- General Functions -----------------------------------------------------------------------------------------------------*/ diff --git a/components/spi_flash/flash_brownout_hook.c b/components/esp_mspi/flash_brownout_hook.c similarity index 91% rename from components/spi_flash/flash_brownout_hook.c rename to components/esp_mspi/flash_brownout_hook.c index 7d070c0b19b..0e797f41f6b 100644 --- a/components/spi_flash/flash_brownout_hook.c +++ b/components/esp_mspi/flash_brownout_hook.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/spi_flash/flash_ops.c b/components/esp_mspi/flash_ops.c similarity index 82% rename from components/spi_flash/flash_ops.c rename to components/esp_mspi/flash_ops.c index e0601f97871..e9f32e9d940 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/esp_mspi/flash_ops.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,10 +9,6 @@ #include #include #include // For MIN/MAX(a, b) - -#include -#include -#include #include #include #include "soc/io_mux_reg.h" @@ -20,9 +16,9 @@ #include "sdkconfig.h" #include "esp_attr.h" #include "esp_cpu.h" -#include "spi_flash_mmap.h" #include "esp_log.h" #include "esp_private/system_internal.h" +#include "esp_private/startup_internal.h" #include "esp_private/spi_flash_os.h" #include "esp_private/esp_clk.h" #include "esp_private/esp_gpio_reserve.h" @@ -35,7 +31,7 @@ #include "soc/spi_mem_reg.h" #include "esp32s3/rom/opi_flash.h" #include "esp32s3/rom/cache.h" -#include "esp32s3/opi_flash_private.h" +#include "esp_private/opi_flash_private.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rom/cache.h" #elif CONFIG_IDF_TARGET_ESP32C2 @@ -46,10 +42,8 @@ #include "esp32c61/rom/cache.h" #endif #include "esp_rom_spiflash.h" -#include "esp_flash_partitions.h" #include "esp_private/mspi_timing_tuning.h" #include "esp_private/cache_utils.h" -#include "esp_flash.h" #include "esp_attr.h" #include "bootloader_flash.h" #include "bootloader_flash_config.h" @@ -103,28 +97,12 @@ const spi_flash_guard_funcs_t *IRAM_ATTR spi_flash_guard_get(void) return s_flash_guard_ops; } - -#ifdef CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS -#define UNSAFE_WRITE_ADDRESS abort() -#else -#define UNSAFE_WRITE_ADDRESS return false -#endif - - -static __attribute__((unused)) bool is_safe_write_address(size_t addr, size_t size) -{ - if (!esp_partition_main_flash_region_safe(addr, size)) { - UNSAFE_WRITE_ADDRESS; - } - return true; -} - #if CONFIG_SPI_FLASH_ROM_IMPL #include "esp_heap_caps.h" void IRAM_ATTR *spi_flash_malloc_internal(size_t size) { - return heap_caps_malloc(size, MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL); + return heap_caps_malloc(size, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); } void IRAM_ATTR spi_flash_rom_impl_init(void) @@ -142,10 +120,19 @@ void IRAM_ATTR spi_flash_rom_impl_init(void) } #endif +bool IRAM_ATTR spi_flash_is_octal_mode_enabled(void) +{ +#if SOC_SPI_MEM_SUPPORT_FLASH_OPI_MODE + return efuse_ll_get_flash_type(); +#else + return false; +#endif +} + void IRAM_ATTR esp_mspi_pin_init(void) { #if SOC_SPI_MEM_SUPPORT_FLASH_OPI_MODE - bool octal_mspi_required = bootloader_flash_is_octal_mode_enabled(); + bool octal_mspi_required = spi_flash_is_octal_mode_enabled(); #if CONFIG_SPIRAM_MODE_OCT octal_mspi_required |= true; #endif @@ -164,8 +151,8 @@ void esp_mspi_pin_reserve(void) uint8_t mspi_io; for (esp_mspi_io_t i = 0; i < ESP_MSPI_IO_MAX; i++) { #if SOC_SPI_MEM_SUPPORT_FLASH_OPI_MODE - if (!bootloader_flash_is_octal_mode_enabled() - && i >= ESP_MSPI_IO_DQS && i <= ESP_MSPI_IO_D7) { + if (!spi_flash_is_octal_mode_enabled() + && i >= ESP_MSPI_IO_DQS && i <= ESP_MSPI_IO_D7) { continue; } #endif @@ -180,12 +167,12 @@ void esp_mspi_pin_reserve(void) esp_err_t IRAM_ATTR spi_flash_init_chip_state(void) { #if SOC_SPI_MEM_SUPPORT_FLASH_OPI_MODE - if (bootloader_flash_is_octal_mode_enabled()) { + if (spi_flash_is_octal_mode_enabled()) { return esp_opiflash_init(rom_spiflash_legacy_data->chip.device_id); } #endif #if CONFIG_SPI_FLASH_HPM_ON - return spi_flash_enable_high_performance_mode(); + return spi_flash_enable_high_performance_mode(); #endif // CONFIG_SPI_FLASH_HPM_ON return ESP_OK; } @@ -193,7 +180,7 @@ esp_err_t IRAM_ATTR spi_flash_init_chip_state(void) void IRAM_ATTR spi_flash_set_rom_required_regs(void) { #if SOC_SPI_MEM_SUPPORT_FLASH_OPI_MODE - if (bootloader_flash_is_octal_mode_enabled()) { + if (spi_flash_is_octal_mode_enabled()) { //Disable the variable dummy mode when doing timing tuning CLEAR_PERI_REG_MASK(SPI_MEM_DDR_REG(1), SPI_MEM_SPI_FMEM_VAR_DUMMY); /** @@ -205,21 +192,6 @@ void IRAM_ATTR spi_flash_set_rom_required_regs(void) #endif } -#if CONFIG_IDF_TARGET_ESP32S3 && CONFIG_SPIRAM_MODE_OCT -// This function will only be called when Octal PSRAM enabled. -void IRAM_ATTR spi_flash_set_vendor_required_regs(void) -{ - if (bootloader_flash_is_octal_mode_enabled()) { - esp_opiflash_set_required_regs(); - SET_PERI_REG_BITS(SPI_MEM_CACHE_FCTRL_REG(1), SPI_MEM_CACHE_USR_CMD_4BYTE_V, 1, SPI_MEM_CACHE_USR_CMD_4BYTE_S); - } else { - //Flash chip requires MSPI specifically, call this function to set them - // Set back MSPI registers after Octal PSRAM initialization. - SET_PERI_REG_BITS(SPI_MEM_CACHE_FCTRL_REG(1), SPI_MEM_CACHE_USR_CMD_4BYTE_V, 0, SPI_MEM_CACHE_USR_CMD_4BYTE_S); - } -} -#endif - static const uint8_t s_mspi_io_num_default[] = { MSPI_IOMUX_PIN_NUM_CLK, MSPI_IOMUX_PIN_NUM_MISO, @@ -323,3 +295,41 @@ esp_err_t IRAM_ATTR esp_mspi_32bit_address_flash_feature_check(void) return ESP_OK; } #endif // !CONFIG_IDF_TARGET_ESP32P4 || !CONFIG_APP_BUILD_TYPE_RAM + +#if CONFIG_ESP_SLEEP_SET_FLASH_DPD +static esp_err_t dpd_enter_func(void) +{ + spi_flash_ll_enter_dpd(&SPIMEM_LL_APB); + while (!spi_flash_ll_cmd_is_done(&SPIMEM_LL_APB)) { + //nop + } + return ESP_OK; +} + +static esp_err_t dpd_exit_func(void) +{ + spi_flash_ll_exit_dpd(&SPIMEM_LL_APB); + while (!spi_flash_ll_cmd_is_done(&SPIMEM_LL_APB)) { + //nop + } + return ESP_OK; +} + +ESP_SYSTEM_INIT_FN(init_flash_dpd, CORE, BIT(0), 125) +{ + // Register DPD function pointers + static spi_flash_dpd_funcs_t dpd_funcs = { + .enter_dpd = dpd_enter_func, + .exit_dpd = dpd_exit_func, + }; + spi_flash_dpd_register_funcs(&dpd_funcs); + + return ESP_OK; +} +#endif // CONFIG_ESP_SLEEP_SET_FLASH_DPD + +void esp_mspi_flash_ops_include_func(void) +{ + // Linker hook function, exists to make the linker examine this file so that + // the init_flash_dpd ESP_SYSTEM_INIT_FN above is not discarded. +} diff --git a/components/spi_flash/include/esp_flash_chips/spi_flash_override.h b/components/esp_mspi/include/esp_flash_chips/spi_flash_override.h similarity index 97% rename from components/spi_flash/include/esp_flash_chips/spi_flash_override.h rename to components/esp_mspi/include/esp_flash_chips/spi_flash_override.h index 09c2a80abac..d495c48ac07 100644 --- a/components/spi_flash/include/esp_flash_chips/spi_flash_override.h +++ b/components/esp_mspi/include/esp_flash_chips/spi_flash_override.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/spi_flash/include/esp_private/cache_utils.h b/components/esp_mspi/include/esp_private/cache_utils.h similarity index 100% rename from components/spi_flash/include/esp_private/cache_utils.h rename to components/esp_mspi/include/esp_private/cache_utils.h diff --git a/components/spi_flash/include/esp_private/spi_flash_os.h b/components/esp_mspi/include/esp_private/spi_flash_os.h similarity index 91% rename from components/spi_flash/include/esp_private/spi_flash_os.h rename to components/esp_mspi/include/esp_private/spi_flash_os.h index e835c1f1e94..76cabab624d 100644 --- a/components/spi_flash/include/esp_private/spi_flash_os.h +++ b/components/esp_mspi/include/esp_private/spi_flash_os.h @@ -14,19 +14,18 @@ #include "sdkconfig.h" #include "esp_rom_spiflash.h" #include "esp_err.h" +#include "esp_bit_defs.h" #include "soc/soc_caps.h" #include "soc/clk_tree_defs.h" - #include "hal/spi_flash_hal.h" - -#include "esp_flash.h" -#include "esp_flash_chips/esp_flash_types.h" +#include "esp_private/spi_share_hw_ctrl.h" #include "esp_flash_chips/spi_flash_override.h" #ifdef __cplusplus extern "C" { #endif +//-------------------Chip Related------------------// // Type of MSPI IO typedef enum { ESP_MSPI_IO_CLK = 0, @@ -53,6 +52,13 @@ typedef enum { */ esp_err_t spi_flash_init_chip_state(void); +/** + * @brief Check if octal flash mode is enabled in eFuse + * + * @return True if flash is in octal mode, false else + */ +bool spi_flash_is_octal_mode_enabled(void); + /** * @brief To initislize the MSPI pins */ @@ -154,6 +160,22 @@ bool spi_flash_hpm_dummy_adjust(void); #endif //CONFIG_SPI_FLASH_HPM_ON #if CONFIG_ESP_SLEEP_SET_FLASH_DPD +//-------------------DPD Related------------------// +/** + * @brief Structure holding DPD function pointers + */ +typedef struct { + esp_err_t (*enter_dpd)(void); + esp_err_t (*exit_dpd)(void); +} spi_flash_dpd_funcs_t; + +/** + * @brief Register DPD function pointers + * + * @param dpd_funcs Pointer to structure holding DPD function pointers + * @return ESP_OK on success + */ +esp_err_t spi_flash_dpd_register_funcs(spi_flash_dpd_funcs_t *dpd_funcs); /** * @brief Get the duration of entering deep power-down mode. @@ -176,7 +198,7 @@ uint32_t spi_flash_dpd_get_exit_duration(void); * @param wait_delay If true, wait tDP (enter) or tRES1 (exit) after the command. * If false, skip the delay; the caller must ensure timing is met elsewhere * - * @note If using self-provided flash (not the chip’s factory-default flash), consult its datasheet to use this API safely. + * @note If using self-provided flash (not the chip's factory-default flash), consult its datasheet to use this API safely. * * @return ESP_OK if success. */ @@ -252,7 +274,6 @@ typedef struct { spi_flash_guard_end_func_t end; /**< critical section end function. */ } spi_flash_guard_funcs_t; - /** * @brief Sets guard functions to access flash. * @@ -292,8 +313,6 @@ extern const spi_flash_guard_funcs_t g_flash_guard_no_os_ops; */ void spi_flash_rom_impl_init(void); - - #ifdef __cplusplus } #endif diff --git a/components/esp_mspi/include/spi_flash_defs.h b/components/esp_mspi/include/spi_flash_defs.h new file mode 100644 index 00000000000..9f9421d24cb --- /dev/null +++ b/components/esp_mspi/include/spi_flash_defs.h @@ -0,0 +1,92 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/soc_caps.h" + +#pragma once + +// SPI commands +#define CMD_RDID 0x9F +#define CMD_RDUID 0x4B /* Read the flash unique ID*/ +#define CMD_WRSR 0x01 +#define SR_WIP (1<<0) /* Status register write-in-progress bit */ +#define SR_WREN (1<<1) /* Status register write enable bit */ +#define CMD_WRSR2 0x31 /* Not all SPI flash uses this command */ +#define CMD_WRSR3 0x11 /* Not all SPI flash uses this command */ +#define CMD_WREN 0x06 +#define CMD_WRENVSR 0x50 /* Flash write enable for volatile SR bits */ +#define CMD_WRDI 0x04 +#define CMD_RDSR 0x05 +#define CMD_RDSR2 0x35 /* Not all SPI flash uses this command */ +#define CMD_RDSR3 0x15 /* Not all SPI flash uses this command */ +#define CMD_OTPEN 0x3A /* Enable OTP mode, not all SPI flash uses this command */ +#define CMD_RDSCUR 0x2B /* MXIC-specific, read security register */ +#define CMD_8READ 0xEC /* MXIC-specific, 8 I/O read */ +#define CMD_8DTRD 0xEE /* MXIC-specific, 8 I/O DTR read */ +#define CMD_RDFR 0x48 /* ISSI-specific, read function register */ + +#define CMD_FASTRD_QIO 0xEB +#define CMD_FASTRD_QIO_4B 0xEC +#define CMD_FASTRD_QUAD 0x6B +#define CMD_FASTRD_QUAD_4B 0x6C +#define CMD_FASTRD_DIO 0xBB +#define CMD_FASTRD_DIO_4B 0xBC +#define CMD_FASTRD_DUAL 0x3B +#define CMD_FASTRD_DUAL_4B 0x3C +#define CMD_FASTRD 0x0B +#define CMD_FASTRD_4B 0x0C +#define CMD_READ 0x03 /* Speed limited */ +#define CMD_READ_4B 0x13 /* Speed limited */ +#define CMD_SLOWRD_4B 0x13 + +#define CMD_CHIP_ERASE 0xC7 +#define CMD_SECTOR_ERASE 0x20 +#define CMD_SECTOR_ERASE_4B 0x21 +#define CMD_LARGE_BLOCK_ERASE 0xD8 /* 64KB block erase command */ +#define CMD_LARGE_BLOCK_ERASE_4B 0xDC /* 64KB block erase command */ +#define CMD_PROGRAM_PAGE 0x02 +#define CMD_PROGRAM_PAGE_4B 0x12 +#define CMD_SUSPEND 0x75 +#define CMD_RESUME 0x7A +#define CMD_HPMEN 0xA3 /* Enable High Performance mode on flash */ +#define CMD_WRAP 0x77 +#define CMD_BURST_RD 0xC0 /* wrap(0x77) and burst read are functionally same. But commands and formats is different */ + +#define CMD_RST_EN 0x66 +#define CMD_RST_DEV 0x99 +#define CMD_RESETEN 0x66 +#define CMD_RESET 0x99 + +#define CMD_RDSFDP 0x5A /* Read the SFDP of the flash */ + +// Flash vendors. +#define SPI_FLASH_GD 0xC8 +#define SPI_FLASH_ISSI 0x9D +#define SPI_FLASH_MXIC 0xC2 +#define SPI_FLASH_XMC_1 0x20 +#define SPI_FLASH_XMC_2 0x46 +#define SPI_FLASH_WINBOND 0xEF +#define SPI_FLASH_TH 0xCD +#define SPI_FLASH_BY 0x68 + +#define SPI_FLASH_DIO_DUMMY_BITLEN 4 +#define SPI_FLASH_QIO_DUMMY_BITLEN 6 +#define SPI_FLASH_DIO_ADDR_BITLEN 24 +#define SPI_FLASH_QIO_ADDR_BITLEN 24 +#define SPI_FLASH_QOUT_ADDR_BITLEN 24 +#define SPI_FLASH_QOUT_DUMMY_BITLEN 8 +#define SPI_FLASH_DOUT_ADDR_BITLEN 24 +#define SPI_FLASH_DOUT_DUMMY_BITLEN 8 +#define SPI_FLASH_FASTRD_ADDR_BITLEN 24 +#define SPI_FLASH_FASTRD_DUMMY_BITLEN 8 +#define SPI_FLASH_SLOWRD_ADDR_BITLEN 24 +#define SPI_FLASH_SLOWRD_DUMMY_BITLEN 0 +#define SPI_FLASH_OPISTR_ADDR_BITLEN 32 +#define SPI_FLASH_OPISTR_DUMMY_BITLEN 20 +#define SPI_FLASH_OPIDTR_ADDR_BITLEN 32 +#define SPI_FLASH_OPIDTR_DUMMY_BITLEN 40 +#define SPI_FLASH_QIO_HPM_DUMMY_BITLEN 10 +#define SPI_FLASH_DIO_HPM_DUMMY_BITLEN 8 diff --git a/components/esp_mspi/linker.lf b/components/esp_mspi/linker.lf new file mode 100644 index 00000000000..16796de9ea3 --- /dev/null +++ b/components/esp_mspi/linker.lf @@ -0,0 +1,38 @@ +[mapping:esp_mspi] +archive: libesp_mspi.a +entries: + if APP_BUILD_TYPE_PURE_RAM_APP = n: + flash_brownout_hook (noflash) + + if SPI_FLASH_PLACE_FUNCTIONS_IN_IRAM = y: + spi_flash_wrap (noflash) + + if ESPTOOLPY_OCT_FLASH = y || ESPTOOLPY_FLASH_MODE_AUTO_DETECT = y: + spi_flash_oct_flash_init (noflash) + + if SPI_FLASH_HPM_ON = y: + spi_flash_hpm_enable (noflash) + + if ESP_SLEEP_SET_FLASH_DPD = y: + spi_flash_dpd_enable (noflash) + flash_ops: dpd_enter_func (noflash) + flash_ops: dpd_exit_func (noflash) + + if SOC_GPIO_NEED_SOFT_ISOLATE_DURING_PD = y: + flash_ops: esp_mspi_get_io (noflash) + flash_ops: s_mspi_io_num_default (noflash) + +[mapping:mspi_timing_tuning_driver] +archive: libesp_mspi.a +entries: + if APP_BUILD_TYPE_PURE_RAM_APP = n: + mspi_timing_tuning (noflash) + if SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY = y: + mspi_timing_by_mspi_delay (noflash) + mspi_timing_config (noflash) + if SOC_MEMSPI_TIMING_TUNING_BY_DQS = y: + mspi_timing_by_dqs (noflash) + if SOC_MEMSPI_TIMING_TUNING_BY_FLASH_DELAY = y: + mspi_timing_by_flash_delay (noflash) + if SOC_MEMSPI_TIMING_TUNING_BY_DQS = y || SOC_MEMSPI_TIMING_TUNING_BY_FLASH_DELAY = y: + mspi_timing_config (noflash) diff --git a/components/spi_flash/linux/cache_utils.c b/components/esp_mspi/linux/cache_utils.c similarity index 67% rename from components/spi_flash/linux/cache_utils.c rename to components/esp_mspi/linux/cache_utils.c index 956b497bb31..a7b8fdffc72 100644 --- a/components/spi_flash/linux/cache_utils.c +++ b/components/esp_mspi/linux/cache_utils.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/esp_hw_support/mspi/mspi_intr/include/esp_private/mspi_intr.h b/components/esp_mspi/mspi_intr/include/esp_private/mspi_intr.h similarity index 100% rename from components/esp_hw_support/mspi/mspi_intr/include/esp_private/mspi_intr.h rename to components/esp_mspi/mspi_intr/include/esp_private/mspi_intr.h diff --git a/components/esp_hw_support/mspi/mspi_intr/mspi_intr.c b/components/esp_mspi/mspi_intr/mspi_intr.c similarity index 95% rename from components/esp_hw_support/mspi/mspi_intr/mspi_intr.c rename to components/esp_mspi/mspi_intr/mspi_intr.c index 94628d26323..a8b9169f339 100644 --- a/components/esp_hw_support/mspi/mspi_intr/mspi_intr.c +++ b/components/esp_mspi/mspi_intr/mspi_intr.c @@ -106,10 +106,10 @@ esp_err_t esp_mspi_register_isr(mspi_isr_t *isr) if (!s_intr_handle) { ret = esp_intr_alloc(mspi_hw_info.instances[MSPI_TIMING_LL_MSPI_ID_0].irq, - MSPI_ISR_FLAGS, - mspi_isr_handler, - NULL, - &s_intr_handle); + MSPI_ISR_FLAGS, + mspi_isr_handler, + NULL, + &s_intr_handle); ESP_RETURN_ON_ERROR(ret, TAG, "Failed to allocate MSPI flash interrupt"); diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/include/esp_private/mspi_timing_config.h b/components/esp_mspi/mspi_timing_tuning/include/esp_private/mspi_timing_config.h similarity index 100% rename from components/esp_hw_support/mspi/mspi_timing_tuning/include/esp_private/mspi_timing_config.h rename to components/esp_mspi/mspi_timing_tuning/include/esp_private/mspi_timing_config.h diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/include/esp_private/mspi_timing_tuning.h b/components/esp_mspi/mspi_timing_tuning/include/esp_private/mspi_timing_tuning.h similarity index 100% rename from components/esp_hw_support/mspi/mspi_timing_tuning/include/esp_private/mspi_timing_tuning.h rename to components/esp_mspi/mspi_timing_tuning/include/esp_private/mspi_timing_tuning.h diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/include/esp_private/mspi_timing_types.h b/components/esp_mspi/mspi_timing_tuning/include/esp_private/mspi_timing_types.h similarity index 100% rename from components/esp_hw_support/mspi/mspi_timing_tuning/include/esp_private/mspi_timing_types.h rename to components/esp_mspi/mspi_timing_tuning/include/esp_private/mspi_timing_types.h diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/mspi_timing_tuning.c b/components/esp_mspi/mspi_timing_tuning/mspi_timing_tuning.c similarity index 99% rename from components/esp_hw_support/mspi/mspi_timing_tuning/mspi_timing_tuning.c rename to components/esp_mspi/mspi_timing_tuning/mspi_timing_tuning.c index 6d2f9b9c502..9248aca57f0 100644 --- a/components/esp_hw_support/mspi/mspi_timing_tuning/mspi_timing_tuning.c +++ b/components/esp_mspi/mspi_timing_tuning/mspi_timing_tuning.c @@ -346,7 +346,6 @@ static void s_do_tuning(uint8_t *reference_data, mspi_timing_config_t *config, b } #endif //#if MSPI_TIMING_FLASH_NEEDS_TUNING || MSPI_TIMING_PSRAM_NEEDS_TUNING - /*------------------------------------------------------------------------------ * FLASH Timing Tuning *----------------------------------------------------------------------------*/ @@ -395,7 +394,6 @@ void mspi_timing_flash_tuning(void) } #endif //MSPI_TIMING_FLASH_NEEDS_TUNING - /*------------------------------------------------------------------------------ * PSRAM Timing Tuning *----------------------------------------------------------------------------*/ @@ -480,7 +478,6 @@ void mspi_timing_psram_tuning(void) } #endif //MSPI_TIMING_PSRAM_NEEDS_TUNING - /*------------------------------------------------------------------------------ * APIs to make SPI0 (and SPI1) FLASH work for high/low freq *----------------------------------------------------------------------------*/ @@ -621,7 +618,6 @@ void mspi_timing_change_speed_mode_cache_safe(bool switch_down) #endif } - /*------------------------------------------------------------------------------ * Early-init MSPI speed switch (see mspi_timing_tuning.h) *----------------------------------------------------------------------------*/ diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c5/CMakeLists.txt b/components/esp_mspi/mspi_timing_tuning/port/esp32c5/CMakeLists.txt similarity index 100% rename from components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c5/CMakeLists.txt rename to components/esp_mspi/mspi_timing_tuning/port/esp32c5/CMakeLists.txt diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c5/mspi_timing_config.c b/components/esp_mspi/mspi_timing_tuning/port/esp32c5/mspi_timing_config.c similarity index 100% rename from components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c5/mspi_timing_config.c rename to components/esp_mspi/mspi_timing_tuning/port/esp32c5/mspi_timing_config.c diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c5/mspi_timing_tuning_configs.h b/components/esp_mspi/mspi_timing_tuning/port/esp32c5/mspi_timing_tuning_configs.h similarity index 99% rename from components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c5/mspi_timing_tuning_configs.h rename to components/esp_mspi/mspi_timing_tuning/port/esp32c5/mspi_timing_tuning_configs.h index 83d584f24d6..4ee8d0f046e 100644 --- a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c5/mspi_timing_tuning_configs.h +++ b/components/esp_mspi/mspi_timing_tuning/port/esp32c5/mspi_timing_tuning_configs.h @@ -126,7 +126,6 @@ ESP_STATIC_ASSERT((MSPI_TIMING_CORE_CLOCK_MHZ == MSPI_TIMING_PSRAM_MODULE_CLOCK) #define MSPI_TIMING_FLASH_GET_TUNING_CONFIG(core_clock_mhz, module_clock_mhz, mode) _GET_TUNING_CONFIG(FLASH, core_clock_mhz, module_clock_mhz, mode) #define MSPI_TIMING_PSRAM_GET_TUNING_CONFIG(core_clock_mhz, module_clock_mhz, mode) _GET_TUNING_CONFIG(PSRAM, core_clock_mhz, module_clock_mhz, mode) - /** * Timing Tuning Parameters */ diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c61/CMakeLists.txt b/components/esp_mspi/mspi_timing_tuning/port/esp32c61/CMakeLists.txt similarity index 100% rename from components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c61/CMakeLists.txt rename to components/esp_mspi/mspi_timing_tuning/port/esp32c61/CMakeLists.txt diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c61/mspi_timing_config.c b/components/esp_mspi/mspi_timing_tuning/port/esp32c61/mspi_timing_config.c similarity index 100% rename from components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c61/mspi_timing_config.c rename to components/esp_mspi/mspi_timing_tuning/port/esp32c61/mspi_timing_config.c diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c61/mspi_timing_tuning_configs.h b/components/esp_mspi/mspi_timing_tuning/port/esp32c61/mspi_timing_tuning_configs.h similarity index 99% rename from components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c61/mspi_timing_tuning_configs.h rename to components/esp_mspi/mspi_timing_tuning/port/esp32c61/mspi_timing_tuning_configs.h index 0ab88f7ed7d..c03a0ee688c 100644 --- a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32c61/mspi_timing_tuning_configs.h +++ b/components/esp_mspi/mspi_timing_tuning/port/esp32c61/mspi_timing_tuning_configs.h @@ -113,7 +113,6 @@ ESP_STATIC_ASSERT((MSPI_TIMING_CORE_CLOCK_MHZ == MSPI_TIMING_FLASH_MODULE_CLOCK) ESP_STATIC_ASSERT((MSPI_TIMING_CORE_CLOCK_MHZ == MSPI_TIMING_PSRAM_MODULE_CLOCK) || (MSPI_TIMING_CORE_CLOCK_MHZ % (2 * MSPI_TIMING_PSRAM_MODULE_CLOCK) == 0), "PSRAM Mode configuration are not supported"); #endif - //------------------------------------------Helper Macros to get FLASH/PSRAM tuning configs-----------------------------------------------// #define __GET_TUNING_CONFIG(type, core_clock, module_clock, mode) \ (mspi_timing_config_t) { .tuning_config_table = MSPI_TIMING_##type##_CONFIG_TABLE_CORE_CLK_##core_clock##M_MODULE_CLK_##module_clock##M_##mode, \ @@ -125,7 +124,6 @@ ESP_STATIC_ASSERT((MSPI_TIMING_CORE_CLOCK_MHZ == MSPI_TIMING_PSRAM_MODULE_CLOCK) #define MSPI_TIMING_FLASH_GET_TUNING_CONFIG(core_clock_mhz, module_clock_mhz, mode) _GET_TUNING_CONFIG(FLASH, core_clock_mhz, module_clock_mhz, mode) #define MSPI_TIMING_PSRAM_GET_TUNING_CONFIG(core_clock_mhz, module_clock_mhz, mode) _GET_TUNING_CONFIG(PSRAM, core_clock_mhz, module_clock_mhz, mode) - /** * Timing Tuning Parameters */ diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32p4/CMakeLists.txt b/components/esp_mspi/mspi_timing_tuning/port/esp32p4/CMakeLists.txt similarity index 100% rename from components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32p4/CMakeLists.txt rename to components/esp_mspi/mspi_timing_tuning/port/esp32p4/CMakeLists.txt diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32p4/mspi_timing_config.c b/components/esp_mspi/mspi_timing_tuning/port/esp32p4/mspi_timing_config.c similarity index 96% rename from components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32p4/mspi_timing_config.c rename to components/esp_mspi/mspi_timing_tuning/port/esp32p4/mspi_timing_config.c index ae0c57789a8..eb52222dfac 100644 --- a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32p4/mspi_timing_config.c +++ b/components/esp_mspi/mspi_timing_tuning/port/esp32p4/mspi_timing_config.c @@ -27,7 +27,7 @@ void mspi_timing_config_set_psram_clock(uint32_t psram_freq_mhz, mspi_timing_spe assert(freqdiv > 0); ESP_DRAM_LOGD(TAG, "psram_freq_mhz: %" PRIu32 " mhz, bus clock div: %" PRIu32, psram_freq_mhz, freqdiv); PERIPH_RCC_ATOMIC() { - //MSPI2 and MSPI3 share the register for core clock. So we only set MSPI2 here. + //MSPI2 and MSPI3 share the register for core clock. So we only set MSPI2 here. psram_ctrlr_ll_enable_core_clock(PSRAM_CTRLR_LL_MSPI_ID_2, true); psram_ctrlr_ll_set_core_clock_div(PSRAM_CTRLR_LL_MSPI_ID_2, MSPI_TIMING_CORE_CLOCK_DIV); psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_3, freqdiv); diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32p4/mspi_timing_tuning_configs.h b/components/esp_mspi/mspi_timing_tuning/port/esp32p4/mspi_timing_tuning_configs.h similarity index 100% rename from components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32p4/mspi_timing_tuning_configs.h rename to components/esp_mspi/mspi_timing_tuning/port/esp32p4/mspi_timing_tuning_configs.h diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s3/CMakeLists.txt b/components/esp_mspi/mspi_timing_tuning/port/esp32s3/CMakeLists.txt similarity index 100% rename from components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s3/CMakeLists.txt rename to components/esp_mspi/mspi_timing_tuning/port/esp32s3/CMakeLists.txt diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_by_mspi_delay.c b/components/esp_mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_by_mspi_delay.c similarity index 93% rename from components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_by_mspi_delay.c rename to components/esp_mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_by_mspi_delay.c index 08a32b6cfe7..c1a3871c944 100644 --- a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_by_mspi_delay.c +++ b/components/esp_mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_by_mspi_delay.c @@ -23,7 +23,7 @@ #include "hal/clk_tree_ll.h" #include "esp_private/mspi_timing_config.h" #include "esp_private/mspi_timing_by_mspi_delay.h" -#include "bootloader_flash.h" +#include "esp_private/spi_flash_os.h" #include "esp32s3/rom/spi_flash.h" #include "esp32s3/rom/opi_flash.h" #if CONFIG_SPIRAM_TIMING_TUNING_POINT_VIA_TEMPERATURE_SENSOR @@ -116,46 +116,47 @@ static uint32_t spi_timing_config_get_dummy(void) if (spi_flash_hpm_dummy_adjust()) { // HPM-DC is enabled const spi_flash_hpm_dummy_conf_t *hpm_dummy = spi_flash_hpm_get_dummy(); switch (mode) { - case MSPI_TIMING_LL_FLASH_QIO_MODE: - return hpm_dummy->qio_dummy - 1; - case MSPI_TIMING_LL_FLASH_QUAD_MODE: - return hpm_dummy->qout_dummy - 1; - case MSPI_TIMING_LL_FLASH_DIO_MODE: - return hpm_dummy->dio_dummy - 1; - case MSPI_TIMING_LL_FLASH_DUAL_MODE: - return hpm_dummy->dout_dummy - 1; - case MSPI_TIMING_LL_FLASH_FAST_MODE: - return hpm_dummy->fastrd_dummy - 1; - case MSPI_TIMING_LL_FLASH_SLOW_MODE: - return 0; - default: - abort(); + case MSPI_TIMING_LL_FLASH_QIO_MODE: + return hpm_dummy->qio_dummy - 1; + case MSPI_TIMING_LL_FLASH_QUAD_MODE: + return hpm_dummy->qout_dummy - 1; + case MSPI_TIMING_LL_FLASH_DIO_MODE: + return hpm_dummy->dio_dummy - 1; + case MSPI_TIMING_LL_FLASH_DUAL_MODE: + return hpm_dummy->dout_dummy - 1; + case MSPI_TIMING_LL_FLASH_FAST_MODE: + return hpm_dummy->fastrd_dummy - 1; + case MSPI_TIMING_LL_FLASH_SLOW_MODE: + return 0; + default: + abort(); } } else #endif - { // HPM-DC is not enabled + { + // HPM-DC is not enabled switch (mode) { - case MSPI_TIMING_LL_FLASH_QIO_MODE: - return SPI1_R_QIO_DUMMY_CYCLELEN; - case MSPI_TIMING_LL_FLASH_QUAD_MODE: - return SPI1_R_FAST_DUMMY_CYCLELEN; - case MSPI_TIMING_LL_FLASH_DIO_MODE: - return SPI1_R_DIO_DUMMY_CYCLELEN; - case MSPI_TIMING_LL_FLASH_DUAL_MODE: - return SPI1_R_FAST_DUMMY_CYCLELEN; - case MSPI_TIMING_LL_FLASH_FAST_MODE: - return SPI1_R_FAST_DUMMY_CYCLELEN; - case MSPI_TIMING_LL_FLASH_SLOW_MODE: - return 0; - default: - abort(); + case MSPI_TIMING_LL_FLASH_QIO_MODE: + return SPI1_R_QIO_DUMMY_CYCLELEN; + case MSPI_TIMING_LL_FLASH_QUAD_MODE: + return SPI1_R_FAST_DUMMY_CYCLELEN; + case MSPI_TIMING_LL_FLASH_DIO_MODE: + return SPI1_R_DIO_DUMMY_CYCLELEN; + case MSPI_TIMING_LL_FLASH_DUAL_MODE: + return SPI1_R_FAST_DUMMY_CYCLELEN; + case MSPI_TIMING_LL_FLASH_FAST_MODE: + return SPI1_R_FAST_DUMMY_CYCLELEN; + case MSPI_TIMING_LL_FLASH_SLOW_MODE: + return 0; + default: + abort(); } } } static void s_set_flash_extra_dummy(uint8_t spi_num, uint8_t extra_dummy) { - if (bootloader_flash_is_octal_mode_enabled()) { + if (spi_flash_is_octal_mode_enabled()) { mspi_timing_ll_set_octal_flash_extra_dummy(spi_num, extra_dummy); return; } @@ -190,7 +191,7 @@ void mspi_timing_config_flash_set_tuning_regs(const void *configs, uint8_t id) //-------------------------------------------FLASH Read/Write------------------------------------------// void mspi_timing_config_flash_read_data(uint8_t *buf, uint32_t addr, uint32_t len) { - if (bootloader_flash_is_octal_mode_enabled()) { + if (spi_flash_is_octal_mode_enabled()) { // note that in spi_flash_read API, there is a wait-idle stage, since flash can only be read in idle state. // but after we change the timing settings, we might not read correct idle status via RDSR. // so, here we should use a read API that won't check idle status. @@ -270,13 +271,13 @@ static void s_psram_write_data(uint8_t *buf, uint32_t addr, uint32_t len) { #if CONFIG_SPIRAM_MODE_OCT esp_rom_opiflash_exec_cmd(1, ESP_ROM_SPIFLASH_OPI_DTR_MODE, - OPI_PSRAM_SYNC_WRITE, 16, - addr, 32, - OCT_PSRAM_WR_DUMMY_NUM, - buf, len * 8, - NULL, 0, - BIT(1), - false); + OPI_PSRAM_SYNC_WRITE, 16, + addr, 32, + OCT_PSRAM_WR_DUMMY_NUM, + buf, len * 8, + NULL, 0, + BIT(1), + false); #elif CONFIG_SPIRAM_MODE_QUAD psram_exec_cmd(1, 0, QPI_PSRAM_WRITE, 8, @@ -294,13 +295,13 @@ static void s_psram_read_data(uint8_t *buf, uint32_t addr, uint32_t len) #if CONFIG_SPIRAM_MODE_OCT mspi_timing_ll_clear_fifo(1); esp_rom_opiflash_exec_cmd(1, ESP_ROM_SPIFLASH_OPI_DTR_MODE, - OPI_PSRAM_SYNC_READ, 16, - addr, 32, - OCT_PSRAM_RD_DUMMY_NUM, - NULL, 0, - buf, len * 8, - BIT(1), - false); + OPI_PSRAM_SYNC_READ, 16, + addr, 32, + OCT_PSRAM_RD_DUMMY_NUM, + NULL, 0, + buf, len * 8, + BIT(1), + false); #elif CONFIG_SPIRAM_MODE_QUAD psram_exec_cmd(1, 0, QPI_PSRAM_FAST_READ, 8, @@ -331,7 +332,7 @@ static void s_psram_execution(uint8_t *buf, uint32_t addr, uint32_t len, bool is void mspi_timing_config_psram_prepare_reference_data(uint8_t *buf, uint32_t len) { assert((len == MSPI_TIMING_TEST_DATA_LEN) && (len % 4 == 0)); - for (int i=0; i < len/4; i++) { + for (int i = 0; i < len / 4; i++) { ((uint32_t *)buf)[i] = 0xa5ff005a; } } @@ -371,7 +372,7 @@ static bool get_working_pll_freq(const uint8_t *reference_data, bool is_flash, u clk_ll_bbpll_set_frequency_for_mspi_tuning(xtal_freq, pll_mhz_tuning, ((pll_mhz_tuning / 4) - 4), 9); //wait calibration done - while(!clk_ll_bbpll_calibration_is_done()); + while (!clk_ll_bbpll_calibration_is_done()); //bbpll calibration stop clk_ll_bbpll_calibration_stop(); @@ -406,7 +407,7 @@ static bool get_working_pll_freq(const uint8_t *reference_data, bool is_flash, u //set pll clk_ll_bbpll_set_config(previous_config.source_freq_mhz, xtal_freq); //wait calibration done - while(!clk_ll_bbpll_calibration_is_done()); + while (!clk_ll_bbpll_calibration_is_done()); //bbpll calibration stop clk_ll_bbpll_calibration_stop(); @@ -535,7 +536,7 @@ static uint32_t s_select_best_tuning_config_str(const mspi_timing_config_t *conf //STR best point scheme uint32_t best_point; - if (consecutive_length <= 2|| consecutive_length >= 5) { + if (consecutive_length <= 2 || consecutive_length >= 5) { //tuning is FAIL, select default point, and generate a warning best_point = configs->default_config_id; ESP_DRAM_LOGW(TAG, "tuning fail, best point is fallen back to index %"PRIu32"", best_point); @@ -595,7 +596,6 @@ void mspi_timing_psram_set_best_tuning_config(const void *configs, uint8_t best_ s_psram_best_timing_tuning_config = ((const mspi_timing_config_t *)configs)->tuning_config_table[best_id]; } - /*------------------------------------------------------------------------------------------------- * Best Timing Tuning Params Clear / Set *-------------------------------------------------------------------------------------------------*/ @@ -637,7 +637,6 @@ void mspi_timing_psram_config_set_tuning_regs(bool control_both_mspi) } #endif //#if MSPI_TIMING_FLASH_NEEDS_TUNING || MSPI_TIMING_PSRAM_NEEDS_TUNING - /*------------------------------------------------------------------------------------------------- * To let upper lay (spi_flash_timing_tuning.c) to know the necessary timing registers *-------------------------------------------------------------------------------------------------*/ @@ -730,8 +729,12 @@ static esp_err_t temperature_sensor_get_celsius_filtered(int16_t *temp_filtered) for (uint8_t idx = 0; idx < filter_window_len; idx++) { temp_arr[idx] = temp_sensor_get_raw_value(NULL); // record the index of the max and min temperature value - if (temp_arr[idx] > temp_arr[temp_max_idx]) temp_max_idx = idx; - if (temp_arr[idx] < temp_arr[temp_min_idx]) temp_min_idx = idx; + if (temp_arr[idx] > temp_arr[temp_max_idx]) { + temp_max_idx = idx; + } + if (temp_arr[idx] < temp_arr[temp_min_idx]) { + temp_min_idx = idx; + } temp_sum += temp_arr[idx]; } // remove the max and min temperature value diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_config.c b/components/esp_mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_config.c similarity index 100% rename from components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_config.c rename to components/esp_mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_config.c diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_tuning_configs.h b/components/esp_mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_tuning_configs.h similarity index 99% rename from components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_tuning_configs.h rename to components/esp_mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_tuning_configs.h index 3631b1e1b09..783042c1812 100644 --- a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_tuning_configs.h +++ b/components/esp_mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_tuning_configs.h @@ -83,7 +83,6 @@ extern "C" { #define MSPI_TIMING_PSRAM_NEEDS_TUNING (MSPI_TIMING_PSRAM_MODULE_CLOCK > 80) #endif - /** * @note Define A feasible core clock below: MSPI_TIMING_FLASH_EXPECTED_CORE_CLK_MHZ and MSPI_TIMING_PSRAM_EXPECTED_CORE_CLK_MHZ */ @@ -138,7 +137,6 @@ extern "C" { #define MSPI_TIMING_PSRAM_EXPECTED_CORE_CLK_MHZ 240 #endif //PSRAM 120M DTR - //------------------------------------------Determine the Core Clock-----------------------------------------------// /** * @note @@ -177,7 +175,6 @@ ESP_STATIC_ASSERT(CHECK_POWER_OF_2(MSPI_TIMING_CORE_CLOCK_MHZ / MSPI_TIMING_FLAS ESP_STATIC_ASSERT(CHECK_POWER_OF_2(MSPI_TIMING_CORE_CLOCK_MHZ / MSPI_TIMING_PSRAM_MODULE_CLOCK), "FLASH and PSRAM Mode configuration are not supported"); #endif - //------------------------------------------Helper Macros to get FLASH/PSRAM tuning configs-----------------------------------------------// #define __GET_TUNING_CONFIG(type, core_clock, module_clock, mode) \ (mspi_timing_config_t) { .tuning_config_table = MSPI_TIMING_##type##_CONFIG_TABLE_CORE_CLK_##core_clock##M_MODULE_CLK_##module_clock##M_##mode, \ @@ -189,8 +186,6 @@ ESP_STATIC_ASSERT(CHECK_POWER_OF_2(MSPI_TIMING_CORE_CLOCK_MHZ / MSPI_TIMING_PSRA #define MSPI_TIMING_FLASH_GET_TUNING_CONFIG(core_clock_mhz, module_clock_mhz, mode) _GET_TUNING_CONFIG(FLASH, core_clock_mhz, module_clock_mhz, mode) #define MSPI_TIMING_PSRAM_GET_TUNING_CONFIG(core_clock_mhz, module_clock_mhz, mode) _GET_TUNING_CONFIG(PSRAM, core_clock_mhz, module_clock_mhz, mode) - - /** * Timing Tuning Parameters */ @@ -244,7 +239,6 @@ ESP_STATIC_ASSERT(CHECK_POWER_OF_2(MSPI_TIMING_CORE_CLOCK_MHZ / MSPI_TIMING_PSRA #define MSPI_TIMING_PSRAM_CONFIG_NUM_CORE_CLK_120M_MODULE_CLK_120M_STR_MODE 12 #define MSPI_TIMING_PSRAM_DEFAULT_CONFIG_ID_CORE_CLK_120M_MODULE_CLK_120M_STR_MODE 2 - //PSRAM: core clock 240M, module clock 120M, DTR mode #define MSPI_TIMING_PSRAM_CONFIG_TABLE_CORE_CLK_240M_MODULE_CLK_120M_DTR_MODE {{0, 0, 0}, {4, 1, 2}, {1, 0, 1}, {4, 0, 2}, {0, 0, 1}, {4, 1, 3}, {1, 0, 2}, {4, 0, 3}, {0, 0, 2}, {4, 1, 4}, {1, 0, 3}, {4, 0, 4}, {0, 0, 3}, {4, 1, 5}} #define MSPI_TIMING_PSRAM_CONFIG_NUM_CORE_CLK_240M_MODULE_CLK_120M_DTR_MODE 14 diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s31/CMakeLists.txt b/components/esp_mspi/mspi_timing_tuning/port/esp32s31/CMakeLists.txt similarity index 100% rename from components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s31/CMakeLists.txt rename to components/esp_mspi/mspi_timing_tuning/port/esp32s31/CMakeLists.txt diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s31/mspi_timing_config.c b/components/esp_mspi/mspi_timing_tuning/port/esp32s31/mspi_timing_config.c similarity index 96% rename from components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s31/mspi_timing_config.c rename to components/esp_mspi/mspi_timing_tuning/port/esp32s31/mspi_timing_config.c index 8d322f8705f..aee52e50cad 100644 --- a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s31/mspi_timing_config.c +++ b/components/esp_mspi/mspi_timing_tuning/port/esp32s31/mspi_timing_config.c @@ -27,7 +27,7 @@ void mspi_timing_config_set_psram_clock(uint32_t psram_freq_mhz, mspi_timing_spe assert(freqdiv > 0); ESP_DRAM_LOGD(TAG, "psram_freq_mhz: %" PRIu32 " mhz, bus clock div: %" PRIu32, psram_freq_mhz, freqdiv); PERIPH_RCC_ATOMIC() { - //MSPI2 and MSPI3 share the register for core clock. So we only set MSPI2 here. + //MSPI2 and MSPI3 share the register for core clock. So we only set MSPI2 here. psram_ctrlr_ll_enable_core_clock(PSRAM_CTRLR_LL_MSPI_ID_2, true); psram_ctrlr_ll_set_core_clock_div(PSRAM_CTRLR_LL_MSPI_ID_2, MSPI_TIMING_CORE_CLOCK_DIV); psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_3, freqdiv); diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s31/mspi_timing_tuning_configs.h b/components/esp_mspi/mspi_timing_tuning/port/esp32s31/mspi_timing_tuning_configs.h similarity index 100% rename from components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s31/mspi_timing_tuning_configs.h rename to components/esp_mspi/mspi_timing_tuning/port/esp32s31/mspi_timing_tuning_configs.h diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_dqs.h b/components/esp_mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_dqs.h similarity index 99% rename from components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_dqs.h rename to components/esp_mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_dqs.h index da104226e33..2107ae331a6 100644 --- a/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_dqs.h +++ b/components/esp_mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_dqs.h @@ -28,7 +28,6 @@ extern "C" { #define IS_DDR 1 #define IS_SDR (!IS_DDR) - /*------------------------------------------------------------------------------------------------- * Timing Required APIs *-------------------------------------------------------------------------------------------------*/ diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_flash_delay.h b/components/esp_mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_flash_delay.h similarity index 99% rename from components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_flash_delay.h rename to components/esp_mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_flash_delay.h index e8ea3d9f97b..0e0dc32e147 100644 --- a/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_flash_delay.h +++ b/components/esp_mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_flash_delay.h @@ -22,7 +22,6 @@ extern "C" { #endif - #if SOC_MEMSPI_TIMING_TUNING_BY_FLASH_DELAY #define IS_DDR 1 @@ -147,7 +146,6 @@ uint32_t mspi_timing_config_get_flash_fdummy_rin(void); #endif //#if SOC_MEMSPI_TIMING_TUNING_BY_FLASH_DELAY - #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_mspi_delay.h b/components/esp_mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_mspi_delay.h similarity index 99% rename from components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_mspi_delay.h rename to components/esp_mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_mspi_delay.h index 938266924e7..defd356fe80 100644 --- a/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_mspi_delay.h +++ b/components/esp_mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_mspi_delay.h @@ -28,7 +28,6 @@ extern "C" { #define IS_DDR 1 #define IS_SDR (!IS_DDR) - #if MSPI_TIMING_FLASH_NEEDS_TUNING || MSPI_TIMING_PSRAM_NEEDS_TUNING /*------------------------------------------------------------------------------------------------- * Timing Required APIs @@ -109,7 +108,6 @@ void mspi_timing_config_psram_write_data(uint8_t *buf, uint32_t addr, uint32_t l */ void mspi_timing_config_psram_read_data(uint8_t *buf, uint32_t addr, uint32_t len); - /*------------------------------------------------------------------------------------------------- * Best Timing Tuning Params Selection *-------------------------------------------------------------------------------------------------*/ @@ -157,7 +155,6 @@ uint32_t mspi_timing_psram_select_best_tuning_config(const void *configs, uint32 */ void mspi_timing_psram_set_best_tuning_config(const void *configs, uint8_t best_id); - /*------------------------------------------------------------------------------------------------- * Best Timing Tuning Params Clear / Set *-------------------------------------------------------------------------------------------------*/ @@ -197,7 +194,6 @@ void mspi_timing_psram_config_clear_tuning_regs(bool control_both_mspi); */ void mspi_timing_psram_config_set_tuning_regs(bool control_both_mspi); - /*------------------------------------------------------------------------------------------------- * APIs for coordination with ESP Flash driver *-------------------------------------------------------------------------------------------------*/ diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_impl_types.h b/components/esp_mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_impl_types.h similarity index 99% rename from components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_impl_types.h rename to components/esp_mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_impl_types.h index 1c23f0bea6e..707b0fec400 100644 --- a/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_impl_types.h +++ b/components/esp_mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_impl_types.h @@ -58,7 +58,6 @@ typedef struct { } mspi_timing_config_t; #endif //#if SOC_MEMSPI_TIMING_TUNING_BY_DQS || SOC_MEMSPI_TIMING_TUNING_BY_FLASH_DELAY - #if SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY /** * MSPI timing tuning registers. diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c b/components/esp_mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c similarity index 100% rename from components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c rename to components/esp_mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_flash_delay.c b/components/esp_mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_flash_delay.c similarity index 89% rename from components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_flash_delay.c rename to components/esp_mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_flash_delay.c index 57f540b07af..290551fe0e7 100644 --- a/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_flash_delay.c +++ b/components/esp_mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_flash_delay.c @@ -161,37 +161,37 @@ static uint32_t spi_timing_config_get_dummy(void) if (spi_flash_hpm_dummy_adjust()) { // HPM-DC is enabled const spi_flash_hpm_dummy_conf_t *hpm_dummy = spi_flash_hpm_get_dummy(); switch (mode) { - case MSPI_TIMING_LL_FLASH_QIO_MODE: - return hpm_dummy->qio_dummy - 1; - case MSPI_TIMING_LL_FLASH_QUAD_MODE: - return hpm_dummy->qout_dummy - 1; - case MSPI_TIMING_LL_FLASH_DIO_MODE: - return hpm_dummy->dio_dummy - 1; - case MSPI_TIMING_LL_FLASH_DUAL_MODE: - return hpm_dummy->dout_dummy - 1; - case MSPI_TIMING_LL_FLASH_FAST_MODE: - return hpm_dummy->fastrd_dummy - 1; - case MSPI_TIMING_LL_FLASH_SLOW_MODE: - return 0; - default: - abort(); + case MSPI_TIMING_LL_FLASH_QIO_MODE: + return hpm_dummy->qio_dummy - 1; + case MSPI_TIMING_LL_FLASH_QUAD_MODE: + return hpm_dummy->qout_dummy - 1; + case MSPI_TIMING_LL_FLASH_DIO_MODE: + return hpm_dummy->dio_dummy - 1; + case MSPI_TIMING_LL_FLASH_DUAL_MODE: + return hpm_dummy->dout_dummy - 1; + case MSPI_TIMING_LL_FLASH_FAST_MODE: + return hpm_dummy->fastrd_dummy - 1; + case MSPI_TIMING_LL_FLASH_SLOW_MODE: + return 0; + default: + abort(); } } else { // HPM-DC is not enabled switch (mode) { - case MSPI_TIMING_LL_FLASH_QIO_MODE: - return SPI1_R_QIO_DUMMY_CYCLELEN; - case MSPI_TIMING_LL_FLASH_QUAD_MODE: - return SPI1_R_FAST_DUMMY_CYCLELEN; - case MSPI_TIMING_LL_FLASH_DIO_MODE: - return SPI1_R_DIO_DUMMY_CYCLELEN; - case MSPI_TIMING_LL_FLASH_DUAL_MODE: - return SPI1_R_FAST_DUMMY_CYCLELEN; - case MSPI_TIMING_LL_FLASH_FAST_MODE: - return SPI1_R_FAST_DUMMY_CYCLELEN; - case MSPI_TIMING_LL_FLASH_SLOW_MODE: - return 0; - default: - abort(); + case MSPI_TIMING_LL_FLASH_QIO_MODE: + return SPI1_R_QIO_DUMMY_CYCLELEN; + case MSPI_TIMING_LL_FLASH_QUAD_MODE: + return SPI1_R_FAST_DUMMY_CYCLELEN; + case MSPI_TIMING_LL_FLASH_DIO_MODE: + return SPI1_R_DIO_DUMMY_CYCLELEN; + case MSPI_TIMING_LL_FLASH_DUAL_MODE: + return SPI1_R_FAST_DUMMY_CYCLELEN; + case MSPI_TIMING_LL_FLASH_FAST_MODE: + return SPI1_R_FAST_DUMMY_CYCLELEN; + case MSPI_TIMING_LL_FLASH_SLOW_MODE: + return 0; + default: + abort(); } } } diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c b/components/esp_mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c similarity index 92% rename from components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c rename to components/esp_mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c index b1ba7201771..3606933dcb3 100644 --- a/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c +++ b/components/esp_mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c @@ -24,8 +24,8 @@ #include "hal/psram_ctrlr_ll.h" #include "esp_private/mspi_timing_config.h" #include "esp_private/mspi_timing_by_mspi_delay.h" +#include "esp_private/spi_flash_os.h" #include "mspi_timing_tuning_configs.h" -#include "bootloader_flash.h" #define QPI_PSRAM_FAST_READ 0XEB #define QPI_PSRAM_WRITE 0X38 @@ -90,7 +90,7 @@ void mspi_timing_config_flash_read_data(uint8_t *buf, uint32_t addr, uint32_t le #if CONFIG_ESPTOOLPY_FLASHMODE_QIO && CONFIG_SPI_FLASH_HPM_ON g_rom_spiflash_dummy_len_plus[1] = 4; #endif - if (bootloader_flash_is_octal_mode_enabled()) { + if (spi_flash_is_octal_mode_enabled()) { // note that in spi_flash_read API, there is a wait-idle stage, since flash can only be read in idle state. // but after we change the timing settings, we might not read correct idle status via RDSR. // so, here we should use a read API that won't check idle status. @@ -156,13 +156,13 @@ void mspi_timing_config_psram_set_tuning_regs(const void *configs, uint8_t id) //-------------------------------------------PSRAM Read/Write------------------------------------------// static void psram_exec_cmd(int mspi_id, psram_cmd_mode_t mode, - uint32_t cmd, int cmd_bit_len, - uint32_t addr, int addr_bit_len, - int dummy_bits, - uint8_t* mosi_data, int mosi_bit_len, - uint8_t* miso_data, int miso_bit_len, - uint32_t cs_mask, - bool is_write_erase_operation) + uint32_t cmd, int cmd_bit_len, + uint32_t addr, int addr_bit_len, + int dummy_bits, + uint8_t* mosi_data, int mosi_bit_len, + uint8_t* miso_data, int miso_bit_len, + uint32_t cs_mask, + bool is_write_erase_operation) { esp_rom_spiflash_read_mode_t rd_mode = (mode == PSRAM_HAL_CMD_QPI) ? ESP_ROM_SPIFLASH_QIO_MODE : ESP_ROM_SPIFLASH_SLOWRD_MODE; @@ -194,15 +194,15 @@ static void s_psram_write_data(uint8_t *buf, uint32_t addr, uint32_t len) uint8_t dummy_len = 0; uint8_t addr_len = 24; psram_cmd_mode_t spi_mode = PSRAM_HAL_CMD_QPI; - for (uint32_t idx= 0; idx < len / FIFO_SIZE_BYTE; idx++) { + for (uint32_t idx = 0; idx < len / FIFO_SIZE_BYTE; idx++) { psram_exec_cmd(mspi_id, spi_mode, - cmd, cmd_len, - addr + idx * FIFO_SIZE_BYTE, addr_len, - dummy_len, - buf + idx * FIFO_SIZE_BYTE, FIFO_SIZE_BYTE * 8, - NULL, 0, - PSRAM_LL_CS_SEL, - false); + cmd, cmd_len, + addr + idx * FIFO_SIZE_BYTE, addr_len, + dummy_len, + buf + idx * FIFO_SIZE_BYTE, FIFO_SIZE_BYTE * 8, + NULL, 0, + PSRAM_LL_CS_SEL, + false); } } @@ -219,15 +219,15 @@ static void s_psram_read_data(uint8_t *buf, uint32_t addr, uint32_t len) uint8_t dummy_len = QPI_PSRAM_FAST_READ_DUMMY; uint8_t addr_len = 24; psram_cmd_mode_t spi_mode = PSRAM_HAL_CMD_QPI; - for (uint32_t idx = 0; idx < len/FIFO_SIZE_BYTE; idx++) { + for (uint32_t idx = 0; idx < len / FIFO_SIZE_BYTE; idx++) { psram_exec_cmd(mspi_id, spi_mode, - cmd, cmd_len, - addr + idx*FIFO_SIZE_BYTE, addr_len, - dummy_len, - NULL, 0, - buf + idx*FIFO_SIZE_BYTE, FIFO_SIZE_BYTE * 8, - PSRAM_LL_CS_SEL, - false); + cmd, cmd_len, + addr + idx * FIFO_SIZE_BYTE, addr_len, + dummy_len, + NULL, 0, + buf + idx * FIFO_SIZE_BYTE, FIFO_SIZE_BYTE * 8, + PSRAM_LL_CS_SEL, + false); } } diff --git a/components/spi_flash/sdkconfig.rename b/components/esp_mspi/sdkconfig.rename similarity index 100% rename from components/spi_flash/sdkconfig.rename rename to components/esp_mspi/sdkconfig.rename diff --git a/components/spi_flash/spi_flash_dpd_enable.c b/components/esp_mspi/spi_flash_dpd_enable.c similarity index 78% rename from components/spi_flash/spi_flash_dpd_enable.c rename to components/esp_mspi/spi_flash_dpd_enable.c index d4448fe6e2b..dc1106ce6e0 100644 --- a/components/spi_flash/spi_flash_dpd_enable.c +++ b/components/esp_mspi/spi_flash_dpd_enable.c @@ -9,9 +9,9 @@ #include "esp_err.h" #include "esp_log.h" #include "esp_attr.h" - +#include "esp_rom_sys.h" #include "hal/spi_flash_hal.h" -#include "esp_flash_chips/spi_flash_chip_generic.h" +#include "esp_private/spi_flash_os.h" /******************************************************************************* * Flash deep power-down mode. @@ -46,6 +46,20 @@ __attribute__((unused)) const static char *DPD_TAG = "flash DPD"; * TODO: PM-623 */ +static spi_flash_dpd_funcs_t s_dpd_funcs = { + .enter_dpd = NULL, + .exit_dpd = NULL, +}; + +esp_err_t spi_flash_dpd_register_funcs(spi_flash_dpd_funcs_t *dpd_funcs) +{ + if (dpd_funcs == NULL) { + return ESP_ERR_INVALID_ARG; + } + s_dpd_funcs = *dpd_funcs; + return ESP_OK; +} + uint32_t spi_flash_dpd_get_enter_duration(void) { #ifndef CONFIG_ESP_SLEEP_SPI_FLASH_ENTER_DPD_MODE_DELAY @@ -64,7 +78,11 @@ uint32_t spi_flash_dpd_get_exit_duration(void) static esp_err_t spi_flash_enter_dpd(bool wait_delay) { - esp_err_t ret = spi_flash_hal_enter_dpd_mode(esp_flash_default_chip->host); + if (s_dpd_funcs.enter_dpd == NULL) { + ESP_EARLY_LOGE(DPD_TAG, "DPD enter function not registered"); + return ESP_ERR_INVALID_STATE; + } + esp_err_t ret = s_dpd_funcs.enter_dpd(); if (wait_delay) { esp_rom_delay_us(spi_flash_dpd_get_enter_duration()); } @@ -74,7 +92,11 @@ static esp_err_t spi_flash_enter_dpd(bool wait_delay) static esp_err_t spi_flash_exit_dpd(bool wait_delay) { - esp_err_t ret = spi_flash_hal_exit_dpd_mode(esp_flash_default_chip->host); + if (s_dpd_funcs.exit_dpd == NULL) { + ESP_EARLY_LOGE(DPD_TAG, "DPD exit function not registered"); + return ESP_ERR_INVALID_STATE; + } + esp_err_t ret = s_dpd_funcs.exit_dpd(); if (wait_delay) { esp_rom_delay_us(spi_flash_dpd_get_exit_duration()); } diff --git a/components/spi_flash/spi_flash_hpm_enable.c b/components/esp_mspi/spi_flash_hpm_enable.c similarity index 97% rename from components/spi_flash/spi_flash_hpm_enable.c rename to components/esp_mspi/spi_flash_hpm_enable.c index 6b303b0d014..071661a04db 100644 --- a/components/spi_flash/spi_flash_hpm_enable.c +++ b/components/esp_mspi/spi_flash_hpm_enable.c @@ -10,13 +10,14 @@ #include "esp_log.h" #include "esp_rom_sys.h" #include "esp_rom_spiflash.h" - -#include "esp_flash_chips/spi_flash_defs.h" +#include "spi_flash_defs.h" #include "esp_flash_chips/spi_flash_override.h" // TODO: These dependencies will be removed after remove bootloader_flash to G0.IDF-4609 #include "bootloader_flash_override.h" -#include "bootloader_flash_priv.h" +#include "esp_private/bootloader_flash_internal.h" + +#define CMD_HPMEN 0xA3 /* Enable High Performance mode on flash */ /******************************************************************************* * Flash high speed performance mode. @@ -38,7 +39,7 @@ * It mean that the flash not running under frequency requires HPM. spi_flash_enable_high_performance_mode() still * called because caller shouldn't take care of the frequency. * - * - bootloader_flash_is_octal_mode_enabled() == true: + * - spi_flash_is_octal_mode_enabled() == true: * This is possible when `CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT` selected * * Octal Flash for now all support 120M. No need to enable HPM. The file is compiled, but will not actually run @@ -127,7 +128,7 @@ static void spi_flash_enable_high_performance_send_cmd(void) */ static esp_err_t spi_flash_high_performance_check_hpf_bit_5(void) { - if((bootloader_read_status_8b_rdsr3() & (1 << 4)) == 0) { + if ((bootloader_read_status_8b_rdsr3() & (1 << 4)) == 0) { return ESP_FAIL; } return ESP_OK; @@ -208,7 +209,7 @@ static void spi_flash_turn_high_performance_reconfig_dummy(void) */ static esp_err_t spi_flash_high_performance_check_dummy_sr(void) { - if((bootloader_read_status_8b_rdsr3() & 0x03) == 0) { + if ((bootloader_read_status_8b_rdsr3() & 0x03) == 0) { return ESP_FAIL; } return ESP_OK; @@ -223,7 +224,6 @@ static void spi_flash_hpm_get_dummy_xmc(spi_flash_hpm_dummy_conf_t *dummy_conf) dummy_conf->fastrd_dummy = SPI_FLASH_FASTRD_DUMMY_BITLEN; } - /** * @brief Probe the chip whether adjust dummy (bit3,4) to enable HPM mode. Take XMC as an example: * Adjust dummy bits to enable HPM mode of the flash. If XMC works under 80MHz, the dummy bits @@ -281,7 +281,7 @@ static void spi_flash_turn_high_performance_dummy_bit3_4(void) */ static esp_err_t spi_flash_high_performance_check_dummy_bit3_4(void) { - if((bootloader_read_status_8b_rdsr3() & 0x18) == 0) { + if ((bootloader_read_status_8b_rdsr3() & 0x18) == 0) { return ESP_FAIL; } return ESP_OK; diff --git a/components/esp_mspi/spi_flash_os_tee_stub.c b/components/esp_mspi/spi_flash_os_tee_stub.c new file mode 100644 index 00000000000..c41279fefd4 --- /dev/null +++ b/components/esp_mspi/spi_flash_os_tee_stub.c @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + * + * Stub for spi_flash_is_octal_mode_enabled() when building for non-OS contexts + * (bootloader, TEE, PURE_RAM_APP). Full flash_ops.c is not built there, but + * esp_hw_support may still reference this symbol; returning false is safe. + */ + +#include + +bool spi_flash_is_octal_mode_enabled(void) +{ + return false; +} diff --git a/components/spi_flash/spi_flash_wrap.c b/components/esp_mspi/spi_flash_wrap.c similarity index 94% rename from components/spi_flash/spi_flash_wrap.c rename to components/esp_mspi/spi_flash_wrap.c index edf32e609f5..34292a8d614 100644 --- a/components/spi_flash/spi_flash_wrap.c +++ b/components/esp_mspi/spi_flash_wrap.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,13 +13,15 @@ #include "esp_rom_spiflash.h" #include "rom/spi_flash.h" -#include "esp_flash_chips/spi_flash_defs.h" #include "esp_flash_chips/spi_flash_override.h" #include "esp_private/spi_flash_os.h" // TODO: These dependencies will be removed after remove bootloader_flash to G0.IDF-4609 #include "bootloader_flash_override.h" -#include "bootloader_flash_priv.h" +#include "esp_private/bootloader_flash_internal.h" + +#define CMD_WRAP 0x77 +#define CMD_BURST_RD 0xC0 /*********************************************************************************** * Flash wrap feature (also called burst read on some flash chips) @@ -69,7 +71,7 @@ esp_err_t spi_flash_wrap_probe_c0(uint32_t flash_id) */ esp_err_t spi_flash_wrap_enable_c0(spi_flash_wrap_size_t wrap_size) { - uint8_t wrap_code = (uint8_t) (__builtin_ctz(wrap_size) - 3); + uint8_t wrap_code = (uint8_t)(__builtin_ctz(wrap_size) - 3); bootloader_flash_execute_command_common(CMD_BURST_RD, 0, 0, 0, 8, wrap_code, 0); return ESP_OK; } @@ -87,7 +89,7 @@ esp_err_t spi_flash_wrap_enable_c0(spi_flash_wrap_size_t wrap_size) */ esp_err_t spi_flash_wrap_enable_77(spi_flash_wrap_size_t wrap_size) { - uint8_t wrap_code = (uint8_t) (((__builtin_ctz(wrap_size) - 3) * 2) << 4); + uint8_t wrap_code = (uint8_t)(((__builtin_ctz(wrap_size) - 3) * 2) << 4); // According to the special format, we need enable QIO_FWRITE for command 77h and clear it after this command is done. REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_FWRITE_QIO); bootloader_flash_execute_command_common(CMD_WRAP, 0, 0, 6, 8, wrap_code, 0); diff --git a/components/esp_mspi/test_apps/.build-test-rules.yml b/components/esp_mspi/test_apps/.build-test-rules.yml new file mode 100644 index 00000000000..2916f9e3d85 --- /dev/null +++ b/components/esp_mspi/test_apps/.build-test-rules.yml @@ -0,0 +1,20 @@ +# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps + +components/esp_mspi/test_apps/mspi: + depends_components: + - esp_mspi + - esp_hal_mspi + - spi_flash + - esp_psram + disable: + - if: IDF_TARGET not in ["esp32s3", "esp32p4", "esp32c61", "esp32c5", "esp32s31"] + - if: CONFIG_NAME in ["generic_timing_tuning_log_safe", "generic_timing_tuning_xip"] and IDF_TARGET in ["esp32s31"] + - if: CONFIG_NAME == "120sdr_120sdr" and IDF_TARGET in ["esp32s3", "esp32p4", "esp32s31"] + +components/esp_mspi/test_apps/no_flash_delay: + depends_components: + - esp_mspi + - esp_hal_mspi + disable: + - if: IDF_TARGET not in ["esp32c3"] + reason: Testing on a single target is sufficient diff --git a/components/esp_hw_support/test_apps/mspi/CMakeLists.txt b/components/esp_mspi/test_apps/mspi/CMakeLists.txt similarity index 100% rename from components/esp_hw_support/test_apps/mspi/CMakeLists.txt rename to components/esp_mspi/test_apps/mspi/CMakeLists.txt diff --git a/components/esp_hw_support/test_apps/mspi/README.md b/components/esp_mspi/test_apps/mspi/README.md similarity index 100% rename from components/esp_hw_support/test_apps/mspi/README.md rename to components/esp_mspi/test_apps/mspi/README.md diff --git a/components/esp_hw_support/test_apps/mspi/main/CMakeLists.txt b/components/esp_mspi/test_apps/mspi/main/CMakeLists.txt similarity index 90% rename from components/esp_hw_support/test_apps/mspi/main/CMakeLists.txt rename to components/esp_mspi/test_apps/mspi/main/CMakeLists.txt index 6f9c6e16268..033955b74e0 100644 --- a/components/esp_hw_support/test_apps/mspi/main/CMakeLists.txt +++ b/components/esp_mspi/test_apps/mspi/main/CMakeLists.txt @@ -7,5 +7,5 @@ set(srcs # In order for the cases defined by `TEST_CASE` to be linked into the final elf, # the component can be registered as WHOLE_ARCHIVE idf_component_register(SRCS ${srcs} - PRIV_REQUIRES unity esp_timer spi_flash esp_partition esp_hal_mspi + PRIV_REQUIRES unity esp_timer spi_flash esp_partition esp_hal_mspi esp_mspi WHOLE_ARCHIVE) diff --git a/components/esp_mspi/test_apps/mspi/main/idf_component.yml b/components/esp_mspi/test_apps/mspi/main/idf_component.yml new file mode 100644 index 00000000000..d5f58e5fa9a --- /dev/null +++ b/components/esp_mspi/test_apps/mspi/main/idf_component.yml @@ -0,0 +1,3 @@ +dependencies: + test_utils: + path: ${IDF_PATH}/tools/test_apps/components/test_utils diff --git a/components/esp_hw_support/test_apps/mspi/main/test_app_main.c b/components/esp_mspi/test_apps/mspi/main/test_app_main.c similarity index 100% rename from components/esp_hw_support/test_apps/mspi/main/test_app_main.c rename to components/esp_mspi/test_apps/mspi/main/test_app_main.c diff --git a/components/esp_hw_support/test_apps/mspi/main/test_flash_psram.c b/components/esp_mspi/test_apps/mspi/main/test_flash_psram.c similarity index 98% rename from components/esp_hw_support/test_apps/mspi/main/test_flash_psram.c rename to components/esp_mspi/test_apps/mspi/main/test_flash_psram.c index b10d0171288..1913d5ff667 100644 --- a/components/esp_hw_support/test_apps/mspi/main/test_flash_psram.c +++ b/components/esp_mspi/test_apps/mspi/main/test_flash_psram.c @@ -68,7 +68,6 @@ TEST_CASE("MSPI: Test_SPI0_PSRAM", "[mspi]") } #endif - //-----------------------------------------SPI1 FLASH TEST-----------------------------------------------// #define SPI1_FLASH_TEST_LEN 512 #define SECTOR_LEN 4096 @@ -82,7 +81,7 @@ static const esp_partition_t *get_test_flash_partition(void) { /* This finds "flash_test" partition defined in partition_table_unit_test_app.csv */ const esp_partition_t *result = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, - ESP_PARTITION_SUBTYPE_ANY, "flash_test"); + ESP_PARTITION_SUBTYPE_ANY, "flash_test"); assert(result != NULL); /* means partition table set wrong */ return result; } @@ -119,7 +118,6 @@ TEST_CASE("MSPI: Test_SPI1_Flash", "[mspi]") printf(DRAM_STR("----------SPI1 Flash Test Success----------\n\n")); } - //-----------------------------------------SPI0 FLASH TEST-----------------------------------------------// #define SPI0_FLASH_TEST_LEN 32 #define SPI0_FLASH_TEST_BUF {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, \ @@ -145,7 +143,6 @@ TEST_CASE("MSPI: Test_SPI0_Flash", "[mspi]") printf(DRAM_STR("----------SPI0 Flash Test Success----------\n\n")); } - /*--------------------------------------------------------------- XIP + PSRAM Stack + Flash API ---------------------------------------------------------------*/ diff --git a/components/esp_hw_support/test_apps/mspi/main/test_mspi.c b/components/esp_mspi/test_apps/mspi/main/test_mspi.c similarity index 99% rename from components/esp_hw_support/test_apps/mspi/main/test_mspi.c rename to components/esp_mspi/test_apps/mspi/main/test_mspi.c index f46de1a9b29..28af33a485f 100644 --- a/components/esp_hw_support/test_apps/mspi/main/test_mspi.c +++ b/components/esp_mspi/test_apps/mspi/main/test_mspi.c @@ -8,7 +8,6 @@ #include "esp_timer.h" #include "esp_private/mspi_timing_tuning.h" - static void sorted_array_insert(uint32_t *array, uint32_t *size, uint32_t item) { uint32_t pos; diff --git a/components/esp_hw_support/test_apps/mspi/partitions.csv b/components/esp_mspi/test_apps/mspi/partitions.csv similarity index 100% rename from components/esp_hw_support/test_apps/mspi/partitions.csv rename to components/esp_mspi/test_apps/mspi/partitions.csv diff --git a/components/esp_hw_support/test_apps/mspi/pytest_flash_psram.py b/components/esp_mspi/test_apps/mspi/pytest_flash_psram.py similarity index 100% rename from components/esp_hw_support/test_apps/mspi/pytest_flash_psram.py rename to components/esp_mspi/test_apps/mspi/pytest_flash_psram.py diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.120sdr_120sdr b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.120sdr_120sdr similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.120sdr_120sdr rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.120sdr_120sdr diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32p4_120sdr_200ddr b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32p4_120sdr_200ddr similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32p4_120sdr_200ddr rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32p4_120sdr_200ddr diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s31_120sdr_200ddr b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s31_120sdr_200ddr similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s31_120sdr_200ddr rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s31_120sdr_200ddr diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_120sdr b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_120sdr similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_120sdr rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_120sdr diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_120sdr_120sdr b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_120sdr_120sdr similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_120sdr_120sdr rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_120sdr_120sdr diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_120sdr_40sdr b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_120sdr_40sdr similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_120sdr_40sdr rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_120sdr_40sdr diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_120sdr_dc_disable_build b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_120sdr_dc_disable_build similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_120sdr_dc_disable_build rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_120sdr_dc_disable_build diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_120sdr_os_silent b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_120sdr_os_silent similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_120sdr_os_silent rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_120sdr_os_silent diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_40sdr_120sdr b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_40sdr_120sdr similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_40sdr_120sdr rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_40sdr_120sdr diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_80sdr_80sdr b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_80sdr_80sdr similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_80sdr_80sdr rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f4r4_80sdr_80sdr diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f4r8_120sdr b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f4r8_120sdr similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f4r8_120sdr rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f4r8_120sdr diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f4r8_80sdr_40ddr b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f4r8_80sdr_40ddr similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f4r8_80sdr_40ddr rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f4r8_80sdr_40ddr diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f4r8_80sdr_80ddr b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f4r8_80sdr_80ddr similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f4r8_80sdr_80ddr rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f4r8_80sdr_80ddr diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_120sdr b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_120sdr similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_120sdr rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_120sdr diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_40ddr_40ddr b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_40ddr_40ddr similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_40ddr_40ddr rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_40ddr_40ddr diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_40ddr_80ddr b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_40ddr_80ddr similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_40ddr_80ddr rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_40ddr_80ddr diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_80ddr_40ddr b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_80ddr_40ddr similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_80ddr_40ddr rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_80ddr_40ddr diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_80ddr_80ddr b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_80ddr_80ddr similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_80ddr_80ddr rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_80ddr_80ddr diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_80ddr_80ddr_ecc b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_80ddr_80ddr_ecc similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_80ddr_80ddr_ecc rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_80ddr_80ddr_ecc diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_80sdr_80ddr b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_80sdr_80ddr similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_80sdr_80ddr rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.esp32s3_f8r8_80sdr_80ddr diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.generic_timing_tuning_log_safe b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.generic_timing_tuning_log_safe similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.generic_timing_tuning_log_safe rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.generic_timing_tuning_log_safe diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.generic_timing_tuning_xip b/components/esp_mspi/test_apps/mspi/sdkconfig.ci.generic_timing_tuning_xip similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.ci.generic_timing_tuning_xip rename to components/esp_mspi/test_apps/mspi/sdkconfig.ci.generic_timing_tuning_xip diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.defaults b/components/esp_mspi/test_apps/mspi/sdkconfig.defaults similarity index 100% rename from components/esp_hw_support/test_apps/mspi/sdkconfig.defaults rename to components/esp_mspi/test_apps/mspi/sdkconfig.defaults diff --git a/components/spi_flash/test_apps/no_flash_delay/CMakeLists.txt b/components/esp_mspi/test_apps/no_flash_delay/CMakeLists.txt similarity index 100% rename from components/spi_flash/test_apps/no_flash_delay/CMakeLists.txt rename to components/esp_mspi/test_apps/no_flash_delay/CMakeLists.txt diff --git a/components/spi_flash/test_apps/no_flash_delay/README.md b/components/esp_mspi/test_apps/no_flash_delay/README.md similarity index 100% rename from components/spi_flash/test_apps/no_flash_delay/README.md rename to components/esp_mspi/test_apps/no_flash_delay/README.md diff --git a/components/spi_flash/test_apps/no_flash_delay/main/CMakeLists.txt b/components/esp_mspi/test_apps/no_flash_delay/main/CMakeLists.txt similarity index 100% rename from components/spi_flash/test_apps/no_flash_delay/main/CMakeLists.txt rename to components/esp_mspi/test_apps/no_flash_delay/main/CMakeLists.txt diff --git a/components/spi_flash/test_apps/no_flash_delay/main/test_main.c b/components/esp_mspi/test_apps/no_flash_delay/main/test_main.c similarity index 57% rename from components/spi_flash/test_apps/no_flash_delay/main/test_main.c rename to components/esp_mspi/test_apps/no_flash_delay/main/test_main.c index b908720b326..d803caf8d18 100644 --- a/components/spi_flash/test_apps/no_flash_delay/main/test_main.c +++ b/components/esp_mspi/test_apps/no_flash_delay/main/test_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ diff --git a/components/spi_flash/test_apps/no_flash_delay/sdkconfig.ci.default b/components/esp_mspi/test_apps/no_flash_delay/sdkconfig.ci.default similarity index 100% rename from components/spi_flash/test_apps/no_flash_delay/sdkconfig.ci.default rename to components/esp_mspi/test_apps/no_flash_delay/sdkconfig.ci.default diff --git a/components/spi_flash/test_apps/spi_flash_opts/CMakeLists.txt b/components/esp_mspi/test_apps/spi_flash_opts/CMakeLists.txt similarity index 100% rename from components/spi_flash/test_apps/spi_flash_opts/CMakeLists.txt rename to components/esp_mspi/test_apps/spi_flash_opts/CMakeLists.txt diff --git a/components/spi_flash/test_apps/spi_flash_opts/README.md b/components/esp_mspi/test_apps/spi_flash_opts/README.md similarity index 100% rename from components/spi_flash/test_apps/spi_flash_opts/README.md rename to components/esp_mspi/test_apps/spi_flash_opts/README.md diff --git a/components/spi_flash/test_apps/spi_flash_opts/main/CMakeLists.txt b/components/esp_mspi/test_apps/spi_flash_opts/main/CMakeLists.txt similarity index 100% rename from components/spi_flash/test_apps/spi_flash_opts/main/CMakeLists.txt rename to components/esp_mspi/test_apps/spi_flash_opts/main/CMakeLists.txt diff --git a/components/spi_flash/test_apps/spi_flash_opts/main/test_main.c b/components/esp_mspi/test_apps/spi_flash_opts/main/test_main.c similarity index 57% rename from components/spi_flash/test_apps/spi_flash_opts/main/test_main.c rename to components/esp_mspi/test_apps/spi_flash_opts/main/test_main.c index b908720b326..d803caf8d18 100644 --- a/components/spi_flash/test_apps/spi_flash_opts/main/test_main.c +++ b/components/esp_mspi/test_apps/spi_flash_opts/main/test_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ diff --git a/components/spi_flash/test_apps/spi_flash_opts/sdkconfig.ci.default b/components/esp_mspi/test_apps/spi_flash_opts/sdkconfig.ci.default similarity index 100% rename from components/spi_flash/test_apps/spi_flash_opts/sdkconfig.ci.default rename to components/esp_mspi/test_apps/spi_flash_opts/sdkconfig.ci.default diff --git a/components/esp_partition/CMakeLists.txt b/components/esp_partition/CMakeLists.txt index 63e09e9091d..e7f1588939d 100644 --- a/components/esp_partition/CMakeLists.txt +++ b/components/esp_partition/CMakeLists.txt @@ -70,6 +70,9 @@ else() file(GENERATE OUTPUT "${build_dir}/linux_flash_data.txt" CONTENT "$,\n>\n") + elseif(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) + # Force linking partition_target.c so the flash region protection init hook is not discarded. + target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_partition_flash_region_protection_include_func") endif() if(CMAKE_C_COMPILER_ID MATCHES "GNU") diff --git a/components/esp_partition/partition_bootloader.c b/components/esp_partition/partition_bootloader.c index 941bfa96e89..fd38fa05702 100644 --- a/components/esp_partition/partition_bootloader.c +++ b/components/esp_partition/partition_bootloader.c @@ -7,7 +7,7 @@ #include "esp_partition.h" #include "esp_flash_partitions.h" // esp_partition_table_verify -#include "bootloader_flash_priv.h" // bootloader_ssupport/bootloader_flash/include +#include "esp_private/bootloader_flash_internal.h" // bootloader_ssupport/bootloader_flash/include #include "esp_log.h" ESP_LOG_ATTR_TAG(TAG, "partition_bootloader"); @@ -55,7 +55,7 @@ const esp_partition_t* esp_partition_find_first(esp_partition_type_t type, esp_p internal_partition.subtype = partition->subtype; internal_partition.address = partition->pos.offset; internal_partition.size = partition->pos.size; - internal_partition.erase_size = SPI_FLASH_SEC_SIZE; + internal_partition.erase_size = FLASH_SECTOR_SIZE; strncpy(internal_partition.label, (char*) partition->label, sizeof(internal_partition.label) - 1); internal_partition.encrypted = partition->flags & PART_FLAG_ENCRYPTED; internal_partition.readonly = partition->flags & PART_FLAG_READONLY; diff --git a/components/esp_partition/partition_target.c b/components/esp_partition/partition_target.c index 56046ad2f97..5f83467671d 100644 --- a/components/esp_partition/partition_target.c +++ b/components/esp_partition/partition_target.c @@ -20,6 +20,8 @@ #include "spi_flash_mmap.h" #include "bootloader_common.h" #include "esp_private/esp_partition_utils.h" +#include "esp_private/startup_internal.h" +#include "esp_private/esp_flash_internal.h" #define HASH_LEN 32 /* SHA-256 digest length */ @@ -280,3 +282,19 @@ uint32_t esp_partition_get_main_flash_sector_size(void) { return SPI_FLASH_SEC_SIZE; } + +#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +ESP_SYSTEM_INIT_FN(esp_partition_flash_region_protection_init, CORE, BIT(0), 131) +{ + esp_flash_partition_ops_t ops = { + .check_main_flash_region_safe = esp_partition_main_flash_region_safe, + .check_region_writable = esp_partition_is_flash_region_writable, + }; + return esp_flash_register_partition_ops(esp_flash_default_chip, &ops); +} + +void esp_partition_flash_region_protection_include_func(void) +{ + // Linker hook function, exists to make the linker examine this file +} +#endif // !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP diff --git a/components/esp_partition/test/CMakeLists.txt b/components/esp_partition/test/CMakeLists.txt index 6451ab5bd65..4c14df5b1c9 100644 --- a/components/esp_partition/test/CMakeLists.txt +++ b/components/esp_partition/test/CMakeLists.txt @@ -1,3 +1,4 @@ idf_component_register(SRC_DIRS "." PRIV_INCLUDE_DIRS "." - PRIV_REQUIRES test_utils esp_partition esp_system app_update bootloader_support spi_flash) + PRIV_REQUIRES test_utils esp_partition esp_system app_update bootloader_support + spi_flash esp_mspi) diff --git a/components/esp_psram/CMakeLists.txt b/components/esp_psram/CMakeLists.txt index d723602b8e0..bb983008c0b 100644 --- a/components/esp_psram/CMakeLists.txt +++ b/components/esp_psram/CMakeLists.txt @@ -10,7 +10,7 @@ if(CONFIG_SOC_SPIRAM_XIP_SUPPORTED) list(APPEND includes xip_impl/include) endif() -set(priv_requires heap spi_flash esp_mm esp_hal_mspi esp_hal_gpio) +set(priv_requires heap esp_mspi esp_mm esp_hal_mspi esp_hal_gpio) if(${target} STREQUAL "esp32") list(APPEND priv_requires bootloader_support esp_driver_gpio) endif() diff --git a/components/esp_psram/esp32s3/esp_psram_impl_octal.c b/components/esp_psram/esp32s3/esp_psram_impl_octal.c index b80bdb8b802..b05524b6190 100644 --- a/components/esp_psram/esp32s3/esp_psram_impl_octal.c +++ b/components/esp_psram/esp32s3/esp_psram_impl_octal.c @@ -23,6 +23,7 @@ #include "esp_private/spi_flash_os.h" #include "esp_private/mspi_timing_tuning.h" #include "esp_private/esp_gpio_reserve.h" +#include "esp_private/opi_flash_private.h" #define OPI_PSRAM_SYNC_READ 0x0000 #define OPI_PSRAM_SYNC_WRITE 0x8080 @@ -336,6 +337,18 @@ static void s_configure_psram_ecc(void) #endif } +static void s_set_flash_vendor_required_regs(void) +{ + if (spi_flash_is_octal_mode_enabled()) { + esp_opiflash_set_required_regs(); + SET_PERI_REG_BITS(SPI_MEM_CACHE_FCTRL_REG(1), SPI_MEM_CACHE_USR_CMD_4BYTE_V, 1, SPI_MEM_CACHE_USR_CMD_4BYTE_S); + } else { + //Flash chip requires MSPI specifically, call this function to set them + // Set back MSPI registers after Octal PSRAM initialization. + SET_PERI_REG_BITS(SPI_MEM_CACHE_FCTRL_REG(1), SPI_MEM_CACHE_USR_CMD_4BYTE_V, 0, SPI_MEM_CACHE_USR_CMD_4BYTE_S); + } +} + esp_err_t esp_psram_impl_enable(void) { s_init_psram_pins(); @@ -386,7 +399,7 @@ esp_err_t esp_psram_impl_enable(void) */ spi_flash_set_rom_required_regs(); //Flash chip requires MSPI specifically, call this function to set them - spi_flash_set_vendor_required_regs(); + s_set_flash_vendor_required_regs(); s_config_psram_spi_phases(); return ESP_OK; diff --git a/components/esp_ringbuf/test_apps/main/CMakeLists.txt b/components/esp_ringbuf/test_apps/main/CMakeLists.txt index 09c67e40b61..359503f5669 100644 --- a/components/esp_ringbuf/test_apps/main/CMakeLists.txt +++ b/components/esp_ringbuf/test_apps/main/CMakeLists.txt @@ -3,7 +3,7 @@ idf_build_get_property(target IDF_TARGET) set(srcs "test_ringbuf_main.c" "test_ringbuf_common.c") -set(priv_requires esp_ringbuf spi_flash unity) +set(priv_requires esp_ringbuf unity esp_mspi) if(NOT ${target} STREQUAL "linux") list(APPEND srcs "test_ringbuf_target.c") diff --git a/components/esp_system/CMakeLists.txt b/components/esp_system/CMakeLists.txt index 1880640a614..00cf3aeb879 100644 --- a/components/esp_system/CMakeLists.txt +++ b/components/esp_system/CMakeLists.txt @@ -12,7 +12,7 @@ if(${target} STREQUAL "linux") "freertos_hooks.c" "startup.c" INCLUDE_DIRS "include" - PRIV_REQUIRES spi_flash) + PRIV_REQUIRES esp_mspi) # Add custom ld file (used to place system init functions). # Mach-O (Apple) does not support linker scripts; section bounds are resolved @@ -39,10 +39,10 @@ if(BOOTLOADER_BUILD OR esp_tee_build) if(esp_tee_build) list(APPEND include_dirs "port/include/private") endif() - # "_esp_error_check_failed()" requires spi_flash module + # "_esp_error_check_failed()" requires esp_mspi module # Bootloader relies on some Kconfig options defined in esp_system. idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "${include_dirs}" - REQUIRES spi_flash) + PRIV_REQUIRES esp_mspi) else() list(APPEND srcs "crosscore_int.c" "esp_ipc.c" @@ -96,7 +96,7 @@ else() list(APPEND srcs "debug_assist.c") endif() - set(priv_requires spi_flash esp_timer esp_mm + set(priv_requires esp_mspi esp_timer esp_mm esp_hal_clock esp_hal_mspi esp_hal_wdt esp_hal_debug_assist esp_hal_uart esp_hal_dma esp_hal_security # [refactor-todo] requirements due to init code, diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index f702507d539..0ce2baa12fb 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -121,7 +121,6 @@ #include "esp_rom_spiflash.h" #include "bootloader_init.h" #include "esp_private/bootloader_flash_internal.h" -#include "spi_flash_mmap.h" #endif // CONFIG_APP_BUILD_TYPE_RAM //This dependency will be removed in the future @@ -569,7 +568,7 @@ FORCE_INLINE_ATTR IRAM_ATTR void ext_mem_init(void) uint32_t cache_mmu_irom_size = 0; #if !CONFIG_APP_BUILD_TYPE_ELF_RAM uint32_t _instruction_size = (uint32_t)&_instruction_reserved_end - (uint32_t)&_instruction_reserved_start; - cache_mmu_irom_size = ((_instruction_size + SPI_FLASH_MMU_PAGE_SIZE - 1) / SPI_FLASH_MMU_PAGE_SIZE) * sizeof(uint32_t); + cache_mmu_irom_size = ((_instruction_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE) * sizeof(uint32_t); #endif // !CONFIG_APP_BUILD_TYPE_ELF_RAM /* Configure the Cache MMU size for instruction and rodata in flash. */ Cache_Set_IDROM_MMU_Size(cache_mmu_irom_size, CACHE_DROM_MMU_MAX_END - cache_mmu_irom_size); @@ -780,10 +779,10 @@ NOINLINE_ATTR static void system_early_init(const soc_reset_reason_t *rst_reas) uint32_t cache_mmu_drom_size = 0; #if !CONFIG_APP_BUILD_TYPE_ELF_RAM uint32_t _instruction_size = (uint32_t)&_instruction_reserved_end - (uint32_t)&_instruction_reserved_start; - cache_mmu_irom_size = ((_instruction_size + SPI_FLASH_MMU_PAGE_SIZE - 1) / SPI_FLASH_MMU_PAGE_SIZE) * sizeof(uint32_t); + cache_mmu_irom_size = ((_instruction_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE) * sizeof(uint32_t); uint32_t _rodata_size = (uint32_t)&_rodata_reserved_end - (uint32_t)&_rodata_reserved_start; - cache_mmu_drom_size = ((_rodata_size + SPI_FLASH_MMU_PAGE_SIZE - 1) / SPI_FLASH_MMU_PAGE_SIZE) * sizeof(uint32_t); + cache_mmu_drom_size = ((_rodata_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE) * sizeof(uint32_t); #endif // !CONFIG_APP_BUILD_TYPE_ELF_RAM int s_instr_flash2spiram_off = 0; diff --git a/components/esp_system/system_init_fn.txt b/components/esp_system/system_init_fn.txt index 60c105f25ab..2df0f1bdec4 100644 --- a/components/esp_system/system_init_fn.txt +++ b/components/esp_system/system_init_fn.txt @@ -69,7 +69,13 @@ CORE: 118: init_vfs_nullfs in components/vfs/nullfs.c on BIT(0) CORE: 119: init_vfs_console in components/esp_stdio/stdio_vfs.c on BIT(0) CORE: 120: init_libc_stdio in components/esp_libc/src/init.c on BIT(0) +CORE: 125: init_flash_dpd in components/esp_mspi/flash_ops.c on BIT(0) + CORE: 130: init_flash in components/spi_flash/esp_flash_spi_init.c on BIT(0) + +# Register partition-based flash write protection callback into spi_flash, right after init_flash. +CORE: 131: esp_partition_flash_region_protection_init in components/esp_partition/partition_target.c on BIT(0) + CORE: 140: init_efuse in components/efuse/src/esp_efuse_startup.c on BIT(0) CORE: 170: init_xt_wdt in components/esp_system/startup_funcs.c on BIT(0) @@ -142,7 +148,7 @@ SECONDARY: 230: usb_serial_jtag_conn_status_init in components/esp_driver_usb_se # psram adjust timing point need a separate task which should be created at startup. # Valid only `CONFIG_SPIRAM_TIMING_TUNING_POINT_VIA_TEMPERATURE_SENSOR` is enabled. -SECONDARY: 240: psram_adjust_timing_point_via_temperature in components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_by_mspi_delay.c on BIT(0) +SECONDARY: 240: psram_adjust_timing_point_via_temperature in components/esp_mspi/mspi_timing_tuning/port/esp32s3/mspi_timing_by_mspi_delay.c on BIT(0) # Has to be the last step! # Now that the application is about to start, disable boot watchdog diff --git a/components/esp_system/test_apps/cache_panic/main/CMakeLists.txt b/components/esp_system/test_apps/cache_panic/main/CMakeLists.txt index e0f128b8475..3a82ae2c17d 100644 --- a/components/esp_system/test_apps/cache_panic/main/CMakeLists.txt +++ b/components/esp_system/test_apps/cache_panic/main/CMakeLists.txt @@ -2,5 +2,5 @@ set(srcs "test_cache_disabled.c" "test_app_main.c") idf_component_register(SRCS ${srcs} - PRIV_REQUIRES unity spi_flash + PRIV_REQUIRES unity esp_mspi WHOLE_ARCHIVE) diff --git a/components/esp_tee/CMakeLists.txt b/components/esp_tee/CMakeLists.txt index a80d4ca197f..dd7feffe202 100644 --- a/components/esp_tee/CMakeLists.txt +++ b/components/esp_tee/CMakeLists.txt @@ -82,7 +82,7 @@ else() idf_component_register(INCLUDE_DIRS include SRCS ${srcs} PRIV_REQUIRES efuse esp_hal_wdt esp_security esp_stdio - esp_system esptool_py mbedtls spi_flash) + esp_system esptool_py mbedtls spi_flash esp_mspi) if(CONFIG_SECURE_ENABLE_TEE) set(EXTRA_LINK_FLAGS) list(APPEND EXTRA_LINK_FLAGS "-u esp_tee_app_config") diff --git a/components/esp_tee/include/private/esp_tee_binary.h b/components/esp_tee/include/private/esp_tee_binary.h index 726e87be2fc..c8f144e894c 100644 --- a/components/esp_tee/include/private/esp_tee_binary.h +++ b/components/esp_tee/include/private/esp_tee_binary.h @@ -11,6 +11,7 @@ extern "C" { #endif #include "soc/soc_caps.h" +#include "soc/soc.h" #include "sdkconfig.h" /* Declarations used inside TEE binary, only */ diff --git a/components/esp_tee/subproject/main/core/esp_secure_services_iram.c b/components/esp_tee/subproject/main/core/esp_secure_services_iram.c index e15edd8fd20..0203a55861e 100644 --- a/components/esp_tee/subproject/main/core/esp_secure_services_iram.c +++ b/components/esp_tee/subproject/main/core/esp_secure_services_iram.c @@ -23,6 +23,7 @@ #include "esp_flash_chips/spi_flash_defs.h" #include "esp_private/memspi_host_driver.h" #include "esp_private/mspi_timing_tuning.h" +#include "esp_private/spi_flash_os.h" #include "esp_flash.h" #include "esp_flash_chips/esp_flash_types.h" #include "bootloader_flash_priv.h" diff --git a/components/esp_tee/subproject/main/ld/esp32c5/esp_tee.ld.in b/components/esp_tee/subproject/main/ld/esp32c5/esp_tee.ld.in index bbb5c11442f..35d11cfcc6f 100644 --- a/components/esp_tee/subproject/main/ld/esp32c5/esp_tee.ld.in +++ b/components/esp_tee/subproject/main/ld/esp32c5/esp_tee.ld.in @@ -116,6 +116,7 @@ SECTIONS *libtee_sec_storage.a:*(.literal .text .literal.* .text.*) *libtee_ota_ops.a:*(.literal .text .literal.* .text.*) *libtee_attestation.a:*(.literal .text .literal.* .text.*) + *libesp_mspi.a:*(.literal .text .literal.* .text.*) /* Align the end of code region as per PMP region granularity */ ALIGNED_SYMBOL(_esp_pmp_align_size, _tee_iram_end) @@ -177,6 +178,7 @@ SECTIONS *libhal.a:mmu_hal.c*(.rodata .srodata .rodata.* .srodata.*) *libhal.a:cache_hal.c*(.rodata .srodata .rodata.* .srodata.*) *libesp_hal_mspi.a:*(.rodata .srodata .rodata.* .srodata.*) + *libesp_mspi.a:*(.rodata .rodata.* .srodata .srodata.*) _tee_rodata_end = ABSOLUTE(.); _tee_dram_end = ABSOLUTE(.); } > sram_tee_seg diff --git a/components/esp_tee/subproject/main/ld/esp32c6/esp_tee.ld.in b/components/esp_tee/subproject/main/ld/esp32c6/esp_tee.ld.in index d3afa44be3e..dbc3ad39c2f 100644 --- a/components/esp_tee/subproject/main/ld/esp32c6/esp_tee.ld.in +++ b/components/esp_tee/subproject/main/ld/esp32c6/esp_tee.ld.in @@ -114,6 +114,7 @@ SECTIONS *libtee_sec_storage.a:*(.literal .text .literal.* .text.*) *libtee_ota_ops.a:*(.literal .text .literal.* .text.*) *libtee_attestation.a:*(.literal .text .literal.* .text.*) + *libesp_mspi.a:*(.literal .text .literal.* .text.*) /* Align the end of code region as per PMP region granularity */ ALIGNED_SYMBOL(_esp_pmp_align_size, _tee_iram_end) @@ -175,6 +176,7 @@ SECTIONS *libhal.a:mmu_hal.c*(.rodata .srodata .rodata.* .srodata.*) *libhal.a:cache_hal.c*(.rodata .srodata .rodata.* .srodata.*) *libesp_hal_mspi.a:*(.rodata .srodata .rodata.* .srodata.*) + *libesp_mspi.a:*(.rodata .rodata.* .srodata .srodata.*) _tee_rodata_end = ABSOLUTE(.); _tee_dram_end = ABSOLUTE(.); } > sram_tee_seg diff --git a/components/esp_tee/subproject/main/ld/esp32c61/esp_tee.ld.in b/components/esp_tee/subproject/main/ld/esp32c61/esp_tee.ld.in index cbfa205a646..884fbf4c0f5 100644 --- a/components/esp_tee/subproject/main/ld/esp32c61/esp_tee.ld.in +++ b/components/esp_tee/subproject/main/ld/esp32c61/esp_tee.ld.in @@ -114,6 +114,7 @@ SECTIONS *libtee_sec_storage.a:*(.literal .text .literal.* .text.*) *libtee_ota_ops.a:*(.literal .text .literal.* .text.*) *libtee_attestation.a:*(.literal .text .literal.* .text.*) + *libesp_mspi.a:*(.literal .text .literal.* .text.*) /* Align the end of code region as per PMP region granularity */ ALIGNED_SYMBOL(_esp_pmp_align_size, _tee_iram_end) @@ -175,6 +176,7 @@ SECTIONS *libhal.a:mmu_hal.c*(.rodata .srodata .rodata.* .srodata.*) *libhal.a:cache_hal.c*(.rodata .srodata .rodata.* .srodata.*) *libesp_hal_mspi.a:*(.rodata .srodata .rodata.* .srodata.*) + *libesp_mspi.a:*(.rodata .rodata.* .srodata .srodata.*) _tee_rodata_end = ABSOLUTE(.); _tee_dram_end = ABSOLUTE(.); } > sram_tee_seg diff --git a/components/esp_tee/subproject/main/ld/esp32h2/esp_tee.ld.in b/components/esp_tee/subproject/main/ld/esp32h2/esp_tee.ld.in index 1a956401a36..5800c53c04d 100644 --- a/components/esp_tee/subproject/main/ld/esp32h2/esp_tee.ld.in +++ b/components/esp_tee/subproject/main/ld/esp32h2/esp_tee.ld.in @@ -114,6 +114,7 @@ SECTIONS *libtee_sec_storage.a:*(.literal .text .literal.* .text.*) *libtee_ota_ops.a:*(.literal .text .literal.* .text.*) *libtee_attestation.a:*(.literal .text .literal.* .text.*) + *libesp_mspi.a:*(.literal .text .literal.* .text.*) /* Align the end of code region as per PMP region granularity */ ALIGNED_SYMBOL(_esp_pmp_align_size, _tee_iram_end) @@ -175,6 +176,7 @@ SECTIONS *libhal.a:mmu_hal.c*(.rodata .srodata .rodata.* .srodata.*) *libhal.a:cache_hal.c*(.rodata .srodata .rodata.* .srodata.*) *libesp_hal_mspi.a:*(.rodata .srodata .rodata.* .srodata.*) + *libesp_mspi.a:*(.rodata .rodata.* .srodata .srodata.*) _tee_rodata_end = ABSOLUTE(.); _tee_dram_end = ABSOLUTE(.); } > sram_tee_seg diff --git a/components/esp_timer/test_apps/esp_timer_tests/main/CMakeLists.txt b/components/esp_timer/test_apps/esp_timer_tests/main/CMakeLists.txt index 60d3e4f31d4..21b455de1fa 100644 --- a/components/esp_timer/test_apps/esp_timer_tests/main/CMakeLists.txt +++ b/components/esp_timer/test_apps/esp_timer_tests/main/CMakeLists.txt @@ -20,7 +20,7 @@ if(NOT ${target} STREQUAL "linux") list(APPEND srcs "test_esp_timer_dfs.c") endif() - set(priv_requires cmock test_utils esp_timer spi_flash esp_psram esp_driver_gpio esp_pm) + set(priv_requires cmock test_utils esp_timer esp_mspi esp_psram esp_driver_gpio esp_pm) list(APPEND srcs "test_ets_timer.c") else() set(priv_requires cmock test_utils esp_timer) diff --git a/components/esp_timer/test_apps/esp_timer_tests/main/test_ets_timer.c b/components/esp_timer/test_apps/esp_timer_tests/main/test_ets_timer.c index a9045562e89..e9a73db3aa3 100644 --- a/components/esp_timer/test_apps/esp_timer_tests/main/test_ets_timer.c +++ b/components/esp_timer/test_apps/esp_timer_tests/main/test_ets_timer.c @@ -12,7 +12,6 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" -#include "spi_flash_mmap.h" #include "esp_rom_sys.h" #include "esp_private/spi_flash_os.h" #include "rom/ets_sys.h" diff --git a/components/espcoredump/src/core_dump_flash.c b/components/espcoredump/src/core_dump_flash.c index eff2abd616d..02d731320af 100644 --- a/components/espcoredump/src/core_dump_flash.c +++ b/components/espcoredump/src/core_dump_flash.c @@ -8,10 +8,11 @@ #include #include "esp_partition.h" #include "esp_log.h" +#include "esp_efuse.h" #include "esp_core_dump_types.h" #include "core_dump_checksum.h" #include "esp_private/esp_flash_internal.h" -#include "esp_efuse.h" +#include "esp_flash_encrypt.h" #include "esp_rom_crc.h" #include "esp_private/spi_flash_os.h" #include "spi_flash_mmap.h" diff --git a/components/heap/test_apps/heap_tests/main/CMakeLists.txt b/components/heap/test_apps/heap_tests/main/CMakeLists.txt index 9e3f86f877d..f054f818ff0 100644 --- a/components/heap/test_apps/heap_tests/main/CMakeLists.txt +++ b/components/heap/test_apps/heap_tests/main/CMakeLists.txt @@ -14,5 +14,5 @@ set(src_test "test_heap_main.c" idf_component_register(SRCS ${src_test} INCLUDE_DIRS "." - REQUIRES unity esp_psram spi_flash esp_mm esp_timer + REQUIRES unity esp_psram esp_mm esp_mspi esp_timer WHOLE_ARCHIVE) diff --git a/components/heap/test_apps/heap_tests/main/test_aligned_alloc_caps.c b/components/heap/test_apps/heap_tests/main/test_aligned_alloc_caps.c index 4c7e1fbf1f7..b1b50d01a09 100644 --- a/components/heap/test_apps/heap_tests/main/test_aligned_alloc_caps.c +++ b/components/heap/test_apps/heap_tests/main/test_aligned_alloc_caps.c @@ -12,7 +12,6 @@ #include "unity.h" #include "esp_attr.h" #include "esp_heap_caps.h" -#include "spi_flash_mmap.h" #include #include #include diff --git a/components/heap/test_apps/heap_tests/main/test_malloc_caps.c b/components/heap/test_apps/heap_tests/main/test_malloc_caps.c index 65f46aba362..2ae7bc4a220 100644 --- a/components/heap/test_apps/heap_tests/main/test_malloc_caps.c +++ b/components/heap/test_apps/heap_tests/main/test_malloc_caps.c @@ -14,7 +14,6 @@ #include "esp_heap_caps.h" #include "esp_heap_caps_init.h" #include "heap_memory_layout.h" -#include "spi_flash_mmap.h" #include "esp_memory_utils.h" #include "esp_private/spi_flash_os.h" #include diff --git a/components/spi_flash/CMakeLists.txt b/components/spi_flash/CMakeLists.txt index dc4811e4767..5eb8ea646a0 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/components/spi_flash/CMakeLists.txt @@ -3,33 +3,19 @@ idf_build_get_property(non_os_build NON_OS_BUILD) if(${target} STREQUAL "linux") idf_component_register(SRCS "linux/spi_flash_linux.c" - "linux/cache_utils.c" "linux/flash_mmap.c" "spi_flash_blockdev.c" INCLUDE_DIRS include - REQUIRES esp_hal_mspi esp_blockdev) + REQUIRES esp_hal_mspi esp_blockdev + PRIV_REQUIRES esp_mspi) return() endif() if(non_os_build OR CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) - set(srcs "spi_flash_wrap.c") + set(srcs "") set(priv_requires bootloader_support soc esp_hal_gpio) else() - set(srcs "flash_brownout_hook.c") - - if(CONFIG_SOC_SPI_MEM_SUPPORT_FLASH_OPI_MODE) - list(APPEND srcs "${target}/spi_flash_oct_flash_init.c") - endif() - - if(CONFIG_SPI_FLASH_HPM_ON) - list(APPEND srcs - "spi_flash_hpm_enable.c") - endif() - - if(CONFIG_ESP_SLEEP_SET_FLASH_DPD) - list(APPEND srcs - "spi_flash_dpd_enable.c") - endif() + set(srcs "") # New implementation after IDF v4.0 list(APPEND srcs @@ -46,13 +32,7 @@ else() "spi_flash_blockdev.c") set(cache_srcs - "cache_utils.c" "flash_mmap.c" - "flash_ops.c" - "spi_flash_wrap.c" - ) - - list(APPEND cache_srcs "esp_flash_api.c" "esp_flash_spi_init.c" "spi_flash_os_func_app.c" @@ -67,7 +47,7 @@ else() endif() idf_component_register(SRCS "${srcs}" - REQUIRES hal esp_hal_mspi esp_blockdev + REQUIRES hal esp_hal_mspi esp_mspi esp_blockdev PRIV_REQUIRES "${priv_requires}" INCLUDE_DIRS include LDFRAGMENTS linker.lf) diff --git a/components/spi_flash/Kconfig b/components/spi_flash/Kconfig index e99d071f06f..e81e86ffec7 100644 --- a/components/spi_flash/Kconfig +++ b/components/spi_flash/Kconfig @@ -1,193 +1,112 @@ -menu "Main Flash configuration" +menu "Optional and Experimental SPI Flash Features (READ DOCS FIRST)" depends on !APP_BUILD_TYPE_PURE_RAM_APP - menu "SPI Flash behavior when brownout" + comment "Features here require specific hardware (READ DOCS FIRST!)" - config SPI_FLASH_BROWNOUT_RESET_XMC - bool "Enable sending reset when brownout for XMC flash chips" - default y - select SPI_FLASH_BROWNOUT_RESET - help - When this option is selected, the patch will be enabled for XMC. - Follow the recommended flow by XMC for better stability. + config SPI_FLASH_AUTO_SUSPEND + bool "Auto suspend long erase/write operations (READ DOCS FIRST)" + default n + depends on SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND && !SPI_FLASH_ROM_IMPL + help + This option is disabled by default because it is supported only + for specific flash chips and for specific Espressif chips. + To evaluate if you can use this feature refer to + `Optional Features for Flash` > `Auto Suspend & Resume` of the `ESP-IDF Programming Guide`. - DO NOT DISABLE UNLESS YOU KNOW WHAT YOU ARE DOING. + CAUTION: If you want to OTA to an app with this feature turned on, please make + sure the bootloader has the support for it. (later than IDF v4.3) - config SPI_FLASH_BROWNOUT_RESET - bool - default y - select ESP_BROWNOUT_USE_INTR - help - When brownout happens during flash erase/write operations, - send reset command to stop the flash operations to improve stability. + If you are using an official Espressif module, please contact Espressif Business support + to check if the module has the flash that support this feature installed. + Also refer to `Concurrency Constraints for Flash on SPI1` > `Flash Auto Suspend Feature` + before enabling this option. - endmenu + config SPI_FLASH_SUSPEND_TSUS_VAL_US + int "SPI flash tSUS value (refer to chapter AC CHARACTERISTICS)" + default 50 + range 20 100 + help + This config is used for setting Tsus parameter. Tsus means CS# high to next command after + suspend. You can refer to the chapter of AC CHARACTERISTICS of flash datasheet. - menu "Optional and Experimental Features (READ DOCS FIRST)" + config SPI_FLASH_SUSPEND_TRS_VAL_US + int "SPI flash tRS value (refer to chapter AC CHARACTERISTICS)" + default 50 + range 20 200 + depends on SOC_SPI_MEM_SUPPORT_TSUS_TRES_SEPERATE_CTR && (!ESP32P4_SELECTS_REV_LESS_V3) + help + This config is used for setting Trs parameter. Trs means CS Latency Between Resume And Next Suspend. + You can refer to the chapter of AC CHARACTERISTICS of flash datasheet. + For high-performance scenarios, some flash chips allow this set value to be smaller than the + given value in the datasheet without causing errors in the flash state machine. + When you have any related needs, please contact espressif business team. - comment "Features here require specific hardware (READ DOCS FIRST!)" + config SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND + bool "Enable XMC-C series flash chip suspend feature anyway" + default n + help + XMC-C series is regarded as not qualified for the Suspend feature, since its specification + has a tRS >= 1ms restriction. We strongly do not suggest using it for the Suspend feature. + However, if your product in field has enabled this feature, you may still enable this + config option to keep the legacy behavior. - config SPI_FLASH_UNDER_HIGH_FREQ - bool - default y if ESPTOOLPY_FLASHFREQ_120M - help - This is a helper config for HPM. Invisible for users. + For new users, DO NOT enable this config. - choice SPI_FLASH_HPM - prompt "High Performance Mode (READ DOCS FIRST, > 80MHz)" - depends on SOC_SPI_MEM_FLASH_SUPPORT_HPM && !ESPTOOLPY_OCT_FLASH - default SPI_FLASH_HPM_AUTO - help - Whether the High Performance Mode of Flash is enabled. As an optional feature, user needs to manually - enable this option as a confirmation. To be back-compatible with earlier IDF version, this option is - automatically enabled with warning when Flash running > 80Mhz. + config SPI_FLASH_FORCE_ENABLE_C6_H2_SUSPEND + bool "Enable chip suspend feature on c6 or h2 anyway (DO NOT ENABLE FOR NEW USERS OR APPLICATIONS)" + default n + help + Flash suspend has a defect on ESP32C6 until v0.2 and ESP32H2 until v1.2. If you already use suspend + feature for mass production, you can enable this for bypassing check after knowing the risk. + But if you are new users, or developing new applications, or producing a new batch, + please DO NOT enable this config option. - config SPI_FLASH_HPM_ENA - # Not using name of SPI_FLASH_HPM_ENABLE because it was used as an invisible option and we don't want - # to inherit the value of that one - bool "Enable" - config SPI_FLASH_HPM_AUTO - bool "Auto (Not recommended)" - config SPI_FLASH_HPM_DIS - bool "Disabled" - endchoice + For more information, please refer to errata or connect to Espressif business support team. - config SPI_FLASH_HPM_ON - bool - # For ESP32-S3, it's enabled by default. For later chips it should be disabled by default - default y if (IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32P4) && ((SPI_FLASH_HPM_ENA || SPI_FLASH_HPM_AUTO)) || \ - (!IDF_TARGET_ESP32S3 && SPI_FLASH_HPM_ENA) - help - This option is invisible, and will be selected automatically - when ``ESPTOOLPY_FLASHFREQ_120M`` is selected. + config SPI_FLASH_SOFTWARE_RESUME + bool "Resume flash program/erase form suspend state by software control" + default n + depends on SPI_FLASH_AUTO_SUSPEND && FREERTOS_UNICORE && IDF_EXPERIMENTAL_FEATURES + help + Enable this config will disable auto-resume from hardware. Thus the software will resume the chip + after any higher priority task/interrupt which suspend the chip. The benefit is that the suspend-resume + will not disturb the higher priority task and interrupt. - choice SPI_FLASH_HPM_DC - prompt "Support HPM using DC (READ DOCS FIRST)" - depends on SPI_FLASH_HPM_ON - default SPI_FLASH_HPM_DC_AUTO - help - This feature needs your bootloader to be compiled DC-aware (BOOTLOADER_FLASH_DC_AWARE=y). Otherwise the - chip will not be able to boot after a reset. + This currently is only valid on single core chip. - config SPI_FLASH_HPM_DC_AUTO - bool "Auto (Enable when bootloader support enabled (BOOTLOADER_FLASH_DC_AWARE))" - config SPI_FLASH_HPM_DC_DISABLE - bool "Disable (READ DOCS FIRST)" - endchoice + config SPI_FLASH_DISABLE_SCHEDULER_IN_SUSPEND + bool "Disable task scheduler when suspend is enabled when SPI1 operation is ongoing" + default n + # Only valid on single core because no protection is supported on multi core + depends on SPI_FLASH_AUTO_SUSPEND && FREERTOS_UNICORE + help + Disable freertos task scheduler when CONFIG_SPI_FLASH_AUTO_SUSPEND is enabled. + Thus only interrupt can trigger a suspend. When SPI_FLASH_AUTO_SUSPEND is enabled, + default behavior is not disable the task scheduler, so both interrupt and high priority + task can suspend the erase/program operation. When this option is enabled, task + scheduler is disabled, only interrupt can suspend erase/program operation. - config SPI_FLASH_HPM_DC_ON - bool - default y if SPI_FLASH_HPM_DC_AUTO && BOOTLOADER_FLASH_DC_AWARE - help - This is a helper config for HPM. Whether HPM-DC is enabled is also determined by bootloader. - Invisible for users. + config SPI_FLASH_AUTO_CHECK_SUSPEND_STATUS + bool "Check flash status automatically after flash suspend" + default n + depends on SPI_FLASH_AUTO_SUSPEND + help + Majority flash supports to use flash register to judge if flash suspend status is + done or not. So enable this config, the behavior would use flash register WIP bit to judge + whether suspend is valid instead of waiting for a specific long time, which can save a + lot of time and benefit for performance improvement. - config SPI_FLASH_AUTO_SUSPEND - bool "Auto suspend long erase/write operations (READ DOCS FIRST)" - default n - depends on SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND && !SPI_FLASH_ROM_IMPL - help - This option is disabled by default because it is supported only - for specific flash chips and for specific Espressif chips. - To evaluate if you can use this feature refer to - `Optional Features for Flash` > `Auto Suspend & Resume` of the `ESP-IDF Programming Guide`. + config SPI_FLASH_PLACE_FUNCTIONS_IN_IRAM + bool "Place spi_flash operation functions into IRAM" if SPI_FLASH_AUTO_SUSPEND + default y + help + When disabled, certain functions in `spi_flash` component will be placed into Flash memory + instead of IRAM. Disabling this option will save almost 10KB of IRAM depending on which + functions are used. - CAUTION: If you want to OTA to an app with this feature turned on, please make - sure the bootloader has the support for it. (later than IDF v4.3) + When enabled, these functions will be placed in internal RAM, with better performance. - If you are using an official Espressif module, please contact Espressif Business support - to check if the module has the flash that support this feature installed. - Also refer to `Concurrency Constraints for Flash on SPI1` > `Flash Auto Suspend Feature` - before enabling this option. - - config SPI_FLASH_SUSPEND_TSUS_VAL_US - int "SPI flash tSUS value (refer to chapter AC CHARACTERISTICS)" - default 50 - range 20 100 - help - This config is used for setting Tsus parameter. Tsus means CS# high to next command after - suspend. You can refer to the chapter of AC CHARACTERISTICS of flash datasheet. - - config SPI_FLASH_SUSPEND_TRS_VAL_US - int "SPI flash tRS value (refer to chapter AC CHARACTERISTICS)" - default 50 - range 20 200 - depends on SOC_SPI_MEM_SUPPORT_TSUS_TRES_SEPERATE_CTR && (!ESP32P4_SELECTS_REV_LESS_V3) - help - This config is used for setting Trs parameter. Trs means CS Latency Between Resume And Next Suspend. - You can refer to the chapter of AC CHARACTERISTICS of flash datasheet. - For high-performance scenarios, some flash chips allow this set value to be smaller than the - given value in the datasheet without causing errors in the flash state machine. - When you have any related needs, please contact espressif business team. - - config SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND - bool "Enable XMC-C series flash chip suspend feature anyway" - default n - help - XMC-C series is regarded as not qualified for the Suspend feature, since its specification - has a tRS >= 1ms restriction. We strongly do not suggest using it for the Suspend feature. - However, if your product in field has enabled this feature, you may still enable this - config option to keep the legacy behavior. - - For new users, DO NOT enable this config. - - config SPI_FLASH_FORCE_ENABLE_C6_H2_SUSPEND - bool "Enable chip suspend feature on c6 or h2 anyway (DO NOT ENABLE FOR NEW USERS OR APPLICATIONS)" - default n - help - Flash suspend has a defect on ESP32C6 until v0.2 and ESP32H2 until v1.2. If you already use suspend - feature for mass production, you can enable this for bypassing check after knowing the risk. - But if you are new users, or developing new applications, or producing a new batch, - please DO NOT enable this config option. - - For more information, please refer to errata or connect to Espressif business support team. - - config SPI_FLASH_SOFTWARE_RESUME - bool "Resume flash program/erase form suspend state by software control" - default n - depends on SPI_FLASH_AUTO_SUSPEND && FREERTOS_UNICORE && IDF_EXPERIMENTAL_FEATURES - help - Enable this config will disable auto-resume from hardware. Thus the software will resume the chip - after any higher priority task/interrupt which suspend the chip. The benefit is that the suspend-resume - will not disturb the higher priority task and interrupt. - - This currently is only valid on single core chip. - - config SPI_FLASH_DISABLE_SCHEDULER_IN_SUSPEND - bool "Disable task scheduler when suspend is enabled when SPI1 operation is ongoing" - default n - # Only valid on single core because no protection is supported on multi core - depends on SPI_FLASH_AUTO_SUSPEND && FREERTOS_UNICORE - help - Disable freertos task scheduler when CONFIG_SPI_FLASH_AUTO_SUSPEND is enabled. - Thus only interrupt can trigger a suspend. When SPI_FLASH_AUTO_SUSPEND is enabled, - default behavior is not disable the task scheduler, so both interrupt and high priority - task can suspend the erase/program operation. When this option is enabled, task - scheduler is disabled, only interrupt can suspend erase/program operation. - - config SPI_FLASH_AUTO_CHECK_SUSPEND_STATUS - bool "Check flash status automatically after flash suspend" - default n - depends on SPI_FLASH_AUTO_SUSPEND - help - Majority flash supports to use flash register to judge if flash suspend status is - done or not. So enable this config, the behavior would use flash register WIP bit to judge - whether suspend is valid instead of waiting for a specific long time, which can save a - lot of time and benefit for performance improvement. - - config SPI_FLASH_PLACE_FUNCTIONS_IN_IRAM - bool "Place spi_flash operation functions into IRAM" if SPI_FLASH_AUTO_SUSPEND - default y - help - When disabled, certain functions in `spi_flash` component will be placed into Flash memory - instead of IRAM. Disabling this option will save almost 10KB of IRAM depending on which - functions are used. - - When enabled, these functions will be placed in internal RAM, with better performance. - - For more information please refer to programming guide. - - endmenu + For more information please refer to programming guide. endmenu menu "SPI Flash driver" diff --git a/components/spi_flash/README.rst b/components/spi_flash/README.rst deleted file mode 100644 index d27fc0172d7..00000000000 --- a/components/spi_flash/README.rst +++ /dev/null @@ -1 +0,0 @@ -See the spi_flash.rst in the programming guide folder for more details. diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index 9d00ae471f0..4f89b23ee3f 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -24,8 +24,9 @@ #include "esp_flash_chips/spi_flash_chip_driver.h" #include "esp_private/memspi_host_driver.h" #include "esp_private/esp_flash_internal.h" -#include "esp_flash_chips/spi_flash_defs.h" +#include "spi_flash_defs.h" #include "spi_flash_mmap.h" +#include "esp_flash.h" #if CONFIG_IDF_TARGET_ESP32S2 #include "esp_crypto_lock.h" // for locking flash encryption peripheral diff --git a/components/spi_flash/esp_flash_spi_init.c b/components/spi_flash/esp_flash_spi_init.c index bcee28e21fc..1acc8251217 100644 --- a/components/spi_flash/esp_flash_spi_init.c +++ b/components/spi_flash/esp_flash_spi_init.c @@ -21,7 +21,6 @@ #include "esp_private/startup_internal.h" #include "esp_spi_flash_counters.h" #include "esp_rom_spiflash.h" -#include "bootloader_flash.h" #include "esp_check.h" #include "esp_private/esp_clk_tree_common.h" #include "esp_clk_tree.h" @@ -33,6 +32,7 @@ #include "esp_flash.h" #include "esp_flash_spi_init.h" #include "esp_flash_chips/spi_flash_chip_driver.h" +#include "esp_flash_chips/esp_flash_types.h" #include "esp_private/memspi_host_driver.h" #include "esp_private/esp_flash_internal.h" #include "esp_private/spi_flash_os.h" @@ -472,7 +472,7 @@ static DRAM_ATTR esp_flash_t default_chip = { static void s_esp_flash_choose_correct_mode(memspi_host_config_t *cfg) { static const char *mode = FLASH_MODE_STRING; - if (bootloader_flash_is_octal_mode_enabled()) { + if (spi_flash_is_octal_mode_enabled()) { #if !CONFIG_ESPTOOLPY_FLASHMODE_OPI ESP_EARLY_LOGW(TAG, "Octal flash chip is using but %s mode is selected, will automatically switch to Octal mode", mode); cfg->octal_mode_en = 1; @@ -663,6 +663,7 @@ ESP_SYSTEM_INIT_FN(init_flash, CORE, BIT(0), 130) esp_mspi_register_isr(NULL); #endif //else register flash standalone ISR to deal with CPU / API flash access + return ESP_OK; } #endif // !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP diff --git a/components/spi_flash/include/esp_flash_chips/esp_flash_types.h b/components/spi_flash/include/esp_flash_chips/esp_flash_types.h index 5d274a5cf8e..d90c17f0ee3 100644 --- a/components/spi_flash/include/esp_flash_chips/esp_flash_types.h +++ b/components/spi_flash/include/esp_flash_chips/esp_flash_types.h @@ -87,7 +87,7 @@ struct esp_flash_t { spi_flash_host_inst_t* host; ///< Pointer to hardware-specific "host_driver" structure. Must be initialized before used. const spi_flash_chip_t *chip_drv; ///< Pointer to chip-model-specific "adapter" structure. If NULL, will be detected during initialisation. - const esp_flash_os_functions_t *os_func; ///< Pointer to os-specific hook structure. Call ``esp_flash_init_os_functions()`` to setup this field, after the host is properly initialized. + const esp_flash_os_functions_t *os_func; ///< Pointer to os-specific hook structure. void *os_func_data; ///< Pointer to argument for os-specific hooks. Left NULL and will be initialized with ``os_func``. esp_flash_io_mode_t read_mode; ///< Configured SPI flash read mode. Set before ``esp_flash_init`` is called. diff --git a/components/spi_flash/include/esp_flash_chips/spi_flash_defs.h b/components/spi_flash/include/esp_flash_chips/spi_flash_defs.h index 3d412a10bf0..8092abee56e 100644 --- a/components/spi_flash/include/esp_flash_chips/spi_flash_defs.h +++ b/components/spi_flash/include/esp_flash_chips/spi_flash_defs.h @@ -1,87 +1,9 @@ /* - * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ -#include "soc/soc_caps.h" - #pragma once -/* SPI commands (actual on-wire commands not SPI controller bitmasks) - Suitable for use with spi_flash_hal_common_command static function. -*/ -#define CMD_RDID 0x9F -#define CMD_RDUID 0x4B /* Read the flash unique ID*/ -#define CMD_WRSR 0x01 -#define SR_WIP (1<<0) /* Status register write-in-progress bit */ -#define SR_WREN (1<<1) /* Status register write enable bit */ -#define CMD_WRSR2 0x31 /* Not all SPI flash uses this command */ -#define CMD_WREN 0x06 -#define CMD_WRDI 0x04 -#define CMD_RDSR 0x05 -#define CMD_RDSR2 0x35 /* Not all SPI flash uses this command */ -#define CMD_RDSCUR 0x2B /* MXIC-specific, read security register */ -#define CMD_8READ 0xEC /* MXIC-specific, 8 I/O read */ -#define CMD_8DTRD 0xEE /* MXIC-specific, 8 I/O DTR read */ -#define CMD_RDFR 0x48 /* ISSI-specific, read function register */ - -#define CMD_FASTRD_QIO 0xEB -#define CMD_FASTRD_QIO_4B 0xEC -#define CMD_FASTRD_QUAD 0x6B -#define CMD_FASTRD_QUAD_4B 0x6C -#define CMD_FASTRD_DIO 0xBB -#define CMD_FASTRD_DIO_4B 0xBC -#define CMD_FASTRD_DUAL 0x3B -#define CMD_FASTRD_DUAL_4B 0x3C -#define CMD_FASTRD 0x0B -#define CMD_FASTRD_4B 0x0C -#define CMD_READ 0x03 /* Speed limited */ -#define CMD_READ_4B 0x13 /* Speed limited */ - -#define CMD_CHIP_ERASE 0xC7 -#define CMD_SECTOR_ERASE 0x20 -#define CMD_SECTOR_ERASE_4B 0x21 -#define CMD_LARGE_BLOCK_ERASE 0xD8 /* 64KB block erase command */ -#define CMD_LARGE_BLOCK_ERASE_4B 0xDC /* 64KB block erase command */ -#define CMD_PROGRAM_PAGE 0x02 -#define CMD_PROGRAM_PAGE_4B 0x12 -#define CMD_SUSPEND 0x75 -#define CMD_RESUME 0x7A -#define CMD_HPMEN 0xA3 /* Enable High Performance mode on flash */ -#define CMD_WRAP 0x77 -#define CMD_BURST_RD 0xC0 /* wrap(0x77) and burst read are functionally same. But commands and formats is different */ - -#define CMD_RST_EN 0x66 -#define CMD_RST_DEV 0x99 - -#define CMD_RDSFDP 0x5A /* Read the SFDP of the flash */ - -#define SPI_FLASH_DIO_DUMMY_BITLEN 4 -#define SPI_FLASH_QIO_DUMMY_BITLEN 6 -#define SPI_FLASH_DIO_ADDR_BITLEN 24 -#define SPI_FLASH_QIO_ADDR_BITLEN 24 -#define SPI_FLASH_QOUT_ADDR_BITLEN 24 -#define SPI_FLASH_QOUT_DUMMY_BITLEN 8 -#define SPI_FLASH_DOUT_ADDR_BITLEN 24 -#define SPI_FLASH_DOUT_DUMMY_BITLEN 8 -#define SPI_FLASH_FASTRD_ADDR_BITLEN 24 -#define SPI_FLASH_FASTRD_DUMMY_BITLEN 8 -#define SPI_FLASH_SLOWRD_ADDR_BITLEN 24 -#define SPI_FLASH_SLOWRD_DUMMY_BITLEN 0 -#define SPI_FLASH_OPISTR_ADDR_BITLEN 32 -#define SPI_FLASH_OPISTR_DUMMY_BITLEN 20 -#define SPI_FLASH_OPIDTR_ADDR_BITLEN 32 -#define SPI_FLASH_OPIDTR_DUMMY_BITLEN 40 -#define SPI_FLASH_QIO_HPM_DUMMY_BITLEN 10 -#define SPI_FLASH_DIO_HPM_DUMMY_BITLEN 8 - -// Flash vendors. -#define SPI_FLASH_GD 0xC8 -#define SPI_FLASH_ISSI 0x9D -#define SPI_FLASH_MXIC 0xC2 -#define SPI_FLASH_XMC_1 0x20 -#define SPI_FLASH_XMC_2 0x46 -#define SPI_FLASH_WINBOND 0xEF -#define SPI_FLASH_TH 0xCD -#define SPI_FLASH_BY 0x68 +#include diff --git a/components/spi_flash/include/esp_flash_err.h b/components/spi_flash/include/esp_flash_err.h index 406dae10d89..8f255ed6cf7 100644 --- a/components/spi_flash/include/esp_flash_err.h +++ b/components/spi_flash/include/esp_flash_err.h @@ -30,6 +30,8 @@ enum { }; //The ROM code has already taken 1 and 2, to avoid possible conflicts, start from 3. +#define ESP_ERR_FLASH_OP_FAIL (ESP_ERR_FLASH_BASE+1) ///< aligned with rom +#define ESP_ERR_FLASH_OP_TIMEOUT (ESP_ERR_FLASH_BASE+2) ///< aligned with rom #define ESP_ERR_FLASH_NOT_INITIALISED (ESP_ERR_FLASH_BASE+3) ///< esp_flash_chip_t structure not correctly initialised by esp_flash_init(). #define ESP_ERR_FLASH_UNSUPPORTED_HOST (ESP_ERR_FLASH_BASE+4) ///< Requested operation isn't supported via this host SPI bus (chip->spi field). #define ESP_ERR_FLASH_UNSUPPORTED_CHIP (ESP_ERR_FLASH_BASE+5) ///< Requested operation isn't supported by this model of SPI flash chip. diff --git a/components/spi_flash/include/esp_private/esp_flash_internal.h b/components/spi_flash/include/esp_private/esp_flash_internal.h index e3523c0e3df..a8d105e91fe 100644 --- a/components/spi_flash/include/esp_private/esp_flash_internal.h +++ b/components/spi_flash/include/esp_private/esp_flash_internal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,19 +20,44 @@ extern "C" { #endif +//-----------------------------ESP FLASH UTILITIES-------------------------------------// +/** + * @brief Initialize main flash + * @note Only call this function to initialize the main flash (flash chip on SPI1 CS0). + * + * @param chip Pointer to main SPI flash(SPI1 CS0) chip to use. + * @return ESP_OK on success, or a flash error code if initialisation fails. + */ +esp_err_t esp_flash_init_main(esp_flash_t *chip); -/** @brief Initialise the default SPI flash chip +/** + * @brief Initialize the bus lock on the SPI1 bus. Should be called if drivers (including esp_flash) + * wants to use SPI1 bus. + * + * @note When using legacy spi flash API, the bus lock will not be available on SPI1 bus. + * + * @return esp_err_t always ESP_OK. + */ +esp_err_t esp_flash_app_init_os_functions(void); + +#if CONFIG_SPI_FLASH_ROM_IMPL +/** + * @brief Initialize ROM API functions structure + * + * This function initializes the ROM API functions structure, either by pointing + * to a custom structure or by patching the ROM structure in RAM. + */ +void esp_flash_rom_api_funcs_init(void); +#endif // CONFIG_SPI_FLASH_ROM_IMPL + +//-----------------------------ESP FLASH OS LAYER-------------------------------------// +/** + * @brief Initialise the default SPI flash chip * * Called by OS startup code. You do not need to call this in your own applications. */ esp_err_t esp_flash_init_default_chip(void); -/** - * @brief Initialize main flash - * @param chip Pointer to main SPI flash(SPI1 CS0) chip to use.. - */ -esp_err_t esp_flash_init_main(esp_flash_t *chip); - /** * Enable OS-level SPI flash protections in IDF * @@ -76,16 +101,6 @@ esp_err_t esp_flash_init_os_functions(esp_flash_t *chip, int host_id, spi_bus_lo */ esp_err_t esp_flash_deinit_os_functions(esp_flash_t* chip, spi_bus_lock_dev_handle_t* out_dev_handle); -/** - * @brief Initialize the bus lock on the SPI1 bus. Should be called if drivers (including esp_flash) - * wants to use SPI1 bus. - * - * @note When using legacy spi flash API, the bus lock will not be available on SPI1 bus. - * - * @return esp_err_t always ESP_OK. - */ -esp_err_t esp_flash_app_init_os_functions(void); - /** * Initialize OS-level functions for the main flash chip. * @@ -126,15 +141,45 @@ esp_err_t esp_flash_app_disable_os_functions(esp_flash_t* chip); */ esp_err_t esp_flash_set_dangerous_write_protection(esp_flash_t *chip, const bool protect); -#if CONFIG_SPI_FLASH_ROM_IMPL /** - * @brief Initialize ROM API functions structure - * - * This function initializes the ROM API functions structure, either by pointing - * to a custom structure or by patching the ROM structure in RAM. + * @brief Partition operations */ -void esp_flash_rom_api_funcs_init(void); -#endif // CONFIG_SPI_FLASH_ROM_IMPL +typedef struct esp_flash_partition_ops_s { + /** + * @brief Check if the main flash region is safe to write/erase. + * + * @param[in] start_addr Start address of the region + * @param[in] size Size of the region + * @return true if the region is safe to write/erase, false otherwise + */ + bool (*check_main_flash_region_safe)(size_t start_addr, size_t size); + + /** + * @brief Check if a region is writable + * + * @param[in] start_addr Start address of the region + * @param[in] size Size of the region + * @return true if the region is writable/eraseable, false otherwise + */ + bool (*check_region_writable)(size_t start_addr, size_t size); +} esp_flash_partition_ops_t; + +/** + * @brief Register a callback to determine whether a flash region is safe to write/erase. + * + * This allows upper-layer components (e.g. esp_partition) to inject partition-aware + * write protection logic without creating a circular dependency. + * + * The main flash chip must always register valid ops. For external flash chips + * calling this is optional; if not called, partition protection stays disabled + * (the default set by the OS-functions constructor). + * + * @param chip Pointer to the flash chip. Must not be NULL. + * @param ops Partition operations. Must not be NULL and both callbacks must be set. + * @return ESP_OK on success, ESP_ERR_INVALID_ARG if chip or ops is invalid, + * ESP_ERR_INVALID_STATE if the flash OS functions are not initialized. + */ +esp_err_t esp_flash_register_partition_ops(esp_flash_t *chip, esp_flash_partition_ops_t *ops); #ifdef __cplusplus } diff --git a/components/spi_flash/include/esp_private/spi_flash_freq_limit_cbs.h b/components/spi_flash/include/esp_private/spi_flash_freq_limit_cbs.h index 3e95f36965a..c35387e9eb3 100644 --- a/components/spi_flash/include/esp_private/spi_flash_freq_limit_cbs.h +++ b/components/spi_flash/include/esp_private/spi_flash_freq_limit_cbs.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,7 +7,6 @@ #pragma once #include "sdkconfig.h" -#include "esp_flash.h" #include "esp_attr.h" #ifdef __cplusplus diff --git a/components/spi_flash/include/spi_flash_mmap.h b/components/spi_flash/include/spi_flash_mmap.h index c05ae3ee296..2498002eaea 100644 --- a/components/spi_flash/include/spi_flash_mmap.h +++ b/components/spi_flash/include/spi_flash_mmap.h @@ -21,14 +21,12 @@ #include "esp_attr.h" #include "sdkconfig.h" #include "esp_spi_flash_counters.h" +#include "hal/esp_flash_err.h" #ifdef __cplusplus extern "C" { #endif -#define ESP_ERR_FLASH_OP_FAIL (ESP_ERR_FLASH_BASE + 1) -#define ESP_ERR_FLASH_OP_TIMEOUT (ESP_ERR_FLASH_BASE + 2) - #define SPI_FLASH_SEC_SIZE 4096 /**< SPI Flash sector size */ #define SPI_FLASH_MMU_PAGE_SIZE CONFIG_MMU_PAGE_SIZE /**< Flash cache MMU mapping page size */ @@ -166,7 +164,6 @@ void spi_flash_mmap_dump(void); */ uint32_t spi_flash_mmap_get_free_pages(spi_flash_mmap_memory_t memory); - #define SPI_FLASH_CACHE2PHYS_FAIL UINT32_MAX /* -#include "esp_flash_chips/spi_flash_defs.h" +#include "spi_flash_defs.h" #include "esp_flash_chips/spi_flash_chip_generic.h" #include "esp_flash_chips/spi_flash_chip_gd.h" diff --git a/components/spi_flash/spi_flash_chip_drivers.c b/components/spi_flash/spi_flash_chip_drivers.c index 24f81b1d04a..b2e144aa3b0 100644 --- a/components/spi_flash/spi_flash_chip_drivers.c +++ b/components/spi_flash/spi_flash_chip_drivers.c @@ -8,7 +8,7 @@ #include "sdkconfig.h" #include "esp_log.h" -#include "esp_flash_chips/spi_flash_defs.h" +#include "spi_flash_defs.h" #include "esp_flash_chips/spi_flash_chip_driver.h" #include "esp_flash_chips/spi_flash_chip_generic.h" #include "esp_flash_chips/spi_flash_chip_issi.h" diff --git a/components/spi_flash/spi_flash_chip_gd.c b/components/spi_flash/spi_flash_chip_gd.c index 4948a192b22..dbca594143e 100644 --- a/components/spi_flash/spi_flash_chip_gd.c +++ b/components/spi_flash/spi_flash_chip_gd.c @@ -10,7 +10,7 @@ #include "esp_log.h" #include "sdkconfig.h" -#include "esp_flash_chips/spi_flash_defs.h" +#include "spi_flash_defs.h" #include "esp_flash_chips/spi_flash_chip_generic.h" #include "esp_flash_chips/spi_flash_chip_gd.h" diff --git a/components/spi_flash/spi_flash_chip_generic.c b/components/spi_flash/spi_flash_chip_generic.c index 05133b6b75c..e0bd390d88f 100644 --- a/components/spi_flash/spi_flash_chip_generic.c +++ b/components/spi_flash/spi_flash_chip_generic.c @@ -12,7 +12,7 @@ #include "esp_rom_caps.h" #include "hal/spi_flash_encrypt_hal.h" -#include "esp_flash_chips/spi_flash_defs.h" +#include "spi_flash_defs.h" #include "esp_flash_chips/spi_flash_chip_generic.h" #include "esp_private/spi_flash_os.h" diff --git a/components/spi_flash/spi_flash_chip_issi.c b/components/spi_flash/spi_flash_chip_issi.c index 20b84e71f5b..11aef0e9a2d 100644 --- a/components/spi_flash/spi_flash_chip_issi.c +++ b/components/spi_flash/spi_flash_chip_issi.c @@ -5,7 +5,7 @@ */ #include -#include "esp_flash_chips/spi_flash_defs.h" +#include "spi_flash_defs.h" #include "esp_flash_chips/spi_flash_chip_generic.h" #include "esp_flash_chips/spi_flash_chip_issi.h" diff --git a/components/spi_flash/spi_flash_chip_mxic.c b/components/spi_flash/spi_flash_chip_mxic.c index cd49f8052e6..35c520a9679 100644 --- a/components/spi_flash/spi_flash_chip_mxic.c +++ b/components/spi_flash/spi_flash_chip_mxic.c @@ -8,7 +8,7 @@ #include "esp_log.h" #include "hal/spi_flash_hal.h" -#include "esp_flash_chips/spi_flash_defs.h" +#include "spi_flash_defs.h" #include "esp_flash_chips/spi_flash_chip_generic.h" /* Driver for MXIC flash chip */ diff --git a/components/spi_flash/spi_flash_chip_mxic_opi.c b/components/spi_flash/spi_flash_chip_mxic_opi.c index d8ba7a72a5a..7293b038458 100644 --- a/components/spi_flash/spi_flash_chip_mxic_opi.c +++ b/components/spi_flash/spi_flash_chip_mxic_opi.c @@ -10,7 +10,7 @@ #include // For MIN/MAX #include "hal/spi_flash_hal.h" -#include "esp_flash_chips/spi_flash_defs.h" +#include "spi_flash_defs.h" #include "esp_flash_chips/spi_flash_chip_generic.h" #define CMD_OPI_FLASH_MXIC(cmd) ((((~(cmd) & 0xff) << 8)) | ((cmd) & 0xff)) diff --git a/components/spi_flash/spi_flash_chip_th.c b/components/spi_flash/spi_flash_chip_th.c index 80342fe76db..c8e92bb0970 100644 --- a/components/spi_flash/spi_flash_chip_th.c +++ b/components/spi_flash/spi_flash_chip_th.c @@ -5,7 +5,7 @@ */ #include -#include "esp_flash_chips/spi_flash_defs.h" +#include "spi_flash_defs.h" #include "esp_flash_chips/spi_flash_chip_generic.h" esp_err_t spi_flash_chip_th_probe(esp_flash_t *chip, uint32_t flash_id) diff --git a/components/spi_flash/spi_flash_chip_winbond.c b/components/spi_flash/spi_flash_chip_winbond.c index 3f826e5656d..dc1bf36806f 100644 --- a/components/spi_flash/spi_flash_chip_winbond.c +++ b/components/spi_flash/spi_flash_chip_winbond.c @@ -9,7 +9,7 @@ #include // For MIN/MAX #include "esp_log.h" -#include "esp_flash_chips/spi_flash_defs.h" +#include "spi_flash_defs.h" #include "esp_flash_chips/spi_flash_chip_generic.h" diff --git a/components/spi_flash/spi_flash_os_func_app.c b/components/spi_flash/spi_flash_os_func_app.c index b38af2aefb2..bc8a64be8d2 100644 --- a/components/spi_flash/spi_flash_os_func_app.c +++ b/components/spi_flash/spi_flash_os_func_app.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include #include //For max/min @@ -19,9 +20,9 @@ #include "esp_flash.h" #include "esp_flash_chips/esp_flash_types.h" -#include "esp_flash_partitions.h" #include "esp_private/spi_flash_os.h" +#include "esp_private/esp_flash_internal.h" #include "esp_private/cache_utils.h" #include "esp_private/flash_mmap.h" #include "esp_private/spi_share_hw_ctrl.h" @@ -61,7 +62,10 @@ typedef struct { spi_bus_lock_dev_handle_t dev_lock; uint32_t no_protect : 1; //to decide whether to check protected region (for the main chip) or not. uint32_t current_op_type : 3; //Whether the mmap lock is already taken, only for SPI1. - uint32_t reserved : 28; + uint32_t require_partition_protection : 1; // Only the main flash must have partition-aware protection callbacks. + uint32_t reserved : 27; + bool (*check_main_flash_region_safe)(size_t start_addr, size_t size); ///< Callback to check if the main flash region is safe to write/erase. Registered by upper layer (e.g. esp_partition). + bool (*check_region_writable)(size_t start_addr, size_t size); ///< Callback to check if a region is writable/eraseable. Registered by upper layer (e.g. esp_partition). uint32_t acquired_since_us; // Time since last explicit yield() uint32_t released_since_us; // Time since last end() (implicit yield) uint32_t start_flags; // Flags passed to start() function, used to determine if freq_limit was called @@ -384,11 +388,24 @@ static void release_buffer_malloc(void* arg, void *temp_buf) static esp_err_t main_flash_region_protected(void* arg, size_t start_addr, size_t size) { - if (!esp_partition_is_flash_region_writable(start_addr, size)) { + app_func_arg_t *func_arg = (app_func_arg_t *)arg; + if (!func_arg->require_partition_protection) { + /** + * - Main flash always register partition protection callbacks. + * - External flash chips on SPI1 may omit them + * - because they are not governed by the main flash partition table + * This case just return OK + */ + return ESP_OK; + } + assert(func_arg->check_region_writable != NULL); + assert(func_arg->check_main_flash_region_safe != NULL); + if (!func_arg->check_region_writable(start_addr, size)) { return ESP_ERR_NOT_ALLOWED; } #if !CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED - if (((app_func_arg_t*)arg)->no_protect || esp_partition_main_flash_region_safe(start_addr, size)) { + if (func_arg->no_protect || + func_arg->check_main_flash_region_safe(start_addr, size)) { //ESP_OK = 0, also means protected==0 return ESP_OK; } else { @@ -474,13 +491,15 @@ esp_err_t esp_flash_init_os_functions(esp_flash_t *chip, int host_id, spi_bus_lo chip->os_func = &esp_flash_spi23_default_os_functions; break; default: + free(chip->os_func_data); + chip->os_func_data = NULL; return ESP_ERR_INVALID_ARG; - break; } *(app_func_arg_t*) chip->os_func_data = (app_func_arg_t) { .dev_lock = dev_handle, .no_protect = true, // This is OK because this code path isn't used for the main flash chip which requires `no_protect = false` + .require_partition_protection = false, }; return ESP_OK; @@ -537,12 +556,32 @@ esp_err_t esp_flash_app_enable_os_functions(esp_flash_t* chip) main_flash_arg = (app_func_arg_t) { .dev_lock = g_spi_lock_main_flash_dev, .no_protect = false, // Required for the main flash chip + .require_partition_protection = true, }; chip->os_func = &esp_flash_spi1_default_os_functions; chip->os_func_data = &main_flash_arg; return ESP_OK; } +esp_err_t esp_flash_register_partition_ops(esp_flash_t *chip, esp_flash_partition_ops_t *ops) +{ + // Error checks first + if (chip == NULL || ops == NULL || + ops->check_region_writable == NULL || ops->check_main_flash_region_safe == NULL) { + return ESP_ERR_INVALID_ARG; + } + // os functions (and thus os_func_data) must be initialized before registering ops + if (chip->os_func_data == NULL) { + return ESP_ERR_INVALID_STATE; + } + + app_func_arg_t *func_arg = (app_func_arg_t *)chip->os_func_data; + func_arg->check_region_writable = ops->check_region_writable; + func_arg->check_main_flash_region_safe = ops->check_main_flash_region_safe; + func_arg->require_partition_protection = true; + return ESP_OK; +} + esp_err_t esp_flash_set_dangerous_write_protection(esp_flash_t *chip, const bool protect) { #if !CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED diff --git a/components/spi_flash/spi_flash_os_func_noos.c b/components/spi_flash/spi_flash_os_func_noos.c index 9e0096b35c4..3151c722daa 100644 --- a/components/spi_flash/spi_flash_os_func_noos.c +++ b/components/spi_flash/spi_flash_os_func_noos.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,6 +16,7 @@ #include "esp_flash.h" #include "esp_flash_chips/esp_flash_types.h" +#include "esp_private/esp_flash_internal.h" static IRAM_ATTR esp_err_t start(void *arg, uint32_t flags) { diff --git a/components/spi_flash/test_apps/.build-test-rules.yml b/components/spi_flash/test_apps/.build-test-rules.yml index fe1f7dee90d..acb0594709d 100644 --- a/components/spi_flash/test_apps/.build-test-rules.yml +++ b/components/spi_flash/test_apps/.build-test-rules.yml @@ -4,9 +4,9 @@ components/spi_flash/test_apps/esp_flash: depends_filepatterns: - components/bootloader_support/bootloader_flash/**/* depends_components: - - *common_components - esp_mm - esp_psram + - esp_mspi - spi_flash - esp_driver_gpio - esp_driver_spi @@ -19,14 +19,14 @@ components/spi_flash/test_apps/esp_flash_blockdev: temporary: false reason: should be sufficient to test on one Xtensa and one RISC-V target depends_components: - - *common_components + - esp_mspi - spi_flash components/spi_flash/test_apps/esp_flash_freq_limit: enable: - if: IDF_TARGET == "esp32c5" depends_components: - - *common_components + - esp_mspi - spi_flash - esp_pm - esp_driver_gptimer @@ -34,7 +34,7 @@ components/spi_flash/test_apps/esp_flash_freq_limit: components/spi_flash/test_apps/esp_flash_stress: depends_components: - - *common_components + - esp_mspi - esp_mm - spi_flash - esp_hal_mspi @@ -51,14 +51,14 @@ components/spi_flash/test_apps/flash_encryption: reason: No runners # IDF-5634 depends_components: - - *common_components + - esp_mspi - esp_mm - spi_flash - esp_hal_mspi components/spi_flash/test_apps/flash_mmap: depends_components: - - *common_components + - esp_mspi - esp_mm - spi_flash - esp_hal_mspi @@ -82,7 +82,7 @@ components/spi_flash/test_apps/flash_suspend: temporary: true reason: lack of runners, or we don't trust generic runner must support suspend depends_components: - - *common_components + - esp_mspi - spi_flash - esp_driver_gptimer - esp_hal_mspi @@ -94,7 +94,7 @@ components/spi_flash/test_apps/mspi_test: depends_filepatterns: - components/bootloader_support/bootloader_flash/**/* depends_components: - - *common_components + - esp_mspi - esp_mm - esp_psram - spi_flash @@ -102,8 +102,3 @@ components/spi_flash/test_apps/mspi_test: - esp_driver_spi - esptool_py # Some flash related kconfigs are listed here. - esp_hal_mspi - -components/spi_flash/test_apps/no_flash_delay: - disable: - - if: IDF_TARGET not in ["esp32c3"] - reason: Testing on a single target is sufficient diff --git a/components/spi_flash/test_apps/components/test_flash_utils/test_flash_utils.c b/components/spi_flash/test_apps/components/test_flash_utils/test_flash_utils.c index af643720b17..8682421f02d 100644 --- a/components/spi_flash/test_apps/components/test_flash_utils/test_flash_utils.c +++ b/components/spi_flash/test_apps/components/test_flash_utils/test_flash_utils.c @@ -22,7 +22,7 @@ const esp_partition_t *get_test_flash_partition(void) { /* This finds "flash_test" partition defined in custom partitions.csv */ const esp_partition_t *result = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, - ESP_PARTITION_SUBTYPE_ANY, "flash_test"); + ESP_PARTITION_SUBTYPE_ANY, "flash_test"); assert(result != NULL); /* means partition table set wrong */ return result; } @@ -101,7 +101,8 @@ err: return ret; } -const esp_partition_t * spi_flash_suspend_test_find_last_partition(void) { +const esp_partition_t * spi_flash_suspend_test_find_last_partition(void) +{ const esp_partition_t *last_partition = NULL; esp_partition_iterator_t it = esp_partition_find(ESP_PARTITION_TYPE_ANY, ESP_PARTITION_SUBTYPE_ANY, NULL); diff --git a/components/spi_flash/test_apps/esp_flash/main/test_app_main.c b/components/spi_flash/test_apps/esp_flash/main/test_app_main.c index dbe134b96a5..dca1bead687 100644 --- a/components/spi_flash/test_apps/esp_flash/main/test_app_main.c +++ b/components/spi_flash/test_apps/esp_flash/main/test_app_main.c @@ -30,13 +30,11 @@ void app_main(void) // | `---..-' || | --' | |` | |\ '-' |.-' `)| | | | // `------'`-----' `--' `--' `--' `--`--'`----' `--' `--' - printf(",------. ,---. ,------. ,------.,--. ,--. \n"); printf("| .---'' .-' | .--. ' | .---'| | ,--,--. ,---. | ,---. \n"); printf("| `--, `. `-. | '--' | | `--, | |' ,-. |( .-' | .-. | \n"); printf("| `---..-' || | --' | |` | |\\ '-' |.-' `)| | | | \n"); printf("`------'`-----' `--' `--' `--' `--`--'`----' `--' `--' \n"); - unity_run_menu(); } diff --git a/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_def.h b/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_def.h index 7a671d0b452..5f44086ab2b 100644 --- a/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_def.h +++ b/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_def.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -120,7 +120,6 @@ typedef void (*flash_test_func_t)(const esp_partition_t *part); LOG_ERASE(bus, erase_2, chip); \ } while (0) - #if defined(CONFIG_SPIRAM) //SPI1 CS1 occupied by PSRAM #define BYPASS_MULTIPLE_CHIP 1 @@ -182,77 +181,77 @@ static const char TAG[] = "test_esp_flash"; #if CONFIG_IDF_TARGET_ESP32 flashtest_config_t config_list[] = { - FLASHTEST_CONFIG_COMMON, - /* current runner doesn't have a flash on SPI2_HOST */ - // { - // .io_mode = TEST_SPI_READ_MODE, - // .freq_mhz = TEST_SPI_SPEED, - // .host_id = SPI2_HOST, - // .cs_id = 0, - // // uses GPIO matrix on esp32s2 regardless if FORCE_GPIO_MATRIX - // .cs_io_num = SPI2_PIN_NUM_CS, - // .input_delay_ns = 20, - // }, - { - .io_mode = TEST_SPI_READ_MODE, - .freq_mhz = TEST_SPI_SPEED, - .host_id = SPI3_HOST, - .cs_id = 0, - .cs_io_num = SPI3_PIN_NUM_CS, - .input_delay_ns = 0, - }, -}; + FLASHTEST_CONFIG_COMMON, + /* current runner doesn't have a flash on SPI2_HOST */ + // { + // .io_mode = TEST_SPI_READ_MODE, + // .freq_mhz = TEST_SPI_SPEED, + // .host_id = SPI2_HOST, + // .cs_id = 0, + // // uses GPIO matrix on esp32s2 regardless if FORCE_GPIO_MATRIX + // .cs_io_num = SPI2_PIN_NUM_CS, + // .input_delay_ns = 20, + // }, + { + .io_mode = TEST_SPI_READ_MODE, + .freq_mhz = TEST_SPI_SPEED, + .host_id = SPI3_HOST, + .cs_id = 0, + .cs_io_num = SPI3_PIN_NUM_CS, + .input_delay_ns = 0, + }, + }; #elif CONFIG_IDF_TARGET_ESP32S2 flashtest_config_t config_list[] = { - FLASHTEST_CONFIG_COMMON, - { - .io_mode = TEST_SPI_READ_MODE, - .freq_mhz = TEST_SPI_SPEED, - .host_id = SPI2_HOST, - .cs_id = 0, - .cs_io_num = SPI2_PIN_NUM_CS, - .input_delay_ns = 0, - }, - { - .io_mode = TEST_SPI_READ_MODE, - .freq_mhz = TEST_SPI_SPEED, - .host_id = SPI3_HOST, - .cs_id = 0, - // uses GPIO matrix on esp32s2 regardless of FORCE_GPIO_MATRIX - .cs_io_num = SPI2_PIN_NUM_CS, - .input_delay_ns = 0, - }, -}; + FLASHTEST_CONFIG_COMMON, + { + .io_mode = TEST_SPI_READ_MODE, + .freq_mhz = TEST_SPI_SPEED, + .host_id = SPI2_HOST, + .cs_id = 0, + .cs_io_num = SPI2_PIN_NUM_CS, + .input_delay_ns = 0, + }, + { + .io_mode = TEST_SPI_READ_MODE, + .freq_mhz = TEST_SPI_SPEED, + .host_id = SPI3_HOST, + .cs_id = 0, + // uses GPIO matrix on esp32s2 regardless of FORCE_GPIO_MATRIX + .cs_io_num = SPI2_PIN_NUM_CS, + .input_delay_ns = 0, + }, + }; #elif CONFIG_IDF_TARGET_ESP32S3 flashtest_config_t config_list[] = { - /* No SPI1 CS1 flash on esp32S3 test */ - { - /* no need to init */ - .host_id = -1, - }, - { - .io_mode = TEST_SPI_READ_MODE, - .freq_mhz = TEST_SPI_SPEED, - .host_id = SPI2_HOST, - .cs_id = 0, - .cs_io_num = SPI2_PIN_NUM_CS, - .input_delay_ns = 0, - }, -}; + /* No SPI1 CS1 flash on esp32S3 test */ + { + /* no need to init */ + .host_id = -1, + }, + { + .io_mode = TEST_SPI_READ_MODE, + .freq_mhz = TEST_SPI_SPEED, + .host_id = SPI2_HOST, + .cs_id = 0, + .cs_io_num = SPI2_PIN_NUM_CS, + .input_delay_ns = 0, + }, + }; #else flashtest_config_t config_list[] = { - /* No SPI1 CS1 flash on esp32c3 test */ - { - /* no need to init */ - .host_id = -1, - }, - { - .io_mode = TEST_SPI_READ_MODE, - .freq_mhz = TEST_SPI_SPEED, - .host_id = SPI2_HOST, - .cs_id = 0, - .cs_io_num = SPI2_PIN_NUM_CS, - .input_delay_ns = 0, - }, -}; + /* No SPI1 CS1 flash on esp32c3 test */ + { + /* no need to init */ + .host_id = -1, + }, + { + .io_mode = TEST_SPI_READ_MODE, + .freq_mhz = TEST_SPI_SPEED, + .host_id = SPI2_HOST, + .cs_id = 0, + .cs_io_num = SPI2_PIN_NUM_CS, + .input_delay_ns = 0, + }, + }; #endif diff --git a/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c b/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c index 4d15f8ff3b3..0d078d969a7 100644 --- a/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c +++ b/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c @@ -12,7 +12,9 @@ #include #include "esp_flash.h" +#include "esp_flash_chips/esp_flash_types.h" // For esp_flash_t structure definition #include "esp_private/spi_common_internal.h" +#include "esp_private/spi_flash_os.h" #include "esp_flash_spi_init.h" #include "esp_private/memspi_host_driver.h" #include @@ -31,7 +33,6 @@ #include "esp_rom_sys.h" #include "esp_timer.h" #include "test_esp_flash_def.h" -#include "esp_private/spi_flash_os.h" #include "ccomp_timer.h" static uint8_t sector_buf[4096]; @@ -229,7 +230,7 @@ static void flash_test_func(flash_test_func_t func, int test_num) { esp_log_level_set("gpio", ESP_LOG_NONE); for (int i = 0; i < test_num; i++) { - ESP_LOGI(TAG, "Testing config %u/%u", i+1, test_num); + ESP_LOGI(TAG, "Testing config %u/%u", i + 1, test_num); flash_test_core(func, &config_list[i]); } ESP_LOGI(TAG, "Completed %u configs", test_num); @@ -264,7 +265,7 @@ static uint32_t erase_test_region(const esp_partition_t *part, int num_sectors) bzero(sector_buf, sizeof(sector_buf)); printf("Erase @ 0x%lx...\n", offs); - TEST_ASSERT_EQUAL_HEX32(ESP_OK, esp_flash_erase_region(chip, offs, num_sectors * 4096) ); + TEST_ASSERT_EQUAL_HEX32(ESP_OK, esp_flash_erase_region(chip, offs, num_sectors * 4096)); printf("Verify erased...\n"); for (int i = 0; i < num_sectors; i++) { @@ -291,12 +292,12 @@ void test_simple_read_write(const esp_partition_t* part) } printf("Write %p...\n", (void *)offs); - TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, sector_buf, offs, sizeof(sector_buf)) ); + TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, sector_buf, offs, sizeof(sector_buf))); bzero(sector_buf, sizeof(sector_buf)); printf("Read back...\n"); - TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read(chip, sector_buf, offs, sizeof(sector_buf)) ); + TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read(chip, sector_buf, offs, sizeof(sector_buf))); printf("Buffer starts 0x%02x 0x%02x 0x%02x 0x%02x\n", sector_buf[0], sector_buf[1], sector_buf[2], sector_buf[3]); @@ -317,13 +318,13 @@ void test_unaligned_read_write(const esp_partition_t* part) const char *msg = "i am a message"; TEST_ASSERT(strlen(msg) + 1 % 4 != 0); - TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, msg, offs + 1, strlen(msg) + 1) ); + TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, msg, offs + 1, strlen(msg) + 1)); char buf[strlen(msg) + 1]; memset(buf, 0xEE, sizeof(buf)); - TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read(chip, buf, offs + 1, strlen(msg) + 1) ); + TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read(chip, buf, offs + 1, strlen(msg) + 1)); TEST_ASSERT_EQUAL_STRING_LEN(msg, buf, strlen(msg)); TEST_ASSERT(memcmp(buf, msg, strlen(msg) + 1) == 0); } @@ -340,14 +341,14 @@ void test_single_read_write(const esp_partition_t* part) srand(seed); for (unsigned v = 0; v < 512; v++) { uint32_t data = rand(); - TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_flash_write(chip, &data, offs + v, 1) ); + TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_flash_write(chip, &data, offs + v, 1)); } srand(seed); for (unsigned v = 0; v < 512; v++) { uint8_t readback; uint32_t data = rand(); - TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_flash_read(chip, &readback, offs + v, 1) ); + TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_flash_read(chip, &readback, offs + v, 1)); TEST_ASSERT_EQUAL_HEX8(data, readback); } } @@ -355,7 +356,6 @@ void test_single_read_write(const esp_partition_t* part) TEST_CASE_FLASH("SPI flash single byte reads/writes", test_single_read_write); TEST_CASE_MULTI_FLASH("SPI flash single byte reads/writes", test_single_read_write); - /* this test is notable because it generates a lot of unaligned reads/writes, and also reads/writes across both a sector boundary & many page boundaries. */ @@ -370,14 +370,14 @@ void test_three_byte_read_write(const esp_partition_t* part) srand(seed); for (uint32_t v = 0; v < 86; v++) { uint32_t data = rand(); - TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, &data, offs + 3 * v, 3) ); + TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, &data, offs + 3 * v, 3)); } srand(seed); for (uint32_t v = 0; v < 1; v++) { uint32_t readback; uint32_t data = rand(); - TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read(chip, &readback, offs + 3 * v, 3) ); + TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read(chip, &readback, offs + 3 * v, 3)); TEST_ASSERT_EQUAL_HEX32(data & 0xFFFFFF, readback & 0xFFFFFF); } } @@ -478,7 +478,7 @@ void test_flash_wrap(const esp_partition_t* part) wrap_buf[i] = rand(); } printf("Write %p...\n", (void *)offs); - TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, wrap_buf, offs + 3, sizeof(wrap_buf)) ); + TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, wrap_buf, offs + 3, sizeof(wrap_buf))); bzero(wrap_buf, sizeof(wrap_buf)); @@ -542,7 +542,7 @@ static bool is_mxic_chip(esp_flash_t* chip) uint32_t flash_id; esp_err_t ret = esp_flash_read_chip_id(chip, &flash_id); TEST_ESP_OK(ret); - return (spi_flash_chip_mxic_probe(chip, flash_id)==ESP_OK); + return (spi_flash_chip_mxic_probe(chip, flash_id) == ESP_OK); } IRAM_ATTR NOINLINE_ATTR static void test_toggle_qe(const esp_partition_t* part) @@ -562,7 +562,7 @@ IRAM_ATTR NOINLINE_ATTR static void test_toggle_qe(const esp_partition_t* part) for (int i = 0; i < 4; i ++) { esp_rom_printf(DRAM_STR("write qe: %" PRIu32 "->%" PRIu32 "\n"), qe, !qe); qe = !qe; - chip->read_mode = qe? SPI_FLASH_QOUT: SPI_FLASH_SLOWRD; + chip->read_mode = qe ? SPI_FLASH_QOUT : SPI_FLASH_SLOWRD; ret = esp_flash_set_io_mode(chip, qe); if (allow_failure && !qe && ret == ESP_ERR_FLASH_NO_RESPONSE) { //allows clear qe failure for Winbond chips @@ -609,7 +609,7 @@ void test_permutations_part(const flashtest_config_t* config, esp_partition_t* p { int clock_index = 0; if (config->host_id != -1) { - while (clock_index < sizeof(flash_frequency_table)/sizeof(uint8_t)) { + while (clock_index < sizeof(flash_frequency_table) / sizeof(uint8_t)) { uint8_t speed = flash_frequency_table[clock_index]; //test io_mode in the inner loop to test QE set/clear function, since //the io mode will switch frequently. @@ -686,16 +686,20 @@ void test_permutations_chip(const flashtest_config_t* config) } for (int i = 0; i < 2; i++) { - if (part[i].size == 0) continue; + if (part[i].size == 0) { + continue; + } write_large_buffer(&part[i], source_buf, length); } teardown_test_chip(chip); for (int i = 0; i < 2; i++) { - if (part[i].size == 0) continue; + if (part[i].size == 0) { + continue; + } - part[i].flash_chip = (esp_flash_t*)-1; + part[i].flash_chip = (esp_flash_t*) -1; ESP_LOGI(TAG, "Testing address 0x%08lX...", part[i].address); test_permutations_part(config, &part[i], source_buf, length); } @@ -717,7 +721,6 @@ TEST_CASE("SPI flash test reading with all speed/mode permutations, 3 chips", "[ } #endif - static void test_write_large_const_buffer(const esp_partition_t* part) { test_write_large_buffer(part, large_const_buffer, sizeof(large_const_buffer)); @@ -744,10 +747,10 @@ static void write_large_buffer(const esp_partition_t *part, const uint8_t *sourc esp_flash_t* chip = part->flash_chip; printf("Writing chip %p %p, %u bytes from source %p\n", chip, (void*)part->address, length, source); - ESP_ERROR_CHECK( esp_flash_erase_region(chip, part->address, (length + part->erase_size) & ~(part->erase_size - 1)) ); + ESP_ERROR_CHECK(esp_flash_erase_region(chip, part->address, (length + part->erase_size) & ~(part->erase_size - 1))); // note writing to unaligned address - ESP_ERROR_CHECK( esp_flash_write(chip, source, part->address + 1, length) ); + ESP_ERROR_CHECK(esp_flash_write(chip, source, part->address + 1, length)); } static void read_and_check(const esp_partition_t *part, const uint8_t *source, size_t length) @@ -756,18 +759,18 @@ static void read_and_check(const esp_partition_t *part, const uint8_t *source, s printf("Checking chip %p 0x%08lX, %u bytes\n", chip, part->address, length); uint8_t *buf = malloc(length); TEST_ASSERT_NOT_NULL(buf); - ESP_ERROR_CHECK( esp_flash_read(chip, buf, part->address + 1, length) ); + ESP_ERROR_CHECK(esp_flash_read(chip, buf, part->address + 1, length)); TEST_ASSERT_EQUAL_HEX8_ARRAY(source, buf, length); free(buf); // check nothing was written at beginning or end uint8_t ends[8]; - ESP_ERROR_CHECK( esp_flash_read(chip, ends, part->address, sizeof(ends)) ); + ESP_ERROR_CHECK(esp_flash_read(chip, ends, part->address, sizeof(ends))); TEST_ASSERT_EQUAL_HEX8(0xFF, ends[0]); TEST_ASSERT_EQUAL_HEX8(source[0], ends[1]); - ESP_ERROR_CHECK( esp_flash_read(chip, ends, part->address + length, sizeof(ends)) ); + ESP_ERROR_CHECK(esp_flash_read(chip, ends, part->address + length, sizeof(ends))); TEST_ASSERT_EQUAL_HEX8(source[length - 1], ends[0]); TEST_ASSERT_EQUAL_HEX8(0xFF, ends[1]); @@ -793,20 +796,20 @@ static void test_write_over_boundary(const esp_partition_t* part) const uint32_t SECTOR_SIZE = 4096; uint8_t buf[0]; - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, 0, flash_size+SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, 0, flash_size + SECTOR_SIZE)); TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, SECTOR_SIZE, flash_size)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size/2, flash_size/2 + SECTOR_SIZE)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size/2 + SECTOR_SIZE, flash_size/2)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size / 2, flash_size / 2 + SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size / 2 + SECTOR_SIZE, flash_size / 2)); TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size - SECTOR_SIZE, 2 * SECTOR_SIZE)); TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, 2 * SECTOR_SIZE, flash_size - SECTOR_SIZE)); TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size - SECTOR_SIZE, flash_size - SECTOR_SIZE)); TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size - SECTOR_SIZE, UINT32_MAX - SECTOR_SIZE + 1)); TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, UINT32_MAX - SECTOR_SIZE + 1, flash_size - SECTOR_SIZE)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, 0, flash_size+SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, 0, flash_size + SECTOR_SIZE)); TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, SECTOR_SIZE, flash_size)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, flash_size/2, flash_size/2 + SECTOR_SIZE)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, flash_size/2 + SECTOR_SIZE, flash_size/2)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, flash_size / 2, flash_size / 2 + SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, flash_size / 2 + SECTOR_SIZE, flash_size / 2)); TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, flash_size - SECTOR_SIZE, 2 * SECTOR_SIZE)); TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, 2 * SECTOR_SIZE, flash_size - SECTOR_SIZE)); TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, flash_size - SECTOR_SIZE, flash_size - SECTOR_SIZE)); @@ -836,7 +839,7 @@ static uint32_t time_measure_end(time_meas_ctx_t* ctx) uint32_t c_time_us = ccomp_timer_stop(); uint32_t time_us = esp_timer_get_time() - ctx->us_start; - ESP_LOGI(TAG, "%s: compensated: %.2lf kB/s, typical: %.2lf kB/s", ctx->name, ctx->len / (c_time_us / 1000.), ctx->len / (time_us/1000.)); + ESP_LOGI(TAG, "%s: compensated: %.2lf kB/s, typical: %.2lf kB/s", ctx->name, ctx->len / (c_time_us / 1000.), ctx->len / (time_us / 1000.)); return ctx->len * 1000 / (c_time_us / 1000); } @@ -902,8 +905,7 @@ static uint32_t measure_read(const char* name, const esp_partition_t* part, uint static const char* get_chip_vendor(uint32_t id) { - switch (id) - { + switch (id) { case 0x20: return "XMC"; break; @@ -967,7 +969,7 @@ static void test_flash_read_write_performance(const esp_partition_t *part) LOG_PERFORMANCE(EXT_, chip_name); } else if (cs_id == 0) { // Main flash - LOG_PERFORMANCE(,chip_name); + LOG_PERFORMANCE(, chip_name); } else { // Other cs pins on SPI1 LOG_PERFORMANCE(SPI1_, chip_name); @@ -978,7 +980,10 @@ static void test_flash_read_write_performance(const esp_partition_t *part) #if !BYPASS_MULTIPLE_CHIP //To make performance data stable, needs to run on special runner -TEST_CASE("Test esp_flash read/write performance", "[esp_flash][test_env=UT_T1_ESP_FLASH]") {flash_test_func(test_flash_read_write_performance, 1);} +TEST_CASE("Test esp_flash read/write performance", "[esp_flash][test_env=UT_T1_ESP_FLASH]") +{ + flash_test_func(test_flash_read_write_performance, 1); +} #endif TEST_CASE_MULTI_FLASH("Test esp_flash read/write performance", test_flash_read_write_performance); @@ -992,12 +997,12 @@ TEST_CASE_MULTI_FLASH("Test esp_flash read/write performance", test_flash_read_w static void s_test_compare_flash_contents_small_reads(esp_flash_t *chip, const uint8_t *buffer, size_t offs, size_t len) { const size_t INTERNAL_BUF_SZ = 1024; // Should fit in internal RAM - uint8_t *ibuf = heap_caps_malloc(INTERNAL_BUF_SZ, MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL); + uint8_t *ibuf = heap_caps_malloc(INTERNAL_BUF_SZ, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); TEST_ASSERT_NOT_NULL(ibuf); for (int i = 0; i < len; i += INTERNAL_BUF_SZ) { size_t to_read = MIN(INTERNAL_BUF_SZ, len - i); - ESP_ERROR_CHECK( esp_flash_read(chip, ibuf, offs + i, to_read) ); + ESP_ERROR_CHECK(esp_flash_read(chip, ibuf, offs + i, to_read)); TEST_ASSERT_EQUAL_HEX8_ARRAY(buffer + i, ibuf, to_read); } @@ -1010,10 +1015,10 @@ static void test_flash_read_large_psram_buffer(const esp_partition_t *part) const size_t BUF_SZ = 256 * 1024; // Too large for internal RAM const size_t TEST_OFFS = 0x1000; // Can be any offset, really - uint8_t *buf = heap_caps_malloc(BUF_SZ, MALLOC_CAP_8BIT|MALLOC_CAP_SPIRAM); + uint8_t *buf = heap_caps_malloc(BUF_SZ, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); TEST_ASSERT_NOT_NULL(buf); - ESP_ERROR_CHECK( esp_flash_read(chip, buf, TEST_OFFS, BUF_SZ) ); + ESP_ERROR_CHECK(esp_flash_read(chip, buf, TEST_OFFS, BUF_SZ)); // Read back the same into smaller internal memory buffer and check it all matches s_test_compare_flash_contents_small_reads(chip, buf, TEST_OFFS, BUF_SZ); @@ -1023,7 +1028,6 @@ static void test_flash_read_large_psram_buffer(const esp_partition_t *part) TEST_CASE_FLASH("esp_flash_read large PSRAM buffer", test_flash_read_large_psram_buffer); - /* similar to above test, but perform it under memory pressure */ static void test_flash_read_large_psram_buffer_low_internal_mem(const esp_partition_t *part) { @@ -1033,14 +1037,14 @@ static void test_flash_read_large_psram_buffer_low_internal_mem(const esp_partit const size_t TEST_OFFS = 0x8000; /* Exhaust the available free internal memory */ - test_utils_exhaust_memory_rec erec = test_utils_exhaust_memory(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT, REMAINING_INTERNAL); + test_utils_exhaust_memory_rec erec = test_utils_exhaust_memory(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT, REMAINING_INTERNAL); - uint8_t *buf = heap_caps_malloc(BUF_SZ, MALLOC_CAP_8BIT|MALLOC_CAP_SPIRAM); + uint8_t *buf = heap_caps_malloc(BUF_SZ, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); TEST_ASSERT_NOT_NULL(buf); /* Calling esp_flash_read() here will need to allocate a small internal buffer, so check it works. */ - ESP_ERROR_CHECK( esp_flash_read(chip, buf, TEST_OFFS, BUF_SZ) ); + ESP_ERROR_CHECK(esp_flash_read(chip, buf, TEST_OFFS, BUF_SZ)); test_utils_free_exhausted_memory(erec); @@ -1053,7 +1057,6 @@ static void test_flash_read_large_psram_buffer_low_internal_mem(const esp_partit TEST_CASE_FLASH("esp_flash_read large PSRAM buffer low memory", test_flash_read_large_psram_buffer_low_internal_mem); #endif - #if CONFIG_SPI_FLASH_ENABLE_COUNTERS #define TEST_CNT_RW_TIMES 4 #define TEST_CNT_RW_LEN 64 @@ -1066,7 +1069,7 @@ void test_flash_counter(const esp_partition_t* part) static uint8_t write_buf[TEST_CNT_RW_LEN * TEST_CNT_RW_TIMES]; static uint8_t read_buf[TEST_CNT_RW_LEN * TEST_CNT_RW_TIMES]; - for(int i = 0;i < TEST_CNT_RW_LEN * TEST_CNT_RW_TIMES; i ++){ + for (int i = 0; i < TEST_CNT_RW_LEN * TEST_CNT_RW_TIMES; i ++) { write_buf[i] = i; } @@ -1086,15 +1089,15 @@ void test_flash_counter(const esp_partition_t* part) TEST_ASSERT_EQUAL_UINT32(TEST_CNT_ERASE_LEN, flash_counter.erase.bytes); int count; - for(count = 0; count < TEST_CNT_RW_TIMES; count ++) { + for (count = 0; count < TEST_CNT_RW_TIMES; count ++) { // check counter on write option - TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, write_buf + TEST_CNT_RW_LEN * count, offs + TEST_CNT_RW_LEN * count, TEST_CNT_RW_LEN) ); + TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, write_buf + TEST_CNT_RW_LEN * count, offs + TEST_CNT_RW_LEN * count, TEST_CNT_RW_LEN)); flash_counter = *esp_flash_get_counters(); TEST_ASSERT_EQUAL_UINT32((count + 1), flash_counter.write.count); TEST_ASSERT_EQUAL_UINT32((count + 1) * TEST_CNT_RW_LEN, flash_counter.write.bytes); // check counter on read option - TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read(chip, read_buf + TEST_CNT_RW_LEN * count, offs + TEST_CNT_RW_LEN * count, TEST_CNT_RW_LEN) ); + TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read(chip, read_buf + TEST_CNT_RW_LEN * count, offs + TEST_CNT_RW_LEN * count, TEST_CNT_RW_LEN)); flash_counter = *esp_flash_get_counters(); TEST_ASSERT_EQUAL_UINT32((count + 1), flash_counter.read.count); TEST_ASSERT_EQUAL_UINT32((count + 1) * TEST_CNT_RW_LEN, flash_counter.read.bytes); @@ -1114,8 +1117,8 @@ void test_flash_counter(const esp_partition_t* part) TEST_ASSERT_EACH_EQUAL_HEX8(0, &flash_counter, sizeof(esp_flash_counters_t)); #if SOC_FLASH_ENC_SUPPORTED - TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write_encrypted(chip, offs, write_buf, TEST_CNT_RW_LEN) ); - TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read_encrypted(chip, offs, read_buf, TEST_CNT_RW_LEN) ); + TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write_encrypted(chip, offs, write_buf, TEST_CNT_RW_LEN)); + TEST_ASSERT_EQUAL(ESP_OK, esp_flash_read_encrypted(chip, offs, read_buf, TEST_CNT_RW_LEN)); printf("\ntest for encrypted write/read\n"); esp_flash_dump_counters(stdout); @@ -1137,7 +1140,7 @@ TEST_CASE_FLASH("SPI flash counter test", test_flash_counter); #if CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS TEST_CASE("test writes to dangerous regions like bootloader", "[esp_flash]") { - TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG, esp_flash_erase_region(NULL, CONFIG_BOOTLOADER_OFFSET_IN_FLASH, 4*4096)); + TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG, esp_flash_erase_region(NULL, CONFIG_BOOTLOADER_OFFSET_IN_FLASH, 4 * 4096)); TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG, esp_flash_erase_region(NULL, CONFIG_PARTITION_TABLE_OFFSET, 4096)); char buffer[32] = {0xa5}; // Encrypted writes to bootloader region not allowed diff --git a/components/spi_flash/test_apps/esp_flash/main/test_spi_flash.c b/components/spi_flash/test_apps/esp_flash/main/test_spi_flash.c index c8ceb438abb..77acda92836 100644 --- a/components/spi_flash/test_apps/esp_flash/main/test_spi_flash.c +++ b/components/spi_flash/test_apps/esp_flash/main/test_spi_flash.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -10,7 +10,6 @@ #include #include "unity.h" -#include "spi_flash_mmap.h" #include "esp_attr.h" #include "esp_intr_alloc.h" #include "ccomp_timer.h" @@ -20,6 +19,8 @@ #include "esp_timer.h" #include "esp_partition.h" #include "bootloader_flash.h" //for bootloader_flash_xmc_startup +#include "esp_flash.h" +#include "spi_flash_mmap.h" #include "test_utils.h" #include "sdkconfig.h" @@ -96,11 +97,11 @@ TEST_CASE("flash write and erase work both on PRO CPU and on APP CPU", "[spi_fla SemaphoreHandle_t done = xSemaphoreCreateCounting(4, 0); struct flash_test_ctx ctx[] = { - { .offset = 0x10 + 6, .done = done }, - { .offset = 0x10 + 7, .done = done }, - { .offset = 0x10 + 8, .done = done }, + { .offset = 0x10 + 6, .done = done }, + { .offset = 0x10 + 7, .done = done }, + { .offset = 0x10 + 8, .done = done }, #ifndef CONFIG_FREERTOS_UNICORE - { .offset = 0x10 + 9, .done = done } + { .offset = 0x10 + 9, .done = done } #endif }; @@ -111,7 +112,7 @@ TEST_CASE("flash write and erase work both on PRO CPU and on APP CPU", "[spi_fla xTaskCreatePinnedToCore(flash_test_task, "t3", 2048, &ctx[3], 3, NULL, 1); #endif - const size_t task_count = sizeof(ctx)/sizeof(ctx[0]); + const size_t task_count = sizeof(ctx) / sizeof(ctx[0]); for (int i = 0; i < task_count; ++i) { xSemaphoreTake(done, portMAX_DELAY); } diff --git a/components/spi_flash/test_apps/esp_flash_freq_limit/main/test_esp_flash_freq_limit.c b/components/spi_flash/test_apps/esp_flash_freq_limit/main/test_esp_flash_freq_limit.c index 47c4790368c..99ee73f34d9 100644 --- a/components/spi_flash/test_apps/esp_flash_freq_limit/main/test_esp_flash_freq_limit.c +++ b/components/spi_flash/test_apps/esp_flash_freq_limit/main/test_esp_flash_freq_limit.c @@ -903,7 +903,6 @@ static void cleanup_interrupt_timer(void) } } - /** * Helper function: Test interrupt during encrypt with PM configuration * Common test logic for both PM enabled and disabled scenarios @@ -1247,5 +1246,4 @@ TEST_CASE("Frequency limit: APB lock released in ISR", "[esp_flash_freq_limit]") } #endif // CONFIG_PM_ENABLE - #endif // CONFIG_IDF_TARGET_ESP32C5 diff --git a/components/spi_flash/test_apps/esp_flash_stress/main/test_esp_flash_stress.c b/components/spi_flash/test_apps/esp_flash_stress/main/test_esp_flash_stress.c index e71f365a2e1..1ab383c90ee 100644 --- a/components/spi_flash/test_apps/esp_flash_stress/main/test_esp_flash_stress.c +++ b/components/spi_flash/test_apps/esp_flash_stress/main/test_esp_flash_stress.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -127,7 +127,7 @@ TEST_CASE("Flash UniCore: Test ESP Flash API Concurrency [Stress]", "[esp_flash] xTaskCreatePinnedToCore(&s_test_flash_ops_task, flash_task_name, 4096, (void *)(&ctx), 5, NULL, 0); } - while(1); + while (1); } #if !CONFIG_FREERTOS_UNICORE @@ -167,7 +167,6 @@ TEST_CASE("Flash DualCore: Test ESP Flash API Concurrency", "[esp_flash]") vSemaphoreDelete(s_test_concurrency_smphr); } - /** * esp_flash APIs concurrency pressure test * This test is for manually test @@ -195,6 +194,6 @@ TEST_CASE("Flash DualCore: Test ESP Flash API Concurrency [Stress]", "[esp_flash xTaskCreatePinnedToCore(&s_test_flash_ops_task, flash_task_name, 4096, (void *)(&ctx), 5, NULL, 1); } - while(1); + while (1); } #endif //#if !CONFIG_FREERTOS_UNICORE diff --git a/components/spi_flash/test_apps/flash_encryption/main/CMakeLists.txt b/components/spi_flash/test_apps/flash_encryption/main/CMakeLists.txt index 59721a4c583..6b768a20ff3 100644 --- a/components/spi_flash/test_apps/flash_encryption/main/CMakeLists.txt +++ b/components/spi_flash/test_apps/flash_encryption/main/CMakeLists.txt @@ -2,5 +2,6 @@ set(srcs "test_app_main.c" "test_flash_encryption.c") idf_component_register(SRCS ${srcs} - PRIV_REQUIRES unity spi_flash bootloader_support esp_partition test_utils test_flash_utils + PRIV_REQUIRES unity spi_flash bootloader_support esp_partition test_utils + test_flash_utils WHOLE_ARCHIVE) diff --git a/components/spi_flash/test_apps/flash_encryption/main/test_app_main.c b/components/spi_flash/test_apps/flash_encryption/main/test_app_main.c index 3990c390433..fcbee37b300 100644 --- a/components/spi_flash/test_apps/flash_encryption/main/test_app_main.c +++ b/components/spi_flash/test_apps/flash_encryption/main/test_app_main.c @@ -25,7 +25,7 @@ static void check_leak(size_t before_free, size_t after_free, const char *type) void setUp(void) { - // Calling esp_partition_find_first ensures that the paritions have been loaded + // Calling esp_partition_find_first ensures that the partitions have been loaded // and subsequent calls to esp_partition_find_first from the tests would not // load partitions which otherwise gets considered as a memory leak. esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL); diff --git a/components/spi_flash/test_apps/flash_encryption/main/test_flash_encryption.c b/components/spi_flash/test_apps/flash_encryption/main/test_flash_encryption.c index 3bdb3227120..8feefe216a9 100644 --- a/components/spi_flash/test_apps/flash_encryption/main/test_flash_encryption.c +++ b/components/spi_flash/test_apps/flash_encryption/main/test_flash_encryption.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -50,7 +50,7 @@ static void setup_tests(void) static void verify_erased_flash(size_t offset, size_t length) { uint8_t *readback = (uint8_t *)heap_caps_malloc(SPI_FLASH_SEC_SIZE, MALLOC_CAP_32BIT | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); - printf("verify erased 0x%" PRIx32 " - 0x%" PRIx32 "\n", (uint32_t) offset, (uint32_t) (offset + length)); + printf("verify erased 0x%" PRIx32 " - 0x%" PRIx32 "\n", (uint32_t) offset, (uint32_t)(offset + length)); TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_flash_read(NULL, readback, offset, length)); for (int i = 0; i < length; i++) { @@ -64,19 +64,19 @@ TEST_CASE("test 16 byte encrypted writes", "[flash_encryption]") setup_tests(); TEST_ASSERT_EQUAL_HEX(ESP_OK, - esp_flash_erase_region(NULL, start, SPI_FLASH_SEC_SIZE)); + esp_flash_erase_region(NULL, start, SPI_FLASH_SEC_SIZE)); uint8_t fortyeight_bytes[0x30]; // 0, 1, 2, 3, 4... 47 - for(int i = 0; i < sizeof(fortyeight_bytes); i++) { + for (int i = 0; i < sizeof(fortyeight_bytes); i++) { fortyeight_bytes[i] = i; } /* Verify unaligned start or length fails */ TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG, - esp_flash_write_encrypted(NULL, start + 1, fortyeight_bytes, 32)); + esp_flash_write_encrypted(NULL, start + 1, fortyeight_bytes, 32)); TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_SIZE, - esp_flash_write_encrypted(NULL, start, fortyeight_bytes, 15)); + esp_flash_write_encrypted(NULL, start, fortyeight_bytes, 15)); /* ensure nothing happened to the flash yet */ verify_erased_flash(start, 0x20); @@ -87,8 +87,8 @@ TEST_CASE("test 16 byte encrypted writes", "[flash_encryption]") /* Slip in an unaligned esp_flash_read_encrypted() test */ uint8_t buf[0x10]; - esp_flash_read_encrypted(NULL, start+0x10, buf, 0x10); - TEST_ASSERT_EQUAL_HEX8_ARRAY(fortyeight_bytes+0x10, buf, 16); + esp_flash_read_encrypted(NULL, start + 0x10, buf, 0x10); + TEST_ASSERT_EQUAL_HEX8_ARRAY(fortyeight_bytes + 0x10, buf, 16); /* Write 16 bytes unaligned */ test_encrypted_write(start + 0x30, fortyeight_bytes, 0x10); @@ -124,7 +124,7 @@ TEST_CASE("test read & write random encrypted data", "[flash_encryption]") { const int MAX_LEN = 192; //buffer to hold the read data - WORD_ALIGNED_ATTR uint8_t buffer_to_write[MAX_LEN+4]; + WORD_ALIGNED_ATTR uint8_t buffer_to_write[MAX_LEN + 4]; //test with unaligned buffer uint8_t* data_buf = &buffer_to_write[3]; @@ -145,7 +145,7 @@ TEST_CASE("test read & write random encrypted data", "[flash_encryption]") do { //the encrypted write only works at 16-byte boundary int skip = (rand() % 4) * 16; - int len = ((rand() % (MAX_LEN/16)) + 1) * 16; + int len = ((rand() % (MAX_LEN / 16)) + 1) * 16; for (int i = 0; i < MAX_LEN; i++) { data_buf[i] = rand(); @@ -159,7 +159,7 @@ TEST_CASE("test read & write random encrypted data", "[flash_encryption]") len = SPI_FLASH_SEC_SIZE - offset; } - printf("write %d bytes to 0x%08" PRIx32 "...\n", len, (uint32_t) (start + offset)); + printf("write %d bytes to 0x%08" PRIx32 "...\n", len, (uint32_t)(start + offset)); err = esp_flash_write_encrypted(NULL, start + offset, data_buf, len); TEST_ESP_OK(err); @@ -169,7 +169,7 @@ TEST_CASE("test read & write random encrypted data", "[flash_encryption]") offset = 0; do { - int len = ((rand() % (MAX_LEN/16)) + 1) * 16; + int len = ((rand() % (MAX_LEN / 16)) + 1) * 16; if (offset + len > SPI_FLASH_SEC_SIZE) { len = SPI_FLASH_SEC_SIZE - offset; } @@ -177,7 +177,7 @@ TEST_CASE("test read & write random encrypted data", "[flash_encryption]") err = esp_flash_read_encrypted(NULL, start + offset, data_buf, len); TEST_ESP_OK(err); - printf("compare %d bytes at 0x%08" PRIx32 "...\n", len, (uint32_t) (start + offset)); + printf("compare %d bytes at 0x%08" PRIx32 "...\n", len, (uint32_t)(start + offset)); TEST_ASSERT_EQUAL_HEX8_ARRAY(cmp_buf + offset, data_buf, len); offset += len; @@ -208,19 +208,19 @@ TEST_CASE("test 16 byte encrypted writes (esp_flash)", "[flash_encryption]") setup_tests(); TEST_ASSERT_EQUAL_HEX(ESP_OK, - esp_flash_erase_region(NULL, start, SPI_FLASH_SEC_SIZE)); + esp_flash_erase_region(NULL, start, SPI_FLASH_SEC_SIZE)); uint8_t fortyeight_bytes[0x30]; // 0, 1, 2, 3, 4... 47 - for(int i = 0; i < sizeof(fortyeight_bytes); i++) { + for (int i = 0; i < sizeof(fortyeight_bytes); i++) { fortyeight_bytes[i] = i; } /* Verify unaligned start or length fails */ TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG, - esp_flash_write_encrypted(NULL, start+1, fortyeight_bytes, 32)); + esp_flash_write_encrypted(NULL, start + 1, fortyeight_bytes, 32)); TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_SIZE, - esp_flash_write_encrypted(NULL, start, fortyeight_bytes, 15)); + esp_flash_write_encrypted(NULL, start, fortyeight_bytes, 15)); /* ensure nothing happened to the flash yet */ verify_erased_flash(start, 0x20); @@ -231,8 +231,8 @@ TEST_CASE("test 16 byte encrypted writes (esp_flash)", "[flash_encryption]") /* Slip in an unaligned esp_flash_read_encrypted() test */ uint8_t buf[0x10]; - esp_flash_read_encrypted(NULL, start+0x10, buf, 0x10); - TEST_ASSERT_EQUAL_HEX8_ARRAY(fortyeight_bytes+0x10, buf, 16); + esp_flash_read_encrypted(NULL, start + 0x10, buf, 0x10); + TEST_ASSERT_EQUAL_HEX8_ARRAY(fortyeight_bytes + 0x10, buf, 16); /* Write 16 bytes unaligned */ test_encrypted_write_new_impl(start + 0x30, fortyeight_bytes, 0x10); @@ -392,7 +392,7 @@ TEST_CASE("test read & write encrypted data with large buffer(n*64+32+16)", "[fl TEST_ESP_OK(ccomp_timer_start()); TEST_ESP_OK(esp_flash_write_encrypted(NULL, start, large_const_buffer, sizeof(large_const_buffer))); int64_t write_time = ccomp_timer_stop(); - IDF_LOG_PERFORMANCE(TAG, "Writing speed: %.2f us/KB", (double)(write_time/sizeof(large_const_buffer))*1024); + IDF_LOG_PERFORMANCE(TAG, "Writing speed: %.2f us/KB", (double)(write_time / sizeof(large_const_buffer)) * 1024); uint8_t *buf = (uint8_t*)heap_caps_malloc(sizeof(large_const_buffer), MALLOC_CAP_8BIT); @@ -412,7 +412,7 @@ TEST_CASE("test read & write encrypted data with large buffer(n*64+32+16)", "[fl TEST_ESP_OK(ccomp_timer_start()); TEST_ESP_OK(esp_flash_write_encrypted(NULL, start, large_const_buffer, sizeof(large_const_buffer))); write_time = ccomp_timer_stop(); - IDF_LOG_PERFORMANCE(TAG, "Writing speed: %.2f us/KB", (double)(write_time/sizeof(large_const_buffer))*1024); + IDF_LOG_PERFORMANCE(TAG, "Writing speed: %.2f us/KB", (double)(write_time / sizeof(large_const_buffer)) * 1024); buf = (uint8_t*)heap_caps_malloc(sizeof(large_const_buffer), MALLOC_CAP_8BIT); @@ -446,7 +446,7 @@ TEST_CASE("test read & write encrypted data with large buffer in ram", "[flash_e TEST_ESP_OK(ccomp_timer_start()); TEST_ESP_OK(esp_flash_write_encrypted(NULL, start, large_const_buffer_dram, sizeof(large_const_buffer_dram))); int64_t write_time = ccomp_timer_stop(); - IDF_LOG_PERFORMANCE(TAG, "Writing speed: %.2f us/KB", (double)(write_time/sizeof(large_const_buffer_dram))*1024); + IDF_LOG_PERFORMANCE(TAG, "Writing speed: %.2f us/KB", (double)(write_time / sizeof(large_const_buffer_dram)) * 1024); uint8_t *buf = (uint8_t*)heap_caps_malloc(sizeof(large_const_buffer_dram), MALLOC_CAP_32BIT | MALLOC_CAP_8BIT); TEST_ESP_OK(esp_flash_read_encrypted(NULL, start, buf, sizeof(large_const_buffer_dram))); @@ -457,7 +457,7 @@ TEST_CASE("test read & write encrypted data with large buffer in ram", "[flash_e #if CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS TEST_CASE("test encrypted writes to dangerous regions like bootloader", "[flash_encryption]") { - TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG, esp_flash_erase_region(NULL, CONFIG_BOOTLOADER_OFFSET_IN_FLASH, 4*4096)); + TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG, esp_flash_erase_region(NULL, CONFIG_BOOTLOADER_OFFSET_IN_FLASH, 4 * 4096)); TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG, esp_flash_erase_region(NULL, CONFIG_PARTITION_TABLE_OFFSET, 4096)); char buffer[32] = {0xa5}; // Encrypted writes to bootloader region not allowed @@ -475,20 +475,20 @@ TEST_CASE("Test flash encrypted write over boundary", "[flash_encryption]") const uint32_t SECTOR_SIZE = 4096; uint8_t buf[0]; - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, 0, flash_size+SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, 0, flash_size + SECTOR_SIZE)); TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, SECTOR_SIZE, flash_size)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size/2, flash_size/2 + SECTOR_SIZE)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size/2 + SECTOR_SIZE, flash_size/2)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size / 2, flash_size / 2 + SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size / 2 + SECTOR_SIZE, flash_size / 2)); TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size - SECTOR_SIZE, 2 * SECTOR_SIZE)); TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, 2 * SECTOR_SIZE, flash_size - SECTOR_SIZE)); TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size - SECTOR_SIZE, flash_size - SECTOR_SIZE)); TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size - SECTOR_SIZE, UINT32_MAX - SECTOR_SIZE + 1)); TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, UINT32_MAX - SECTOR_SIZE + 1, flash_size - SECTOR_SIZE)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, 0, buf, flash_size+SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, 0, buf, flash_size + SECTOR_SIZE)); TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, SECTOR_SIZE, buf, flash_size)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, flash_size/2, buf, flash_size/2 + SECTOR_SIZE)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, flash_size/2 + SECTOR_SIZE, buf, flash_size/2)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, flash_size / 2, buf, flash_size / 2 + SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, flash_size / 2 + SECTOR_SIZE, buf, flash_size / 2)); TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, flash_size - SECTOR_SIZE, buf, 2 * SECTOR_SIZE)); TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, 2 * SECTOR_SIZE, buf, flash_size - SECTOR_SIZE)); TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, flash_size - SECTOR_SIZE, buf, flash_size - SECTOR_SIZE)); diff --git a/components/spi_flash/test_apps/flash_mmap/main/test_app_main.c b/components/spi_flash/test_apps/flash_mmap/main/test_app_main.c index 635327c2032..d4db693b3b2 100644 --- a/components/spi_flash/test_apps/flash_mmap/main/test_app_main.c +++ b/components/spi_flash/test_apps/flash_mmap/main/test_app_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -14,7 +14,6 @@ static size_t before_free_8bit; static size_t before_free_32bit; - void setUp(void) { before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); @@ -41,7 +40,6 @@ void app_main(void) */ - printf("______ _ ___ _____ _ _ ___ ______ ___ ___ ______\n"); printf("| ___| | / _ \\ / ___| | | | | \\/ || \\/ | / _ \\ | ___ \\\n"); printf("| |_ | | / /_\\ \\\\ `--.| |_| | | . . || . . |/ /_\\ \\| |_/ /\n"); diff --git a/components/spi_flash/test_apps/flash_mmap/pytest_flash_mmap.py b/components/spi_flash/test_apps/flash_mmap/pytest_flash_mmap.py index 2c64831db7a..1310974d449 100644 --- a/components/spi_flash/test_apps/flash_mmap/pytest_flash_mmap.py +++ b/components/spi_flash/test_apps/flash_mmap/pytest_flash_mmap.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 import pytest from pytest_embedded import Dut diff --git a/components/spi_flash/test_apps/flash_suspend/main/test_app_main.c b/components/spi_flash/test_apps/flash_suspend/main/test_app_main.c index c72d87cead6..56e21e6c857 100644 --- a/components/spi_flash/test_apps/flash_suspend/main/test_app_main.c +++ b/components/spi_flash/test_apps/flash_suspend/main/test_app_main.c @@ -14,7 +14,6 @@ static size_t before_free_8bit; static size_t before_free_32bit; - void setUp(void) { before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); diff --git a/components/spi_flash/test_apps/flash_suspend/main/test_flash_suspend.c b/components/spi_flash/test_apps/flash_suspend/main/test_flash_suspend.c index 9745ffac786..394a5a1e04f 100644 --- a/components/spi_flash/test_apps/flash_suspend/main/test_flash_suspend.c +++ b/components/spi_flash/test_apps/flash_suspend/main/test_flash_suspend.c @@ -47,7 +47,6 @@ DRAM_ATTR static uint32_t s_isr_interval_t2; DRAM_ATTR static uint32_t s_isr_interval_time; DRAM_ATTR static uint32_t times = 0; - static NOINLINE_ATTR void func_in_flash(void) { /** @@ -66,7 +65,7 @@ static NOINLINE_ATTR void func_in_flash(void) static bool IRAM_ATTR gptimer_alarm_suspend_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx) { s_isr_t1 = esp_cpu_get_cycle_count(); - if (s_isr_interval_t1 != 0 ) { + if (s_isr_interval_t1 != 0) { s_isr_interval_t2 = esp_cpu_get_cycle_count(); s_isr_interval_time += (s_isr_interval_t2 - s_isr_interval_t1); } diff --git a/components/spi_flash/test_apps/mspi_test/main/test_large_flash_writes.c b/components/spi_flash/test_apps/mspi_test/main/test_large_flash_writes.c index f677ccf83b9..0b5a2baf804 100644 --- a/components/spi_flash/test_apps/mspi_test/main/test_large_flash_writes.c +++ b/components/spi_flash/test_apps/mspi_test/main/test_large_flash_writes.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,8 +22,8 @@ static const uint8_t large_const_buffer[16400] = { 203, // first byte - 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20, - 21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, [50 ... 99] = 2, [1600 ... 2000] = 3, [8000 ... 9000] = 77, @@ -37,7 +37,7 @@ const esp_partition_t *get_test_data_partition(void) { /* This finds "flash_test" partition defined in partition_table_unit_test_app.csv */ const esp_partition_t *result = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, - ESP_PARTITION_SUBTYPE_ANY, "flash_test"); + ESP_PARTITION_SUBTYPE_ANY, "flash_test"); TEST_ASSERT_NOT_NULL(result); /* means partition table set wrong */ return result; } @@ -68,12 +68,12 @@ static void test_write_large_buffer(const uint8_t *source, size_t length) uint8_t *buf = malloc(length); TEST_ASSERT_NOT_NULL(buf); - TEST_ESP_OK( esp_flash_erase_region(NULL, part->address, (length + part->erase_size) & ~(part->erase_size-1)) ); + TEST_ESP_OK(esp_flash_erase_region(NULL, part->address, (length + part->erase_size) & ~(part->erase_size - 1))); // note writing to unaligned address - TEST_ESP_OK( esp_flash_write(NULL, source, part->address + 1, length) ); + TEST_ESP_OK(esp_flash_write(NULL, source, part->address + 1, length)); - TEST_ESP_OK( esp_flash_read(NULL, buf, part->address + 1, length) ); + TEST_ESP_OK(esp_flash_read(NULL, buf, part->address + 1, length)); TEST_ASSERT_EQUAL_HEX8_ARRAY(source, buf, length); @@ -82,12 +82,12 @@ static void test_write_large_buffer(const uint8_t *source, size_t length) // check nothing was written at beginning or end uint8_t ends[8]; - TEST_ESP_OK( esp_flash_read(NULL, ends, part->address, sizeof(ends)) ); + TEST_ESP_OK(esp_flash_read(NULL, ends, part->address, sizeof(ends))); TEST_ASSERT_EQUAL_HEX8(0xFF, ends[0]); - TEST_ASSERT_EQUAL_HEX8(source[0] , ends[1]); + TEST_ASSERT_EQUAL_HEX8(source[0], ends[1]); - TEST_ESP_OK( esp_flash_read(NULL, ends, part->address + length, sizeof(ends)) ); - TEST_ASSERT_EQUAL_HEX8(source[length-1], ends[0]); + TEST_ESP_OK(esp_flash_read(NULL, ends, part->address + length, sizeof(ends))); + TEST_ASSERT_EQUAL_HEX8(source[length - 1], ends[0]); TEST_ASSERT_EQUAL_HEX8(0xFF, ends[1]); TEST_ASSERT_EQUAL_HEX8(0xFF, ends[2]); TEST_ASSERT_EQUAL_HEX8(0xFF, ends[3]); diff --git a/components/spi_flash/test_apps/mspi_test/main/test_read_write.c b/components/spi_flash/test_apps/mspi_test/main/test_read_write.c index 7055e2b787d..3dea1a689a2 100644 --- a/components/spi_flash/test_apps/mspi_test/main/test_read_write.c +++ b/components/spi_flash/test_apps/mspi_test/main/test_read_write.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -50,7 +50,7 @@ static void setup_tests(void) static void fill(char *dest, int32_t start, int32_t len) { for (int32_t i = 0; i < len; i++) { - *(dest + i) = (char) (start + i); + *(dest + i) = (char)(start + i); } } @@ -330,8 +330,7 @@ TEST_CASE("esp_flash_write can write from external RAM buffer", "[spi_flash]") TEST_ASSERT_NOT_NULL(buf_ext); srand(0); - for (size_t i = 0; i < SPI_FLASH_SEC_SIZE / sizeof(uint32_t); i++) - { + for (size_t i = 0; i < SPI_FLASH_SEC_SIZE / sizeof(uint32_t); i++) { uint32_t val = rand(); buf_ext[i] = val; } diff --git a/components/unity/CMakeLists.txt b/components/unity/CMakeLists.txt index ef7ee00cd23..f68fd684d83 100644 --- a/components/unity/CMakeLists.txt +++ b/components/unity/CMakeLists.txt @@ -43,7 +43,7 @@ idf_component_register(SRCS "${srcs}" REQUIRES ${requires}) if(CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER) - idf_component_optional_requires(PRIVATE spi_flash) + idf_component_optional_requires(PRIVATE esp_mspi) endif() target_compile_definitions(${COMPONENT_LIB} PUBLIC diff --git a/examples/storage/custom_flash_driver/bootloader_components/bootloader_flash/bootloader_flash_unlock_custom.c b/examples/storage/custom_flash_driver/bootloader_components/bootloader_flash/bootloader_flash_unlock_custom.c index e028fd51d9a..21c04e25e4b 100644 --- a/examples/storage/custom_flash_driver/bootloader_components/bootloader_flash/bootloader_flash_unlock_custom.c +++ b/examples/storage/custom_flash_driver/bootloader_components/bootloader_flash/bootloader_flash_unlock_custom.c @@ -1,9 +1,11 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ -#include "bootloader_flash_priv.h" +#include "esp_bit_defs.h" +#include "bootloader_flash_override.h" +#include "spi_flash_defs.h" #include "esp_rom_spiflash.h" #include "esp_rom_sys.h" #include "esp_attr.h" @@ -17,7 +19,7 @@ Overview Step-by-Step Implementation 1. Include Necessary Headers: - • bootloader_flash_priv.h: For private bootloader functions. + • bootloader_flash_override.h: For `bootloader_execute_flash_command` function. • esp_rom_spiflash.h: For ROM SPI flash functions. • esp_rom_sys.h: For basic ROM system functions. • esp_attr.h and esp_log.h: For attributes and logging. diff --git a/tools/ci/check_public_headers_exceptions.txt b/tools/ci/check_public_headers_exceptions.txt index 958f8c40018..534d3aa3be6 100644 --- a/tools/ci/check_public_headers_exceptions.txt +++ b/tools/ci/check_public_headers_exceptions.txt @@ -92,7 +92,6 @@ components/bootloader_support/bootloader_flash/include/bootloader_flash.h components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h components/esp_hw_support/include/esp_private/regdma_link.h components/lwip/include/lwip/netdb.h -components/spi_flash/include/esp_private/spi_flash_os.h ### To be fixed: files which don't compile for esp32s2 target: diff --git a/tools/test_apps/system/g1_components/check_dependencies.py b/tools/test_apps/system/g1_components/check_dependencies.py index acc69dcfccf..71381930394 100644 --- a/tools/test_apps/system/g1_components/check_dependencies.py +++ b/tools/test_apps/system/g1_components/check_dependencies.py @@ -20,8 +20,8 @@ g1_g0_components_base = [ 'esp_system', 'xtensa', 'riscv', - 'spi_flash', 'esp_mm', + 'esp_mspi', ] @@ -54,8 +54,8 @@ g1_g0_components = g1_g0_components_base + get_all_esp_hal_components() # Global expected dependency violations that apply to all targets expected_dep_violations = { 'esp_system': ['esp_timer', 'bootloader_support', 'esp_pm'], - 'spi_flash': ['bootloader_support', 'esp_blockdev', 'esp_driver_gpio'], 'esp_hw_support': ['efuse', 'bootloader_support', 'esp_driver_gpio', 'esp_timer', 'esp_pm'], + 'esp_mspi': ['bootloader_support'], 'cxx': ['pthread'], } @@ -68,15 +68,11 @@ else: expected_dep_violations['esp_system'].append('esp_usb_cdc_rom_console') # Target-specific expected dependency violations -target_specific_expected_dep_violations = { +target_specific_expected_dep_violations: dict[str, dict[str, list[str]]] = { # 'target': { # Add target-specific violations for target here # 'component_name': ['dependency1', 'dependency2'], # }, - 'esp32s2': { - # ESP32-S2 uses the crypto DMA lock for encrypted writes, thus, spi_flash needs to depend on esp_security - 'spi_flash': ['esp_security'], - }, } diff --git a/tools/test_apps/system/g1_components/g1_check.cmake b/tools/test_apps/system/g1_components/g1_check.cmake index 414d80e5450..4f5787a6bc2 100644 --- a/tools/test_apps/system/g1_components/g1_check.cmake +++ b/tools/test_apps/system/g1_components/g1_check.cmake @@ -13,7 +13,7 @@ set(extra_components_which_shouldnt_be_included bootloader # bootloader_support is a dependency of the following G1 components: - # spi_flash, esp_system, esp_hw_support. + # esp_system, esp_hw_support, esp_mspi. # as well as the following non G1 components: # efuse, app_update, esp_partition # Challenging to remove: IDF-8581 for more details @@ -23,7 +23,7 @@ set(extra_components_which_shouldnt_be_included cxx # esp_driver_gpio is a dependency of esp_pm (should be removed from g1 builds), - # as well as spi_flash, esp_hw_support, IDF-10387 + # as well as esp_hw_support, IDF-10387 esp_driver_gpio # esp_app_format is dependency of bootloader_support, app_update, efuse. @@ -76,6 +76,9 @@ set(extra_components_which_shouldnt_be_included # esp_security is required by spi_flash esp_security + + # spi_flash is pulled in by bootloader_support (non-bootloader build). + spi_flash ) if(NOT IDF_BUILD_V2) diff --git a/tools/test_apps/system/g1_components/g1_setup.cmake b/tools/test_apps/system/g1_components/g1_setup.cmake index cd942849810..a39676c923e 100644 --- a/tools/test_apps/system/g1_components/g1_setup.cmake +++ b/tools/test_apps/system/g1_components/g1_setup.cmake @@ -3,7 +3,7 @@ # project is configured, since cmakev1 uses COMPONENTS to restrict the build. set(g0_components soc hal esp_common esp_rom) # also , i.e. xtensa or riscv, will be added below -set(g1_components spi_flash freertos log heap esp_libc esp_system esp_hw_support esp_mm esp_stdio) +set(g1_components freertos log heap esp_libc esp_system esp_hw_support esp_mm esp_stdio esp_mspi) # The HAL components that required by G1 components # Most of these HAL components are required by `clk.c` in `esp_system` for peripherals clock initialization. set(esp_hal_components