From d4c9a45675500240ad45142b02ee41e4b636eb0b Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 16 Dec 2020 14:50:13 +1100 Subject: [PATCH 1/3] spi_flash: Add ESP32-C3 support Based on internal commit 3ef01301fff --- components/hal/spi_flash_hal_common.inc | 37 ++++- components/hal/spi_flash_hal_iram.c | 4 +- components/spi_flash/CMakeLists.txt | 30 +--- components/spi_flash/Kconfig | 13 ++ components/spi_flash/cache_utils.c | 44 ++++++ .../spi_flash/esp32c3/flash_ops_esp32c3.c | 145 ++++++++++++++++++ .../spi_flash/esp32c3/spi_flash_rom_patch.c | 26 ++++ components/spi_flash/esp_flash_api.c | 47 ++++-- components/spi_flash/esp_flash_spi_init.c | 36 +++-- components/spi_flash/flash_mmap.c | 9 +- components/spi_flash/flash_ops.c | 55 +++++-- .../spi_flash/include/spi_flash_chip_driver.h | 4 + .../spi_flash/include/spi_flash_chip_gd.h | 4 + .../include/spi_flash_chip_generic.h | 2 +- .../spi_flash/include/spi_flash_chip_issi.h | 4 + components/spi_flash/memspi_host_driver.c | 11 +- components/spi_flash/spi_flash_chip_gd.c | 6 +- components/spi_flash/spi_flash_chip_generic.c | 15 +- components/spi_flash/spi_flash_chip_issi.c | 2 + components/spi_flash/spi_flash_chip_mxic.c | 1 + components/spi_flash/spi_flash_chip_winbond.c | 1 + components/spi_flash/spi_flash_os_func_noos.c | 16 ++ components/spi_flash/test/test_esp_flash.c | 53 +++++-- components/spi_flash/test/test_mmap.c | 9 +- components/spi_flash/test/test_read_write.c | 2 +- components/spi_flash/test/test_spi_flash.c | 15 +- 26 files changed, 493 insertions(+), 98 deletions(-) create mode 100644 components/spi_flash/esp32c3/flash_ops_esp32c3.c create mode 100644 components/spi_flash/esp32c3/spi_flash_rom_patch.c diff --git a/components/hal/spi_flash_hal_common.inc b/components/hal/spi_flash_hal_common.inc index db785deebc..6a33c67e38 100644 --- a/components/hal/spi_flash_hal_common.inc +++ b/components/hal/spi_flash_hal_common.inc @@ -78,6 +78,26 @@ esp_err_t spi_flash_hal_configure_host_io_mode( return ESP_ERR_NOT_SUPPORTED; } +#if CONFIG_SPI_FLASH_ROM_IMPL + /* + * In S3 ROM, extra bits than 24-bit are used to indicate requirements of M7-M0: + * - 24: normal transactions + * - 28: 24bit DIO + conf bits (M7-M0 excluded from dummy_bitlen) + * - 32: 24bit QIO + conf bits (M7-M0 excluded from dummy_bitlen) + + * Detect requirements for the conf bits by the address len, and modify the length to normal + * case (addr_bitlen = 24, dummy_bitlen includes M7-M0) as other chip versions use. + */ + int m70_bits = addr_bitlen - 24; + if (m70_bits) { + assert(io_mode == SPI_FLASH_DIO || io_mode == SPI_FLASH_QIO); + conf_required = true; + addr_bitlen -= m70_bits; + int line_width = (io_mode == SPI_FLASH_DIO? 2: 4); + dummy_cyclelen_base += m70_bits / line_width; + } +#endif //CONFIG_SPI_FLASH_ROM_IMPL + #if SOC_SPI_PERIPH_SUPPORT_CONTROL_DUMMY_OUTPUT // The CONTROL_DUMMY_OUTPUT feature is used to control M7-M0 bits. spi_flash_ll_set_dummy_out(dev, (conf_required? 1: 0), 1); @@ -110,11 +130,18 @@ esp_err_t spi_flash_hal_common_command(spi_flash_host_inst_t *host, spi_flash_tr { spi_dev_t *dev = get_spi_dev(host); esp_flash_io_mode_t io_mode = ((spi_flash_hal_context_t*)host)->base_io_mode; - uint16_t command = trans->command; - uint8_t dummy_bitlen = trans->dummy_bitlen; - - if ((trans->flags & SPI_FLASH_TRANS_FLAG_IGNORE_BASEIO) != 0) { - io_mode = 0; + uint16_t command; + uint8_t dummy_bitlen; + if (trans->reserved != 0) { + // Back-compatible with caller functions of ESP32-S3 ROM + command = (uint8_t)trans->reserved; + dummy_bitlen = 0; + } else { + command = trans->command; + dummy_bitlen = trans->dummy_bitlen; + if ((trans->flags & SPI_FLASH_TRANS_FLAG_IGNORE_BASEIO) != 0) { + io_mode = ((spi_flash_hal_context_t*)host)->base_io_mode; + } } host->driver->configure_host_io_mode(host, command, trans->address_bitlen, dummy_bitlen, io_mode); diff --git a/components/hal/spi_flash_hal_iram.c b/components/hal/spi_flash_hal_iram.c index 9e76553485..0efda5a47a 100644 --- a/components/hal/spi_flash_hal_iram.c +++ b/components/hal/spi_flash_hal_iram.c @@ -13,7 +13,7 @@ // limitations under the License. #include "sdkconfig.h" -#ifndef CONFIG_SPI_FLASH_NEW_ROM_API +#ifndef CONFIG_SPI_FLASH_ROM_IMPL // HAL for // - MEMSPI @@ -95,4 +95,4 @@ bool spi_flash_hal_host_idle(spi_flash_host_inst_t *host) return idle; } -#endif // !CONFIG_SPI_FLASH_NEW_ROM_API +#endif // !CONFIG_SPI_FLASH_ROM_IMPL diff --git a/components/spi_flash/CMakeLists.txt b/components/spi_flash/CMakeLists.txt index df7b630c16..0c2d20a81c 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/components/spi_flash/CMakeLists.txt @@ -62,18 +62,7 @@ if(${spi_flash_mock}) else() if(BOOTLOADER_BUILD) - if(CONFIG_IDF_TARGET_ESP32) - # ESP32 Bootloader needs SPIUnlock from this file, but doesn't - # need other parts of this component - set(srcs "esp32/spi_flash_rom_patch.c") - elseif(CONFIG_IDF_TARGET_ESP32S2) - set(srcs "esp32s2/spi_flash_rom_patch.c") - elseif(CONFIG_IDF_TARGET_ESP32S3) - set(srcs "esp32s3/spi_flash_rom_patch.c") - else() - # but on other platforms no source files are needed for bootloader - set(srcs) - endif() + set(srcs "${target}/spi_flash_rom_patch.c") set(cache_srcs "") set(priv_requires bootloader_support soc) else() @@ -81,21 +70,12 @@ else() "cache_utils.c" "flash_mmap.c" "flash_ops.c" - "${IDF_TARGET}/flash_ops_${IDF_TARGET}.c" + "${target}/flash_ops_${target}.c" ) set(srcs - "partition.c") - - if(CONFIG_IDF_TARGET_ESP32) - list(APPEND srcs - "esp32/spi_flash_rom_patch.c") - elseif(CONFIG_IDF_TARGET_ESP32S2) - list(APPEND srcs - "esp32s2/spi_flash_rom_patch.c") - elseif(CONFIG_IDF_TARGET_ESP32S3) - list(APPEND srcs - "esp32s3/spi_flash_rom_patch.c") - endif() + "partition.c" + "${target}/spi_flash_rom_patch.c" + ) # New implementation after IDF v4.0 list(APPEND srcs diff --git a/components/spi_flash/Kconfig b/components/spi_flash/Kconfig index eb34c3790a..e99be18823 100644 --- a/components/spi_flash/Kconfig +++ b/components/spi_flash/Kconfig @@ -53,6 +53,19 @@ menu "SPI Flash driver" to flash on ESP32-D2WD; (2) main SPI flash is connected to non-default pins; (3) main SPI flash chip is manufactured by ISSI. + config SPI_FLASH_ROM_IMPL + bool "Use esp_flash implementation in ROM" + depends on IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C3 + default n + help + Enable this flag to use new SPI flash driver functions from ROM instead of ESP-IDF. + + If keeping this as "n" in your project, you will have less free IRAM. + But you can use all of our flash features. + + If making this as "y" in your project, you will increase free IRAM. + But you may miss out on some flash features and support for new flash chips. + choice SPI_FLASH_DANGEROUS_WRITE bool "Writing to dangerous flash regions" default SPI_FLASH_DANGEROUS_WRITE_ABORTS diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index 5285e6be27..f016847518 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -875,6 +875,50 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable } #endif +#if CONFIG_IDF_TARGET_ESP32C3 + +static IRAM_ATTR void esp_enable_cache_flash_wrap(bool icache) +{ + uint32_t i_autoload; + if (icache) { + i_autoload = Cache_Suspend_ICache(); + } + REG_SET_BIT(EXTMEM_CACHE_WRAP_AROUND_CTRL_REG, EXTMEM_CACHE_FLASH_WRAP_AROUND); + if (icache) { + Cache_Resume_ICache(i_autoload); + } +} + +esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable) +{ + int flash_wrap_size = 0; + bool flash_support_wrap = false; + + if (icache_wrap_enable) { + flash_wrap_size = 32; + } + +#ifdef CONFIG_FLASHMODE_QIO + flash_support_wrap = true; + extern bool spi_flash_support_wrap_size(uint32_t wrap_size); + if (!spi_flash_support_wrap_size(flash_wrap_size)) { + flash_support_wrap = false; + ESP_EARLY_LOGW(TAG, "Flash do not support wrap size %d.", flash_wrap_size); + } +#else + ESP_EARLY_LOGW(TAG, "Flash is not in QIO mode, do not support wrap."); +#endif // CONFIG_FLASHMODE_QIO + + extern esp_err_t spi_flash_enable_wrap(uint32_t wrap_size); + if (flash_support_wrap && flash_wrap_size > 0) { + ESP_EARLY_LOGI(TAG, "Flash wrap enabled, size = %d.", flash_wrap_size); + spi_flash_enable_wrap(flash_wrap_size); + esp_enable_cache_flash_wrap((flash_wrap_size > 0)); + } + return ESP_OK; +} +#endif // CONFIG_IDF_TARGET_ESP32C3 + void IRAM_ATTR spi_flash_enable_cache(uint32_t cpuid) { #if CONFIG_IDF_TARGET_ESP32 diff --git a/components/spi_flash/esp32c3/flash_ops_esp32c3.c b/components/spi_flash/esp32c3/flash_ops_esp32c3.c new file mode 100644 index 0000000000..55879b8341 --- /dev/null +++ b/components/spi_flash/esp32c3/flash_ops_esp32c3.c @@ -0,0 +1,145 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "esp_spi_flash.h" +#include "soc/system_reg.h" +#include "soc/soc_memory_layout.h" +#include "esp32c3/rom/spi_flash.h" +#include "esp32c3/rom/cache.h" +#include "hal/spi_flash_hal.h" +#include "esp_flash.h" +#include "esp_log.h" + +static const char *TAG = "spiflash_c3"; + +#define SPICACHE SPIMEM0 +#define SPIFLASH SPIMEM1 + +esp_rom_spiflash_result_t IRAM_ATTR spi_flash_write_encrypted_chip(size_t dest_addr, const void *src, size_t size) +{ + const spi_flash_guard_funcs_t *ops = spi_flash_guard_get(); + esp_rom_spiflash_result_t rc; + + assert((dest_addr % 16) == 0); + assert((size % 16) == 0); + + if (!esp_ptr_internal(src)) { + uint8_t block[128]; // Need to buffer in RAM as we write + while (size > 0) { + size_t next_block = MIN(size, sizeof(block)); + memcpy(block, src, next_block); + + esp_rom_spiflash_result_t r = spi_flash_write_encrypted_chip(dest_addr, block, next_block); + if (r != ESP_ROM_SPIFLASH_RESULT_OK) { + return r; + } + + size -= next_block; + dest_addr += next_block; + src = ((uint8_t *)src) + next_block; + } + bzero(block, sizeof(block)); + + return ESP_ROM_SPIFLASH_RESULT_OK; + } else { // Already in internal memory + ESP_LOGV(TAG, "calling esp_rom_spiflash_write_encrypted addr 0x%x src %p size 0x%x", dest_addr, src, size); + +#ifndef CONFIG_SPI_FLASH_USE_LEGACY_IMPL + /* The ROM function SPI_Encrypt_Write assumes ADDR_BITLEN is already set but new + implementation doesn't automatically set this to a usable value */ + SPIFLASH.user1.usr_addr_bitlen = 23; +#endif + + if (ops && ops->start) { + ops->start(); + } + rc = esp_rom_spiflash_write_encrypted(dest_addr, (uint32_t *)src, size); + if (ops && ops->end) { + ops->end(); + } + return rc; + } +} + +#define FLASH_WRAP_CMD 0x77 +esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode) +{ + uint32_t reg_bkp_ctrl = SPIFLASH.ctrl.val; + uint32_t reg_bkp_usr = SPIFLASH.user.val; + SPIFLASH.user.fwrite_dio = 0; + SPIFLASH.user.fwrite_dual = 0; + SPIFLASH.user.fwrite_qio = 1; + SPIFLASH.user.fwrite_quad = 0; + SPIFLASH.ctrl.fcmd_dual = 0; + SPIFLASH.ctrl.fcmd_quad = 0; + SPIFLASH.user.usr_dummy = 0; + SPIFLASH.user.usr_addr = 1; + SPIFLASH.user.usr_command = 1; + SPIFLASH.user2.usr_command_bitlen = 7; + SPIFLASH.user2.usr_command_value = FLASH_WRAP_CMD; + SPIFLASH.user1.usr_addr_bitlen = 23; + SPIFLASH.addr = 0; + SPIFLASH.user.usr_miso = 0; + SPIFLASH.user.usr_mosi = 1; + SPIFLASH.mosi_dlen.usr_mosi_bit_len = 7; + SPIFLASH.data_buf[0] = (uint32_t) mode << 4;; + SPIFLASH.cmd.usr = 1; + while (SPIFLASH.cmd.usr != 0) + { } + + SPIFLASH.ctrl.val = reg_bkp_ctrl; + SPIFLASH.user.val = reg_bkp_usr; + return ESP_OK; +} + +esp_err_t spi_flash_enable_wrap(uint32_t wrap_size) +{ + switch (wrap_size) { + case 8: + return spi_flash_wrap_set(FLASH_WRAP_MODE_8B); + case 16: + return spi_flash_wrap_set(FLASH_WRAP_MODE_16B); + case 32: + return spi_flash_wrap_set(FLASH_WRAP_MODE_32B); + case 64: + return spi_flash_wrap_set(FLASH_WRAP_MODE_64B); + default: + return ESP_FAIL; + } +} + +void spi_flash_disable_wrap(void) +{ + spi_flash_wrap_set(FLASH_WRAP_MODE_DISABLE); +} + +bool spi_flash_support_wrap_size(uint32_t wrap_size) +{ + if (!REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FREAD_QIO) || !REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FASTRD_MODE)) { + return ESP_FAIL; + } + switch (wrap_size) { + case 0: + case 8: + case 16: + case 32: + case 64: + return true; + default: + return false; + } +} diff --git a/components/spi_flash/esp32c3/spi_flash_rom_patch.c b/components/spi_flash/esp32c3/spi_flash_rom_patch.c new file mode 100644 index 0000000000..7180f3883f --- /dev/null +++ b/components/spi_flash/esp32c3/spi_flash_rom_patch.c @@ -0,0 +1,26 @@ +// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "sdkconfig.h" +#include "esp32c3/rom/spi_flash.h" +#include "soc/spi_periph.h" +#include "spi_flash_defs.h" + +#define SPI_IDX 1 + +esp_rom_spiflash_result_t esp_rom_spiflash_write_disable(void) +{ + REG_WRITE(SPI_MEM_CMD_REG(SPI_IDX), SPI_MEM_FLASH_WRDI); + while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0); + return ESP_ROM_SPIFLASH_RESULT_OK; +} diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index 2a44c0e73e..bc9bede10b 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -23,8 +23,6 @@ #include "sdkconfig.h" #include "esp_flash_internal.h" -#include "spi_flash_chip_generic.h" //for spi_flash_chip_generic_yield() - static const char TAG[] = "spi_flash"; #ifdef CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE @@ -70,10 +68,12 @@ _Static_assert(sizeof(io_mode_str)/IO_STR_LEN == SPI_FLASH_READ_MODE_MAX, "the i esp_err_t esp_flash_read_chip_id(esp_flash_t* chip, uint32_t* flash_id); +#ifndef CONFIG_SPI_FLASH_ROM_IMPL static esp_err_t spiflash_start_default(esp_flash_t *chip); static esp_err_t spiflash_end_default(esp_flash_t *chip, esp_err_t err); static esp_err_t check_chip_pointer_default(esp_flash_t **inout_chip); static esp_err_t flash_end_flush_cache(esp_flash_t* chip, esp_err_t err, bool bus_acquired, uint32_t address, uint32_t length); +#endif //CONFIG_SPI_FLASH_ROM_IMPL typedef struct { esp_err_t (*start)(esp_flash_t *chip); @@ -82,6 +82,7 @@ typedef struct { esp_err_t (*flash_end_flush_cache)(esp_flash_t* chip, esp_err_t err, bool bus_acquired, uint32_t address, uint32_t length); } rom_spiflash_api_func_t; +#ifndef CONFIG_SPI_FLASH_ROM_IMPL // These functions can be placed in the ROM. For now we use the code in IDF. DRAM_ATTR static rom_spiflash_api_func_t default_spiflash_rom_api = { .start = spiflash_start_default, @@ -91,12 +92,17 @@ DRAM_ATTR static rom_spiflash_api_func_t default_spiflash_rom_api = { }; DRAM_ATTR rom_spiflash_api_func_t *rom_spiflash_api_funcs = &default_spiflash_rom_api; +#else +extern rom_spiflash_api_func_t *esp_flash_api_funcs; +#define rom_spiflash_api_funcs esp_flash_api_funcs +#endif // CONFIG_SPI_FLASH_ROM_IMPL /* Static function to notify OS of a new SPI flash operation. If returns an error result, caller must abort. If returns ESP_OK, caller must call rom_spiflash_api_funcs->end() before returning. */ +#ifndef CONFIG_SPI_FLASH_ROM_IMPL static esp_err_t IRAM_ATTR spiflash_start_default(esp_flash_t *chip) { if (chip->os_func != NULL && chip->os_func->start != NULL) { @@ -155,10 +161,7 @@ static IRAM_ATTR esp_err_t flash_end_flush_cache(esp_flash_t* chip, esp_err_t er } return rom_spiflash_api_funcs->end(chip, err); } - - -/* Return true if regions 'a' and 'b' overlap at all, based on their start offsets and lengths. */ -inline static bool regions_overlap(uint32_t a_start, uint32_t a_len,uint32_t b_start, uint32_t b_len); +#endif //CONFIG_SPI_FLASH_ROM_IMPL /* Top-level API functions, calling into chip_drv functions via chip->drv */ @@ -270,6 +273,7 @@ esp_err_t esp_flash_read_chip_id(esp_flash_t* chip, uint32_t* out_id) return read_id_core(chip, out_id, true); } +#ifndef CONFIG_SPI_FLASH_ROM_IMPL esp_err_t esp_flash_read_id(esp_flash_t* chip, uint32_t* out_id) { esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); @@ -279,6 +283,7 @@ esp_err_t esp_flash_read_id(esp_flash_t* chip, uint32_t* out_id) return read_id_core(chip, out_id, false); } +#endif //CONFIG_SPI_FLASH_ROM_IMPL static esp_err_t IRAM_ATTR detect_spi_flash_chip(esp_flash_t *chip) { @@ -316,6 +321,8 @@ static esp_err_t IRAM_ATTR detect_spi_flash_chip(esp_flash_t *chip) return ESP_OK; } +#ifndef CONFIG_SPI_FLASH_ROM_IMPL + /* Convenience macro for beginning of all API functions. * Check the return value of `rom_spiflash_api_funcs->chip_check` is correct, * and the chip supports the operation in question. @@ -327,6 +334,9 @@ static esp_err_t IRAM_ATTR detect_spi_flash_chip(esp_flash_t *chip) } \ } while (0) +/* Return true if regions 'a' and 'b' overlap at all, based on their start offsets and lengths. */ +inline static bool regions_overlap(uint32_t a_start, uint32_t a_len,uint32_t b_start, uint32_t b_len); + esp_err_t IRAM_ATTR esp_flash_get_size(esp_flash_t *chip, uint32_t *out_size) { esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); @@ -358,9 +368,11 @@ esp_err_t IRAM_ATTR esp_flash_erase_chip(esp_flash_t *chip) CHECK_WRITE_ADDRESS(chip, 0, chip->size); //check before the operation, in case this is called too close to the last operation - err = spi_flash_chip_generic_yield(chip, false); - if (err != ESP_OK) { - return err; + if (chip->chip_drv->yield) { + err = chip->chip_drv->yield(chip, 0); + if (err != ESP_OK) { + return err; + } } err = rom_spiflash_api_funcs->start(chip); @@ -432,9 +444,11 @@ esp_err_t IRAM_ATTR esp_flash_erase_region(esp_flash_t *chip, uint32_t start, ui bool bus_acquired = false; while (1) { //check before the operation, in case this is called too close to the last operation - err = spi_flash_chip_generic_yield(chip, false); - if (err != ESP_OK) { - break; + if (chip->chip_drv->yield) { + err = chip->chip_drv->yield(chip, 0); + if (err != ESP_OK) { + return err; + } } err = rom_spiflash_api_funcs->start(chip); @@ -707,9 +721,11 @@ esp_err_t IRAM_ATTR esp_flash_write(esp_flash_t *chip, const void *buffer, uint3 } //check before the operation, in case this is called too close to the last operation - err = spi_flash_chip_generic_yield(chip, false); - if (err != ESP_OK) { - break; + if (chip->chip_drv->yield) { + err = chip->chip_drv->yield(chip, 0); + if (err != ESP_OK) { + return err; + } } err = rom_spiflash_api_funcs->start(chip); @@ -814,6 +830,7 @@ IRAM_ATTR esp_err_t esp_flash_set_io_mode(esp_flash_t* chip, bool qe) err = chip->chip_drv->set_io_mode(chip); return rom_spiflash_api_funcs->end(chip, err); } +#endif //CONFIG_SPI_FLASH_ROM_IMPL #ifndef CONFIG_SPI_FLASH_USE_LEGACY_IMPL esp_err_t esp_flash_app_disable_protect(bool disable) diff --git a/components/spi_flash/esp_flash_spi_init.c b/components/spi_flash/esp_flash_spi_init.c index de764901c7..64cef8c75e 100644 --- a/components/spi_flash/esp_flash_spi_init.c +++ b/components/spi_flash/esp_flash_spi_init.c @@ -87,12 +87,18 @@ __attribute__((unused)) static const char TAG[] = "spi_flash"; .iomux = true, \ .input_delay_ns = 0,\ } +#elif CONFIG_IDF_TARGET_ESP32C3 +#include "esp32c3/rom/efuse.h" +#define ESP_FLASH_HOST_CONFIG_DEFAULT() (memspi_host_config_t){ \ + .host_id = SPI_HOST,\ + .speed = DEFAULT_FLASH_SPEED, \ + .cs_num = 0, \ + .iomux = true, \ + .input_delay_ns = 0,\ +} #endif -esp_flash_t *esp_flash_default_chip = NULL; - - static IRAM_ATTR NOINLINE_ATTR void cs_initialize(esp_flash_t *chip, const esp_flash_spi_device_config_t *config, bool use_iomux, int cs_id) { //Not using spicommon_cs_initialize since we don't want to put the whole @@ -111,11 +117,15 @@ static IRAM_ATTR NOINLINE_ATTR void cs_initialize(esp_flash_t *chip, const esp_f if (use_iomux) { PIN_FUNC_SELECT(iomux_reg, spics_func); } else { +#if CONFIG_IDF_TARGET_ESP32C3 + GPIO.enable_w1ts.val = (0x1 << cs_io_num); +#else if (cs_io_num < 32) { GPIO.enable_w1ts = (0x1 << cs_io_num); } else { GPIO.enable1_w1ts.data = (0x1 << (cs_io_num - 32)); } +#endif GPIO.pin[cs_io_num].pad_driver = 0; esp_rom_gpio_connect_out_signal(cs_io_num, spics_out, false, false); if (cs_id == 0) { @@ -208,10 +218,14 @@ esp_err_t spi_bus_remove_flash_device(esp_flash_t *chip) return ESP_OK; } - /* The default (ie initial boot) no-OS ROM esp_flash_os_functions_t */ extern const esp_flash_os_functions_t esp_flash_noos_functions; +/* This pointer is defined in ROM and extern-ed on targets where CONFIG_SPI_FLASH_ROM_IMPL = y*/ +#if !CONFIG_SPI_FLASH_ROM_IMPL +esp_flash_t *esp_flash_default_chip = NULL; +#endif + #ifndef CONFIG_SPI_FLASH_USE_LEGACY_IMPL static DRAM_ATTR memspi_host_inst_t esp_flash_default_host; @@ -224,6 +238,7 @@ static DRAM_ATTR esp_flash_t default_chip = { esp_err_t esp_flash_init_default_chip(void) { + const esp_rom_spiflash_chip_t *legacy_chip = &g_rom_flashchip; memspi_host_config_t cfg = ESP_FLASH_HOST_CONFIG_DEFAULT(); #if !CONFIG_IDF_TARGET_ESP32 @@ -243,14 +258,15 @@ esp_err_t esp_flash_init_default_chip(void) if (err != ESP_OK) { return err; } - if (default_chip.size < g_rom_flashchip.chip_size) { - ESP_EARLY_LOGE(TAG, "Detected size(%dk) smaller than the size in the binary image header(%dk). Probe failed.", default_chip.size/1024, g_rom_flashchip.chip_size/1024); + if (default_chip.size < legacy_chip->chip_size) { + ESP_EARLY_LOGE(TAG, "Detected size(%dk) smaller than the size in the binary image header(%dk). Probe failed.", default_chip.size/1024, legacy_chip->chip_size/1024); return ESP_ERR_FLASH_SIZE_NOT_MATCH; - } else if (default_chip.size > g_rom_flashchip.chip_size) { - ESP_EARLY_LOGW(TAG, "Detected size(%dk) larger than the size in the binary image header(%dk). Using the size in the binary image header.", default_chip.size/1024, g_rom_flashchip.chip_size/1024); - default_chip.size = g_rom_flashchip.chip_size; + } else if (default_chip.size > legacy_chip->chip_size) { + ESP_EARLY_LOGW(TAG, "Detected size(%dk) larger than the size in the binary image header(%dk). Using the size in the binary image header.", default_chip.size/1024, legacy_chip->chip_size/1024); + default_chip.size = legacy_chip->chip_size; + } else { + default_chip.size = legacy_chip->chip_size; } - default_chip.size = g_rom_flashchip.chip_size; esp_flash_default_chip = &default_chip; return ESP_OK; diff --git a/components/spi_flash/flash_mmap.c b/components/spi_flash/flash_mmap.c index aacf13a7be..1ba148f0ac 100644 --- a/components/spi_flash/flash_mmap.c +++ b/components/spi_flash/flash_mmap.c @@ -107,6 +107,8 @@ #define PAGES_LIMIT (IROM0_PAGES_END > DROM0_PAGES_END ? IROM0_PAGES_END:DROM0_PAGES_END) #define VADDR1_FIRST_USABLE_ADDR SOC_IROM_LOW +#if !CONFIG_SPI_FLASH_ROM_IMPL + typedef struct mmap_entry_{ uint32_t handle; int page; @@ -405,12 +407,16 @@ uint32_t IRAM_ATTR spi_flash_mmap_get_free_pages(spi_flash_mmap_memory_t memory) return count; } -uint32_t spi_flash_cache2phys(const void *cached) +size_t spi_flash_cache2phys(const void *cached) { intptr_t c = (intptr_t)cached; size_t cache_page; int offset = 0; +#if !CONFIG_IDF_TARGET_ESP32C3 if (c >= VADDR1_START_ADDR && c < VADDR1_FIRST_USABLE_ADDR) { +#else + if (c >= SOC_IRAM_LOW && c < VADDR1_FIRST_USABLE_ADDR) { +#endif /* IRAM address, doesn't map to flash */ return SPI_FLASH_CACHE2PHYS_FAIL; } else if (c < VADDR1_FIRST_USABLE_ADDR) { @@ -564,3 +570,4 @@ IRAM_ATTR bool spi_flash_check_and_flush_cache(size_t start_addr, size_t length) } return ret; } +#endif //!CONFIG_SPI_FLASH_ROM_IMPL diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index d13b11a68f..a71624538f 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -116,8 +116,6 @@ const DRAM_ATTR spi_flash_guard_funcs_t g_flash_guard_no_os_ops = { .yield = NULL, }; -static const spi_flash_guard_funcs_t *s_flash_guard_ops; - #ifdef CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS #define UNSAFE_WRITE_ADDRESS abort() #else @@ -132,7 +130,7 @@ static const spi_flash_guard_funcs_t *s_flash_guard_ops; #define CHECK_WRITE_ADDRESS(ADDR, SIZE) #else /* FAILS or ABORTS */ #define CHECK_WRITE_ADDRESS(ADDR, SIZE) do { \ - if (s_flash_guard_ops && s_flash_guard_ops->is_safe_write_address && !s_flash_guard_ops->is_safe_write_address(ADDR, SIZE)) { \ + if (guard && guard->is_safe_write_address && !guard->is_safe_write_address(ADDR, SIZE)) { \ return ESP_ERR_INVALID_ARG; \ } \ } while(0) @@ -146,14 +144,39 @@ static __attribute__((unused)) bool is_safe_write_address(size_t addr, size_t si return true; } +#if CONFIG_SPI_FLASH_ROM_IMPL +#include "esp_heap_caps.h" +typedef void *(*malloc_internal_cb_t)(size_t size); + +void IRAM_ATTR *spi_flash_malloc_internal(size_t size) +{ + return heap_caps_malloc(size, MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL); +} +#endif + void spi_flash_init(void) { spi_flash_init_lock(); #if CONFIG_SPI_FLASH_ENABLE_COUNTERS spi_flash_reset_counters(); #endif + +#if CONFIG_SPI_FLASH_ROM_IMPL + spi_flash_guard_set(&g_flash_guard_default_ops); + + /* These two functions are in ROM only */ + extern void spi_flash_mmap_os_func_set(void *(*func1)(size_t size), void (*func2)(void *p)); + spi_flash_mmap_os_func_set(spi_flash_malloc_internal, heap_caps_free); + + extern esp_err_t spi_flash_mmap_page_num_init(uint32_t page_num); + spi_flash_mmap_page_num_init(128); +#endif } +#if !CONFIG_SPI_FLASH_ROM_IMPL + +static const spi_flash_guard_funcs_t *s_flash_guard_ops; + void IRAM_ATTR spi_flash_guard_set(const spi_flash_guard_funcs_t *funcs) { s_flash_guard_ops = funcs; @@ -164,6 +187,8 @@ const spi_flash_guard_funcs_t *IRAM_ATTR spi_flash_guard_get(void) return s_flash_guard_ops; } +#endif + size_t IRAM_ATTR spi_flash_get_chip_size(void) { return g_rom_flashchip.chip_size; @@ -171,29 +196,33 @@ size_t IRAM_ATTR spi_flash_get_chip_size(void) static inline void IRAM_ATTR spi_flash_guard_start(void) { - if (s_flash_guard_ops && s_flash_guard_ops->start) { - s_flash_guard_ops->start(); + const spi_flash_guard_funcs_t *guard = spi_flash_guard_get(); + if (guard && guard->start) { + guard->start(); } } static inline void IRAM_ATTR spi_flash_guard_end(void) { - if (s_flash_guard_ops && s_flash_guard_ops->end) { - s_flash_guard_ops->end(); + const spi_flash_guard_funcs_t *guard = spi_flash_guard_get(); + if (guard && guard->end) { + guard->end(); } } static inline void IRAM_ATTR spi_flash_guard_op_lock(void) { - if (s_flash_guard_ops && s_flash_guard_ops->op_lock) { - s_flash_guard_ops->op_lock(); + const spi_flash_guard_funcs_t *guard = spi_flash_guard_get(); + if (guard && guard->op_lock) { + guard->op_lock(); } } static inline void IRAM_ATTR spi_flash_guard_op_unlock(void) { - if (s_flash_guard_ops && s_flash_guard_ops->op_unlock) { - s_flash_guard_ops->op_unlock(); + const spi_flash_guard_funcs_t *guard = spi_flash_guard_get(); + if (guard && guard->op_unlock) { + guard->op_unlock(); } } @@ -232,6 +261,7 @@ static esp_rom_spiflash_result_t IRAM_ATTR spi_flash_unlock(void) esp_err_t IRAM_ATTR spi_flash_erase_sector(size_t sec) { + const spi_flash_guard_funcs_t *guard = spi_flash_guard_get(); CHECK_WRITE_ADDRESS(sec * SPI_FLASH_SEC_SIZE, SPI_FLASH_SEC_SIZE); return spi_flash_erase_range(sec * SPI_FLASH_SEC_SIZE, SPI_FLASH_SEC_SIZE); } @@ -240,6 +270,7 @@ esp_err_t IRAM_ATTR spi_flash_erase_sector(size_t sec) //deprecated, only used in compatible mode esp_err_t IRAM_ATTR spi_flash_erase_range(size_t start_addr, size_t size) { + const spi_flash_guard_funcs_t *guard = spi_flash_guard_get(); CHECK_WRITE_ADDRESS(start_addr, size); if (start_addr % SPI_FLASH_SEC_SIZE != 0) { return ESP_ERR_INVALID_ARG; @@ -379,6 +410,7 @@ static IRAM_ATTR esp_rom_spiflash_result_t spi_flash_write_inner(uint32_t target esp_err_t IRAM_ATTR spi_flash_write(size_t dst, const void *srcv, size_t size) { + const spi_flash_guard_funcs_t *guard = spi_flash_guard_get(); CHECK_WRITE_ADDRESS(dst, size); // Out of bound writes are checked in ROM code, but we can give better // error code here @@ -479,6 +511,7 @@ out: esp_err_t IRAM_ATTR spi_flash_write_encrypted(size_t dest_addr, const void *src, size_t size) { esp_err_t err = ESP_OK; + const spi_flash_guard_funcs_t *guard = spi_flash_guard_get(); CHECK_WRITE_ADDRESS(dest_addr, size); if ((dest_addr % 16) != 0) { return ESP_ERR_INVALID_ARG; diff --git a/components/spi_flash/include/spi_flash_chip_driver.h b/components/spi_flash/include/spi_flash_chip_driver.h index 349adbe571..83668b0df9 100644 --- a/components/spi_flash/include/spi_flash_chip_driver.h +++ b/components/spi_flash/include/spi_flash_chip_driver.h @@ -182,6 +182,10 @@ struct spi_flash_chip_t { * Read the requested register (status, etc.). */ esp_err_t (*read_reg)(esp_flash_t *chip, spi_flash_register_t reg_id, uint32_t* out_reg); + + /** Yield to other tasks. Called during erase operations. */ + esp_err_t (*yield)(esp_flash_t *chip, uint32_t wip); + }; /* Pointer to an array of pointers to all known drivers for flash chips. This array is used diff --git a/components/spi_flash/include/spi_flash_chip_gd.h b/components/spi_flash/include/spi_flash_chip_gd.h index 0d52435a38..09e1661174 100644 --- a/components/spi_flash/include/spi_flash_chip_gd.h +++ b/components/spi_flash/include/spi_flash_chip_gd.h @@ -29,4 +29,8 @@ * chips, and GD25LQ chips, WRSR (01H) command is used; while WRSR2 (31H) is used for GD25Q32 - * GD25Q127 chips. */ +esp_err_t spi_flash_chip_gd_probe(esp_flash_t *chip, uint32_t flash_id); +esp_err_t spi_flash_chip_gd_set_io_mode(esp_flash_t *chip); +esp_err_t spi_flash_chip_gd_get_io_mode(esp_flash_t *chip, esp_flash_io_mode_t* out_io_mode); + extern const spi_flash_chip_t esp_flash_chip_gd; diff --git a/components/spi_flash/include/spi_flash_chip_generic.h b/components/spi_flash/include/spi_flash_chip_generic.h index 1b54e0740e..0469a438a6 100644 --- a/components/spi_flash/include/spi_flash_chip_generic.h +++ b/components/spi_flash/include/spi_flash_chip_generic.h @@ -392,7 +392,7 @@ esp_err_t spi_flash_chip_generic_config_host_io_mode(esp_flash_t *chip, bool add * @param wip Write (erase) in progress, `true` if this function is called during waiting idle of a erase/write command; else `false`. * @return ESP_OK if success, otherwise failed. */ -esp_err_t spi_flash_chip_generic_yield(esp_flash_t* chip, bool wip); +esp_err_t spi_flash_chip_generic_yield(esp_flash_t* chip, uint32_t wip); /// Default timeout configuration used by most chips const flash_chip_op_timeout_t spi_flash_chip_generic_timeout; diff --git a/components/spi_flash/include/spi_flash_chip_issi.h b/components/spi_flash/include/spi_flash_chip_issi.h index 2b1d411552..2f1b063539 100644 --- a/components/spi_flash/include/spi_flash_chip_issi.h +++ b/components/spi_flash/include/spi_flash_chip_issi.h @@ -24,4 +24,8 @@ * default autodetection, this is used as a catchall if a more specific chip_drv * is not found. */ +esp_err_t spi_flash_chip_issi_probe(esp_flash_t *chip, uint32_t flash_id); +esp_err_t spi_flash_chip_issi_set_io_mode(esp_flash_t *chip); +esp_err_t spi_flash_chip_issi_get_io_mode(esp_flash_t *chip, esp_flash_io_mode_t* out_io_mode); + extern const spi_flash_chip_t esp_flash_chip_issi; diff --git a/components/spi_flash/memspi_host_driver.c b/components/spi_flash/memspi_host_driver.c index 63e915e2df..d9f5b6b757 100644 --- a/components/spi_flash/memspi_host_driver.c +++ b/components/spi_flash/memspi_host_driver.c @@ -22,7 +22,6 @@ #define SPI_FLASH_HAL_MAX_WRITE_BYTES 64 #define SPI_FLASH_HAL_MAX_READ_BYTES 64 -static const char TAG[] = "memspi"; DRAM_ATTR static const spi_flash_host_driver_t esp_flash_default_host = ESP_FLASH_DEFAULT_HOST_DRIVER(); #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 @@ -73,12 +72,20 @@ esp_err_t memspi_host_init_pointers(memspi_host_inst_t *host, const memspi_host_ else { host->inst.driver = &esp_flash_gpspi_host; } +#elif CONFIG_IDF_TARGET_ESP32C3 + if (cfg->host_id == SPI_HOST) { + host->inst.driver = &esp_flash_default_host; + } #endif esp_err_t err = spi_flash_hal_init(host, cfg); return err; } +#ifndef CONFIG_SPI_FLASH_ROM_IMPL + +static const char TAG[] = "memspi"; + esp_err_t memspi_host_read_id_hs(spi_flash_host_inst_t *host, uint32_t *id) { uint32_t id_buf = 0; @@ -214,3 +221,5 @@ int memspi_host_read_data_slicer(spi_flash_host_inst_t *host, uint32_t address, *align_address = address; return MIN(max_len, len); } + +#endif // CONFIG_SPI_FLASH_ROM_IMPL diff --git a/components/spi_flash/spi_flash_chip_gd.c b/components/spi_flash/spi_flash_chip_gd.c index 6f710817be..c7c1005cf9 100644 --- a/components/spi_flash/spi_flash_chip_gd.c +++ b/components/spi_flash/spi_flash_chip_gd.c @@ -14,8 +14,11 @@ #include #include "spi_flash_chip_generic.h" +#include "spi_flash_chip_gd.h" #include "spi_flash_defs.h" +#ifndef CONFIG_SPI_FLASH_ROM_IMPL + #define FLASH_ID_MASK 0xFF00 #define FLASH_SIZE_MASK 0xFF #define GD25Q_PRODUCT_ID 0x4000 @@ -70,7 +73,7 @@ esp_err_t spi_flash_chip_gd_get_io_mode(esp_flash_t *chip, esp_flash_io_mode_t* } return ret; } - +#endif //CONFIG_SPI_FLASH_ROM_IMPL static const char chip_name[] = "gd"; @@ -107,4 +110,5 @@ const spi_flash_chip_t esp_flash_chip_gd = { .get_io_mode = spi_flash_chip_gd_get_io_mode, .read_reg = spi_flash_chip_generic_read_reg, + .yield = spi_flash_chip_generic_yield, }; diff --git a/components/spi_flash/spi_flash_chip_generic.c b/components/spi_flash/spi_flash_chip_generic.c index e36d443e6b..9ef7afe495 100644 --- a/components/spi_flash/spi_flash_chip_generic.c +++ b/components/spi_flash/spi_flash_chip_generic.c @@ -20,10 +20,6 @@ #include "esp_log.h" #include "esp_attr.h" - -static const char TAG[] = "chip_generic"; - - typedef struct flash_chip_dummy { uint8_t dio_dummy_bitlen; uint8_t qio_dummy_bitlen; @@ -62,6 +58,10 @@ const DRAM_ATTR flash_chip_op_timeout_t spi_flash_chip_generic_timeout = { .page_program_timeout = SPI_FLASH_GENERIC_PAGE_PROGRAM_TIMEOUT_MS * 1000, }; +#ifndef CONFIG_SPI_FLASH_ROM_IMPL + +static const char TAG[] = "chip_generic"; + esp_err_t spi_flash_chip_generic_probe(esp_flash_t *chip, uint32_t flash_id) { // This is the catch-all probe function, claim the chip always if nothing @@ -322,7 +322,7 @@ esp_err_t spi_flash_chip_generic_read_reg(esp_flash_t* chip, spi_flash_register_ return chip->host->driver->read_status(chip->host, (uint8_t*)out_reg); } -esp_err_t spi_flash_chip_generic_yield(esp_flash_t* chip, bool wip) +esp_err_t spi_flash_chip_generic_yield(esp_flash_t* chip, uint32_t wip) { esp_err_t err = ESP_OK; uint32_t flags = wip? 1: 0; //check_yield() and yield() impls should not issue suspend/resume if this flag is zero @@ -472,6 +472,7 @@ esp_err_t spi_flash_chip_generic_set_io_mode(esp_flash_t *chip) spi_flash_common_read_status_16b_rdsr_rdsr2, BIT_QE); } +#endif // CONFIG_SPI_FLASH_ROM_IMPL static const char chip_name[] = "generic"; @@ -509,8 +510,10 @@ const spi_flash_chip_t esp_flash_chip_generic = { .get_io_mode = spi_flash_chip_generic_get_io_mode, .read_reg = spi_flash_chip_generic_read_reg, + .yield = spi_flash_chip_generic_yield, }; +#ifndef CONFIG_SPI_FLASH_ROM_IMPL /******************************************************************************* * Utility functions ******************************************************************************/ @@ -647,3 +650,5 @@ esp_err_t spi_flash_common_set_io_mode(esp_flash_t *chip, esp_flash_wrsr_func_t } return ret; } + +#endif // !CONFIG_SPI_FLASH_ROM_IMPL diff --git a/components/spi_flash/spi_flash_chip_issi.c b/components/spi_flash/spi_flash_chip_issi.c index 7759e61438..6bb13f9e44 100644 --- a/components/spi_flash/spi_flash_chip_issi.c +++ b/components/spi_flash/spi_flash_chip_issi.c @@ -14,6 +14,7 @@ #include #include "spi_flash_chip_generic.h" +#include "spi_flash_chip_issi.h" #include "spi_flash_defs.h" /* Driver for ISSI flash chip, as used in ESP32 D2WD */ @@ -93,4 +94,5 @@ const spi_flash_chip_t esp_flash_chip_issi = { .get_io_mode = spi_flash_chip_issi_get_io_mode, .read_reg = spi_flash_chip_generic_read_reg, + .yield = spi_flash_chip_generic_yield, }; diff --git a/components/spi_flash/spi_flash_chip_mxic.c b/components/spi_flash/spi_flash_chip_mxic.c index 8159269e36..750e765221 100644 --- a/components/spi_flash/spi_flash_chip_mxic.c +++ b/components/spi_flash/spi_flash_chip_mxic.c @@ -72,4 +72,5 @@ const spi_flash_chip_t esp_flash_chip_mxic = { .get_io_mode = spi_flash_chip_mxic_get_io_mode, .read_reg = spi_flash_chip_mxic_read_reg, + .yield = spi_flash_chip_generic_yield, }; diff --git a/components/spi_flash/spi_flash_chip_winbond.c b/components/spi_flash/spi_flash_chip_winbond.c index b45ee34603..73ab2f09b4 100644 --- a/components/spi_flash/spi_flash_chip_winbond.c +++ b/components/spi_flash/spi_flash_chip_winbond.c @@ -175,6 +175,7 @@ const spi_flash_chip_t esp_flash_chip_winbond = { .get_io_mode = spi_flash_chip_generic_get_io_mode, .read_reg = spi_flash_chip_generic_read_reg, + .yield = spi_flash_chip_generic_yield, }; diff --git a/components/spi_flash/spi_flash_os_func_noos.c b/components/spi_flash/spi_flash_os_func_noos.c index a50878ba3f..bc48ea0665 100644 --- a/components/spi_flash/spi_flash_os_func_noos.c +++ b/components/spi_flash/spi_flash_os_func_noos.c @@ -38,6 +38,12 @@ typedef struct { uint32_t dcache_autoload; } spi_noos_arg_t; +static DRAM_ATTR spi_noos_arg_t spi_arg = { 0 }; +#elif CONFIG_IDF_TARGET_ESP32C3 +typedef struct { + uint32_t icache_autoload; +} spi_noos_arg_t; + static DRAM_ATTR spi_noos_arg_t spi_arg = { 0 }; #endif @@ -50,6 +56,9 @@ static IRAM_ATTR esp_err_t start(void *arg) spi_noos_arg_t *spi_arg = arg; spi_arg->icache_autoload = Cache_Suspend_ICache(); spi_arg->dcache_autoload = Cache_Suspend_DCache(); +#elif CONFIG_IDF_TARGET_ESP32C3 + spi_noos_arg_t *spi_arg = arg; + spi_arg->icache_autoload = Cache_Suspend_ICache(); #endif return ESP_OK; } @@ -80,6 +89,13 @@ static IRAM_ATTR esp_err_t delay_us(void *arg, uint32_t us) return ESP_OK; } +// Currently when the os is not up yet, the caller is supposed to call esp_flash APIs with proper +// buffers. +IRAM_ATTR void* get_temp_buffer_not_supported(void* arg, size_t reqest_size, size_t* out_size) +{ + return NULL; +} + const DRAM_ATTR esp_flash_os_functions_t esp_flash_noos_functions = { .start = start, .end = end, diff --git a/components/spi_flash/test/test_esp_flash.c b/components/spi_flash/test/test_esp_flash.c index 6c11099749..7588fa1511 100644 --- a/components/spi_flash/test/test_esp_flash.c +++ b/components/spi_flash/test/test_esp_flash.c @@ -22,6 +22,7 @@ #include "ccomp_timer.h" #include "esp_rom_gpio.h" #include "esp_rom_sys.h" +#include "esp_timer.h" #define FUNC_SPI 1 @@ -82,6 +83,26 @@ static uint8_t sector_buf[4096]; #define FSPI_PIN_NUM_WP 38 #define FSPI_PIN_NUM_CS 34 +// Just use the same pins for HSPI +#define HSPI_PIN_NUM_MOSI FSPI_PIN_NUM_MOSI +#define HSPI_PIN_NUM_MISO FSPI_PIN_NUM_MISO +#define HSPI_PIN_NUM_CLK FSPI_PIN_NUM_CLK +#define HSPI_PIN_NUM_HD FSPI_PIN_NUM_HD +#define HSPI_PIN_NUM_WP FSPI_PIN_NUM_WP +#define HSPI_PIN_NUM_CS FSPI_PIN_NUM_CS + +#elif CONFIG_IDF_TARGET_ESP32C3 +#define SPI1_CS_IO 26 //the pin which is usually used by the PSRAM cs +#define SPI1_HD_IO 27 //the pin which is usually used by the PSRAM hd +#define SPI1_WP_IO 28 //the pin which is usually used by the PSRAM wp + +#define FSPI_PIN_NUM_MOSI 7 +#define FSPI_PIN_NUM_MISO 2 +#define FSPI_PIN_NUM_CLK 6 +#define FSPI_PIN_NUM_HD 4 +#define FSPI_PIN_NUM_WP 5 +#define FSPI_PIN_NUM_CS 10 + // Just use the same pins for HSPI #define HSPI_PIN_NUM_MOSI FSPI_PIN_NUM_MOSI #define HSPI_PIN_NUM_MISO FSPI_PIN_NUM_MISO @@ -108,7 +129,8 @@ typedef void (*flash_test_func_t)(const esp_partition_t *part); These tests run for all the flash chip configs shown in config_list, below (internal and external). */ -#if defined(CONFIG_SPIRAM) +#if defined(CONFIG_SPIRAM) || TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3) + #define FLASH_TEST_CASE_3(STR, FUNCT_TO_RUN) #define FLASH_TEST_CASE_3_IGNORE(STR, FUNCT_TO_RUN) #else @@ -188,7 +210,20 @@ flashtest_config_t config_list[] = { #elif CONFIG_IDF_TARGET_ESP32S3 flashtest_config_t config_list[] = { FLASHTEST_CONFIG_COMMON, - /* No runners for esp32s2 for these config yet */ + /* No runners for esp32s3 for these config yet */ + { + .io_mode = TEST_SPI_READ_MODE, + .speed = TEST_SPI_SPEED, + .host_id = FSPI_HOST, + .cs_id = 0, + .cs_io_num = FSPI_PIN_NUM_CS, + .input_delay_ns = 0, + }, +}; +#elif CONFIG_IDF_TARGET_ESP32C3 +flashtest_config_t config_list[] = { + FLASHTEST_CONFIG_COMMON, + /* No runners for esp32c3 for these config yet */ { .io_mode = TEST_SPI_READ_MODE, .speed = TEST_SPI_SPEED, @@ -197,16 +232,6 @@ flashtest_config_t config_list[] = { .cs_io_num = FSPI_PIN_NUM_CS, .input_delay_ns = 0, }, - // /* current runner doesn't have a flash on HSPI */ - // { - // .io_mode = TEST_SPI_READ_MODE, - // .speed = TEST_SPI_SPEED, - // .host_id = HSPI_HOST, - // .cs_id = 0, - // // uses GPIO matrix on esp32s2 regardless if FORCE_GPIO_MATRIX - // .cs_io_num = HSPI_PIN_NUM_CS, - // .input_delay_ns = 20, - // }, }; #endif @@ -296,7 +321,7 @@ static void setup_bus(spi_host_device_t host_id) gpio_set_level(HSPI_PIN_NUM_WP, 1); #endif } -#if !DISABLED_FOR_TARGETS(ESP32S2, ESP32S3) +#if !DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C3) else if (host_id == VSPI_HOST) { ESP_LOGI(TAG, "setup flash on SPI%d (VSPI) CS0...\n", host_id + 1); spi_bus_config_t vspi_bus_cfg = { @@ -801,12 +826,14 @@ TEST_CASE("SPI flash test reading with all speed/mode permutations", "[esp_flash } #ifndef CONFIG_SPIRAM +#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3) TEST_CASE("SPI flash test reading with all speed/mode permutations, 3 chips", "[esp_flash_3][test_env=UT_T1_ESP_FLASH]") { for (int i = 0; i < TEST_CONFIG_NUM; i++) { test_permutations_chip(&config_list[i]); } } +#endif //TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3) #endif diff --git a/components/spi_flash/test/test_mmap.c b/components/spi_flash/test/test_mmap.c index ab0772eceb..047fe4328c 100644 --- a/components/spi_flash/test/test_mmap.c +++ b/components/spi_flash/test/test_mmap.c @@ -153,6 +153,9 @@ TEST_CASE("Can mmap into data address space", "[spi_flash][mmap]") TEST_ASSERT_EQUAL_PTR(NULL, spi_flash_phys2cache(start, SPI_FLASH_MMAP_DATA)); } +#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3) +// TODO ESP32C3 IDF-2458 + TEST_CASE("Can mmap into instruction address space", "[spi_flash][mmap]") { setup_mmap_tests(); @@ -209,6 +212,9 @@ TEST_CASE("Can mmap into instruction address space", "[spi_flash][mmap]") } +#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3) + + TEST_CASE("Can mmap unordered pages into contiguous memory", "[spi_flash][mmap]") { int nopages; @@ -352,7 +358,8 @@ TEST_CASE("phys2cache/cache2phys basic checks", "[spi_flash][mmap]") { uint8_t buf[64]; - static const uint8_t constant_data[] = { 1, 2, 3, 7, 11, 16, 3, 88 }; + /* Avoid put constant data in the sdata/sdata2 section */ + static const uint8_t constant_data[] = { 1, 2, 3, 7, 11, 16, 3, 88, 99}; /* esp_partition_find is in IROM */ uint32_t phys = spi_flash_cache2phys(esp_partition_find); diff --git a/components/spi_flash/test/test_read_write.c b/components/spi_flash/test/test_read_write.c index eb74b90a12..a4128be540 100644 --- a/components/spi_flash/test/test_read_write.c +++ b/components/spi_flash/test/test_read_write.c @@ -238,7 +238,7 @@ TEST_CASE("Test spi_flash_write", "[spi_flash][esp_flash]") * NB: At the moment these only support aligned addresses, because memcpy * is not aware of the 32-but load requirements for these regions. */ -#ifdef CONFIG_IDF_TARGET_ESP32S2 +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 #define TEST_SOC_IROM_ADDR (SOC_IROM_LOW) #define TEST_SOC_CACHE_RAM_BANK0_ADDR (SOC_IRAM_LOW) #define TEST_SOC_CACHE_RAM_BANK1_ADDR (SOC_IRAM_LOW + 0x2000) diff --git a/components/spi_flash/test/test_spi_flash.c b/components/spi_flash/test/test_spi_flash.c index 901a0e7a5f..bb7673ca63 100644 --- a/components/spi_flash/test/test_spi_flash.c +++ b/components/spi_flash/test/test_spi_flash.c @@ -13,6 +13,7 @@ #include "ccomp_timer.h" #include "esp_log.h" #include "esp_rom_sys.h" +#include "esp_timer.h" #include "sdkconfig.h" #if CONFIG_IDF_TARGET_ESP32 @@ -21,6 +22,8 @@ #include "esp32s2/rom/spi_flash.h" #elif CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32C3 +#include "esp32c3/rom/spi_flash.h" #endif struct flash_test_ctx { @@ -391,9 +394,9 @@ TEST_CASE("spi_flash deadlock with high priority busy-waiting task", "[spi_flash TEST_CASE("WEL is cleared after boot", "[spi_flash]") { - extern esp_rom_spiflash_chip_t g_rom_spiflash_chip; + esp_rom_spiflash_chip_t *legacy_chip = &g_rom_flashchip; uint32_t status; - esp_rom_spiflash_read_status(&g_rom_spiflash_chip, &status); + esp_rom_spiflash_read_status(legacy_chip, &status); TEST_ASSERT((status & 0x2) == 0); } @@ -402,15 +405,15 @@ TEST_CASE("WEL is cleared after boot", "[spi_flash]") // ISSI chip has its QE bit on other chips' BP4, which may get cleared by accident TEST_CASE("rom unlock will not erase QE bit", "[spi_flash]") { - extern esp_rom_spiflash_chip_t g_rom_spiflash_chip; + esp_rom_spiflash_chip_t *legacy_chip = &g_rom_flashchip; uint32_t status; - printf("dev_id: %08X \n", g_rom_spiflash_chip.device_id); + printf("dev_id: %08X \n", legacy_chip->device_id); - if (((g_rom_spiflash_chip.device_id >> 16) & 0xff) != 0x9D) { + if (((legacy_chip->device_id >> 16) & 0xff) != 0x9D) { TEST_IGNORE_MESSAGE("This test is only for ISSI chips. Ignore."); } esp_rom_spiflash_unlock(); - esp_rom_spiflash_read_status(&g_rom_spiflash_chip, &status); + esp_rom_spiflash_read_status(legacy_chip, &status); printf("status: %08x\n", status); TEST_ASSERT(status & 0x40); From 0736c91d68a0f4eff59effcf3fa832eb762d5851 Mon Sep 17 00:00:00 2001 From: Cao Sen Miao Date: Wed, 9 Dec 2020 12:22:55 +0800 Subject: [PATCH 2/3] soc: Remove cache constants from soc.h --- components/soc/esp32/include/soc/mmu.h | 42 ++++++ components/soc/esp32c3/include/soc/mmu.h | 42 ++++++ components/soc/esp32c3/include/soc/soc.h | 16 --- components/soc/esp32s2/include/soc/mmu.h | 42 ++++++ components/soc/esp32s3/include/soc/mmu.h | 42 ++++++ components/spi_flash/flash_mmap.c | 163 +++++++++-------------- 6 files changed, 228 insertions(+), 119 deletions(-) create mode 100644 components/soc/esp32/include/soc/mmu.h create mode 100644 components/soc/esp32c3/include/soc/mmu.h create mode 100644 components/soc/esp32s2/include/soc/mmu.h create mode 100644 components/soc/esp32s3/include/soc/mmu.h diff --git a/components/soc/esp32/include/soc/mmu.h b/components/soc/esp32/include/soc/mmu.h new file mode 100644 index 0000000000..bde6995516 --- /dev/null +++ b/components/soc/esp32/include/soc/mmu.h @@ -0,0 +1,42 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once + +#include +#include "soc/dport_reg.h" +#include "soc/soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Defined for flash mmap */ +#define SOC_MMU_REGIONS_COUNT 4 +#define SOC_MMU_PAGES_PER_REGION 64 +#define SOC_MMU_IROM0_PAGES_START 64 +#define SOC_MMU_IROM0_PAGES_END 256 +#define SOC_MMU_DROM0_PAGES_START 0 +#define SOC_MMU_DROM0_PAGES_END 64 +#define SOC_MMU_INVALID_ENTRY_VAL DPORT_FLASH_MMU_TABLE_INVALID_VAL +#define SOC_MMU_ADDR_MASK DPORT_MMU_ADDRESS_MASK +#define SOC_MMU_PAGE_IN_FLASH(page) (page) +#define SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE ((volatile uint32_t*) 0x3FF10000) +#define SOC_MMU_VADDR1_START_ADDR SOC_IROM_MASK_LOW +#define SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE ((SOC_MMU_VADDR1_FIRST_USABLE_ADDR - SOC_MMU_VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + SOC_MMU_IROM0_PAGES_START) +#define SOC_MMU_VADDR0_START_ADDR SOC_DROM_LOW +#define SOC_MMU_VADDR1_FIRST_USABLE_ADDR SOC_IROM_LOW + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c3/include/soc/mmu.h b/components/soc/esp32c3/include/soc/mmu.h new file mode 100644 index 0000000000..d8db3d5c12 --- /dev/null +++ b/components/soc/esp32c3/include/soc/mmu.h @@ -0,0 +1,42 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once + +#include +#include "soc/cache_memory.h" +#include "soc/soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Defined for flash mmap */ +#define SOC_MMU_REGIONS_COUNT 1 +#define SOC_MMU_PAGES_PER_REGION 128 +#define SOC_MMU_IROM0_PAGES_START (CACHE_IROM_MMU_START / sizeof(uint32_t)) +#define SOC_MMU_IROM0_PAGES_END (CACHE_IROM_MMU_END / sizeof(uint32_t)) +#define SOC_MMU_DROM0_PAGES_START (CACHE_DROM_MMU_START / sizeof(uint32_t)) +#define SOC_MMU_DROM0_PAGES_END (CACHE_DROM_MMU_END / sizeof(uint32_t)) +#define SOC_MMU_INVALID_ENTRY_VAL MMU_TABLE_INVALID_VAL +#define SOC_MMU_ADDR_MASK MMU_ADDRESS_MASK +#define SOC_MMU_PAGE_IN_FLASH(page) (page) //Always in Flash +#define SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE FLASH_MMU_TABLE +#define SOC_MMU_VADDR1_START_ADDR SOC_IRAM_LOW +#define SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE SOC_MMU_IROM0_PAGES_START +#define SOC_MMU_VADDR0_START_ADDR (SOC_DROM_LOW + (SOC_MMU_DROM0_PAGES_START * SPI_FLASH_MMU_PAGE_SIZE)) +#define SOC_MMU_VADDR1_FIRST_USABLE_ADDR SOC_IROM_LOW + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c3/include/soc/soc.h b/components/soc/esp32c3/include/soc/soc.h index 544479edd0..92a40af326 100644 --- a/components/soc/esp32c3/include/soc/soc.h +++ b/components/soc/esp32c3/include/soc/soc.h @@ -262,22 +262,6 @@ // Start (highest address) of ROM boot stack, only relevant during early boot #define SOC_ROM_STACK_START 0x3fcebf10 -/* Defined for flash mmap */ -#define REGIONS_COUNT 1 -#define PAGES_PER_REGION 128 -#define IROM0_PAGES_START (CACHE_IROM_MMU_START / sizeof(uint32_t)) -#define IROM0_PAGES_END (CACHE_IROM_MMU_END / sizeof(uint32_t)) -#define DROM0_PAGES_START (CACHE_DROM_MMU_START / sizeof(uint32_t)) -#define DROM0_PAGES_END (CACHE_DROM_MMU_END / sizeof(uint32_t)) -#define INVALID_ENTRY_VAL MMU_TABLE_INVALID_VAL -#define MMU_ADDR_MASK MMU_ADDRESS_MASK -#define PAGE_IN_FLASH(page) (page) //Always in Flash -#define DPORT_PRO_FLASH_MMU_TABLE FLASH_MMU_TABLE -#define VADDR1_START_ADDR IRAM0_CACHE_ADDRESS_LOW -#define PRO_IRAM0_FIRST_USABLE_PAGE IROM0_PAGES_START -#define VADDR0_START_ADDR (SOC_DROM_LOW + (DROM0_PAGES_START * SPI_FLASH_MMU_PAGE_SIZE)) -#define VADDR1_FIRST_USABLE_ADDR SOC_IROM_LOW - //interrupt cpu using table, Please see the core-isa.h /************************************************************************************************************* * Intr num Level Type PRO CPU usage APP CPU uasge diff --git a/components/soc/esp32s2/include/soc/mmu.h b/components/soc/esp32s2/include/soc/mmu.h new file mode 100644 index 0000000000..44f716f217 --- /dev/null +++ b/components/soc/esp32s2/include/soc/mmu.h @@ -0,0 +1,42 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once + +#include +#include "soc/cache_memory.h" +#include "soc/soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Defined for flash mmap */ +#define SOC_MMU_REGIONS_COUNT 6 +#define SOC_MMU_PAGES_PER_REGION 64 +#define SOC_MMU_IROM0_PAGES_START (PRO_CACHE_IBUS0_MMU_START / sizeof(uint32_t)) +#define SOC_MMU_IROM0_PAGES_END (PRO_CACHE_IBUS1_MMU_END / sizeof(uint32_t)) +#define SOC_MMU_DROM0_PAGES_START (PRO_CACHE_IBUS2_MMU_START / sizeof(uint32_t)) +#define SOC_MMU_DROM0_PAGES_END (PRO_CACHE_IBUS2_MMU_END / sizeof(uint32_t)) +#define SOC_MMU_INVALID_ENTRY_VAL MMU_TABLE_INVALID_VAL +#define SOC_MMU_ADDR_MASK MMU_ADDRESS_MASK +#define SOC_MMU_PAGE_IN_FLASH(page) ((page) | MMU_ACCESS_FLASH) +#define SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE FLASH_MMU_TABLE +#define SOC_MMU_VADDR1_START_ADDR SOC_IROM_MASK_LOW +#define SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE ((SOC_MMU_VADDR1_FIRST_USABLE_ADDR - SOC_MMU_VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + SOC_MMU_IROM0_PAGES_START) +#define SOC_MMU_VADDR0_START_ADDR SOC_DROM_LOW +#define SOC_MMU_VADDR1_FIRST_USABLE_ADDR SOC_IROM_LOW + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32s3/include/soc/mmu.h b/components/soc/esp32s3/include/soc/mmu.h new file mode 100644 index 0000000000..a38cb9eb42 --- /dev/null +++ b/components/soc/esp32s3/include/soc/mmu.h @@ -0,0 +1,42 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once + +#include +#include "soc/cache_memory.h" +#include "soc/soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Defined for flash mmap */ +#define SOC_MMU_REGIONS_COUNT 2 +#define SOC_MMU_PAGES_PER_REGION 256 +#define SOC_MMU_IROM0_PAGES_START (CACHE_IROM_MMU_START / sizeof(uint32_t)) +#define SOC_MMU_IROM0_PAGES_END (CACHE_IROM_MMU_END / sizeof(uint32_t)) +#define SOC_MMU_DROM0_PAGES_START (CACHE_DROM_MMU_START / sizeof(uint32_t)) +#define SOC_MMU_DROM0_PAGES_END (CACHE_DROM_MMU_END / sizeof(uint32_t)) +#define SOC_MMU_INVALID_ENTRY_VAL MMU_TABLE_INVALID_VAL +#define SOC_MMU_ADDR_MASK MMU_ADDRESS_MASK +#define SOC_MMU_PAGE_IN_FLASH(page) ((page) | MMU_ACCESS_FLASH) +#define SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE FLASH_MMU_TABLE +#define SOC_MMU_VADDR1_START_ADDR IRAM0_CACHE_ADDRESS_LOW +#define SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE SOC_MMU_IROM0_PAGES_START +#define SOC_MMU_VADDR0_START_ADDR (SOC_DROM_LOW + (SOC_MMU_DROM0_PAGES_START * SPI_FLASH_MMU_PAGE_SIZE)) +#define SOC_MMU_VADDR1_FIRST_USABLE_ADDR SOC_IROM_LOW + +#ifdef __cplusplus +} +#endif diff --git a/components/spi_flash/flash_mmap.c b/components/spi_flash/flash_mmap.c index 1ba148f0ac..7b221dd064 100644 --- a/components/spi_flash/flash_mmap.c +++ b/components/spi_flash/flash_mmap.c @@ -35,22 +35,26 @@ #include "esp32/rom/cache.h" #include "esp32/rom/spi_flash.h" #include "esp32/spiram.h" +#include "soc/mmu.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/rom/cache.h" #include "esp32s2/rom/spi_flash.h" #include "esp32s2/spiram.h" #include "soc/extmem_reg.h" #include "soc/cache_memory.h" +#include "soc/mmu.h" #elif CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/rom/spi_flash.h" #include "esp32s3/rom/cache.h" #include "esp32s3/spiram.h" #include "soc/extmem_reg.h" #include "soc/cache_memory.h" +#include "soc/mmu.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rom/cache.h" #include "esp32c3/rom/spi_flash.h" #include "soc/cache_memory.h" +#include "soc/mmu.h" #endif #ifndef NDEBUG @@ -59,53 +63,9 @@ #endif #include "sys/queue.h" -#ifdef CONFIG_IDF_TARGET_ESP32 -#define PAGES_PER_REGION 64 -#define REGIONS_COUNT 4 -#define IROM0_PAGES_START 64 -#define IROM0_PAGES_END 256 -#define DROM0_PAGES_START 0 -#define DROM0_PAGES_END 64 -#define PAGE_IN_FLASH(page) (page) -#define INVALID_ENTRY_VAL DPORT_FLASH_MMU_TABLE_INVALID_VAL -#define MMU_ADDR_MASK DPORT_MMU_ADDRESS_MASK -#define VADDR1_START_ADDR 0x40000000 -#define PRO_IRAM0_FIRST_USABLE_PAGE ((VADDR1_FIRST_USABLE_ADDR - VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + IROM0_PAGES_START) -#define VADDR0_START_ADDR SOC_DROM_LOW -#elif CONFIG_IDF_TARGET_ESP32S2 -#define PAGES_PER_REGION 64 -#define REGIONS_COUNT 6 -#define IROM0_PAGES_START (PRO_CACHE_IBUS0_MMU_START / sizeof(uint32_t)) -#define IROM0_PAGES_END (PRO_CACHE_IBUS1_MMU_END / sizeof(uint32_t)) -#define DROM0_PAGES_START (PRO_CACHE_IBUS2_MMU_START / sizeof(uint32_t)) -#define DROM0_PAGES_END (PRO_CACHE_IBUS2_MMU_END / sizeof(uint32_t)) -#define DPORT_PRO_FLASH_MMU_TABLE FLASH_MMU_TABLE -#define INVALID_ENTRY_VAL MMU_TABLE_INVALID_VAL -#define MMU_ADDR_MASK MMU_ADDRESS_MASK -#define PAGE_IN_FLASH(page) ((page) | MMU_ACCESS_FLASH) -#define VADDR1_START_ADDR 0x40000000 -#define PRO_IRAM0_FIRST_USABLE_PAGE ((VADDR1_FIRST_USABLE_ADDR - VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + IROM0_PAGES_START) -#define VADDR0_START_ADDR SOC_DROM_LOW -#elif CONFIG_IDF_TARGET_ESP32S3 -#define REGIONS_COUNT 2 -#define PAGES_PER_REGION 256 -#define IROM0_PAGES_START (CACHE_IROM_MMU_START / sizeof(uint32_t)) -#define IROM0_PAGES_END (CACHE_IROM_MMU_END / sizeof(uint32_t)) -#define DROM0_PAGES_START (CACHE_DROM_MMU_START / sizeof(uint32_t)) -#define DROM0_PAGES_END (CACHE_DROM_MMU_END / sizeof(uint32_t)) -#define DPORT_PRO_FLASH_MMU_TABLE FLASH_MMU_TABLE -#define INVALID_ENTRY_VAL MMU_TABLE_INVALID_VAL -#define MMU_ADDR_MASK MMU_ADDRESS_MASK -#define PAGE_IN_FLASH(page) ((page) | MMU_ACCESS_FLASH) -#define VADDR1_START_ADDR IRAM0_CACHE_ADDRESS_LOW -#define PRO_IRAM0_FIRST_USABLE_PAGE (IROM0_PAGES_START) -#define VADDR0_START_ADDR (SOC_DROM_LOW + (DROM0_PAGES_START * SPI_FLASH_MMU_PAGE_SIZE)) -#endif - -#define IROM0_PAGES_NUM (IROM0_PAGES_END - IROM0_PAGES_START) -#define DROM0_PAGES_NUM (DROM0_PAGES_END - DROM0_PAGES_START) -#define PAGES_LIMIT (IROM0_PAGES_END > DROM0_PAGES_END ? IROM0_PAGES_END:DROM0_PAGES_END) -#define VADDR1_FIRST_USABLE_ADDR SOC_IROM_LOW +#define IROM0_PAGES_NUM (SOC_MMU_IROM0_PAGES_END - SOC_MMU_IROM0_PAGES_START) +#define DROM0_PAGES_NUM (SOC_MMU_DROM0_PAGES_END - SOC_MMU_DROM0_PAGES_START) +#define PAGES_LIMIT ((SOC_MMU_IROM0_PAGES_END > SOC_MMU_DROM0_PAGES_END) ? SOC_MMU_IROM0_PAGES_END:SOC_MMU_DROM0_PAGES_END) #if !CONFIG_SPI_FLASH_ROM_IMPL @@ -119,33 +79,33 @@ typedef struct mmap_entry_{ static LIST_HEAD(mmap_entries_head, mmap_entry_) s_mmap_entries_head = LIST_HEAD_INITIALIZER(s_mmap_entries_head); -static uint8_t s_mmap_page_refcnt[REGIONS_COUNT * PAGES_PER_REGION] = {0}; +static uint8_t s_mmap_page_refcnt[SOC_MMU_REGIONS_COUNT * SOC_MMU_PAGES_PER_REGION] = {0}; static uint32_t s_mmap_last_handle = 0; static void IRAM_ATTR spi_flash_mmap_init(void) { - if (s_mmap_page_refcnt[DROM0_PAGES_START] != 0) { + if (s_mmap_page_refcnt[SOC_MMU_DROM0_PAGES_START] != 0) { return; /* mmap data already initialised */ } DPORT_INTERRUPT_DISABLE(); - for (int i = 0; i < REGIONS_COUNT * PAGES_PER_REGION; ++i) { - uint32_t entry_pro = DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_PRO_FLASH_MMU_TABLE[i]); + for (int i = 0; i < SOC_MMU_REGIONS_COUNT * SOC_MMU_PAGES_PER_REGION; ++i) { + uint32_t entry_pro = DPORT_SEQUENCE_REG_READ((uint32_t)&SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i]); #if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32 uint32_t entry_app = DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_APP_FLASH_MMU_TABLE[i]); if (entry_pro != entry_app) { // clean up entries used by boot loader - entry_pro = INVALID_ENTRY_VAL; - DPORT_PRO_FLASH_MMU_TABLE[i] = INVALID_ENTRY_VAL; + entry_pro = SOC_MMU_INVALID_ENTRY_VAL; + SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i] = SOC_MMU_INVALID_ENTRY_VAL; } #endif - if ((entry_pro & INVALID_ENTRY_VAL) == 0 && (i == DROM0_PAGES_START || i == PRO_IRAM0_FIRST_USABLE_PAGE || entry_pro != 0)) { + if ((entry_pro & SOC_MMU_INVALID_ENTRY_VAL) == 0 && (i == SOC_MMU_DROM0_PAGES_START || i == SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE || entry_pro != 0)) { s_mmap_page_refcnt[i] = 1; } else { - DPORT_PRO_FLASH_MMU_TABLE[i] = INVALID_ENTRY_VAL; + SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i] = SOC_MMU_INVALID_ENTRY_VAL; #if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32 - DPORT_APP_FLASH_MMU_TABLE[i] = INVALID_ENTRY_VAL; + DPORT_APP_FLASH_MMU_TABLE[i] = SOC_MMU_INVALID_ENTRY_VAL; #endif } } @@ -156,14 +116,14 @@ static void IRAM_ATTR get_mmu_region(spi_flash_mmap_memory_t memory, int* out_be { if (memory == SPI_FLASH_MMAP_DATA) { // Vaddr0 - *out_begin = DROM0_PAGES_START; + *out_begin = SOC_MMU_DROM0_PAGES_START; *out_size = DROM0_PAGES_NUM; - *region_addr = VADDR0_START_ADDR; + *region_addr = SOC_MMU_VADDR0_START_ADDR; } else { // only part of VAddr1 is usable, so adjust for that - *out_begin = PRO_IRAM0_FIRST_USABLE_PAGE; - *out_size = IROM0_PAGES_END - *out_begin; - *region_addr = VADDR1_FIRST_USABLE_ADDR; + *out_begin = SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE; + *out_size = SOC_MMU_IROM0_PAGES_END - *out_begin; + *region_addr = SOC_MMU_VADDR1_FIRST_USABLE_ADDR; } } @@ -238,9 +198,9 @@ esp_err_t IRAM_ATTR spi_flash_mmap_pages(const int *pages, size_t page_count, sp int pos; DPORT_INTERRUPT_DISABLE(); for (pos = start; pos < start + page_count; ++pos, ++pageno) { - int table_val = (int) DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_PRO_FLASH_MMU_TABLE[pos]); + int table_val = (int) DPORT_SEQUENCE_REG_READ((uint32_t)&SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[pos]); uint8_t refcnt = s_mmap_page_refcnt[pos]; - if (refcnt != 0 && table_val != PAGE_IN_FLASH(pages[pageno])) { + if (refcnt != 0 && table_val != SOC_MMU_PAGE_IN_FLASH(pages[pageno])) { break; } } @@ -261,23 +221,23 @@ esp_err_t IRAM_ATTR spi_flash_mmap_pages(const int *pages, size_t page_count, sp DPORT_INTERRUPT_DISABLE(); for (int i = start; i != start + page_count; ++i, ++pageno) { // sanity check: we won't reconfigure entries with non-zero reference count - uint32_t entry_pro = DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_PRO_FLASH_MMU_TABLE[i]); + uint32_t entry_pro = DPORT_SEQUENCE_REG_READ((uint32_t)&SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i]); #if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32 uint32_t entry_app = DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_APP_FLASH_MMU_TABLE[i]); #endif assert(s_mmap_page_refcnt[i] == 0 || - (entry_pro == PAGE_IN_FLASH(pages[pageno]) + (entry_pro == SOC_MMU_PAGE_IN_FLASH(pages[pageno]) #if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32 - && entry_app == PAGE_IN_FLASH(pages[pageno]) + && entry_app == SOC_MMU_PAGE_IN_FLASH(pages[pageno]) #endif )); if (s_mmap_page_refcnt[i] == 0) { - if (entry_pro != PAGE_IN_FLASH(pages[pageno]) + if (entry_pro != SOC_MMU_PAGE_IN_FLASH(pages[pageno]) #if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32 - || entry_app != PAGE_IN_FLASH(pages[pageno]) + || entry_app != SOC_MMU_PAGE_IN_FLASH(pages[pageno]) #endif ) { - DPORT_PRO_FLASH_MMU_TABLE[i] = PAGE_IN_FLASH(pages[pageno]); + SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i] = SOC_MMU_PAGE_IN_FLASH(pages[pageno]); #if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32 DPORT_APP_FLASH_MMU_TABLE[i] = pages[pageno]; #endif @@ -338,9 +298,9 @@ void IRAM_ATTR spi_flash_munmap(spi_flash_mmap_handle_t handle) for (int i = it->page; i < it->page + it->count; ++i) { assert(s_mmap_page_refcnt[i] > 0); if (--s_mmap_page_refcnt[i] == 0) { - DPORT_PRO_FLASH_MMU_TABLE[i] = INVALID_ENTRY_VAL; + SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i] = SOC_MMU_INVALID_ENTRY_VAL; #if !CONFIG_FREERTOS_UNICORE && CONFIG_IDF_TARGET_ESP32 - DPORT_APP_FLASH_MMU_TABLE[i] = INVALID_ENTRY_VAL; + DPORT_APP_FLASH_MMU_TABLE[i] = SOC_MMU_INVALID_ENTRY_VAL; #endif } } @@ -366,7 +326,7 @@ static uint32_t IRAM_ATTR NOINLINE_ATTR spi_flash_protected_read_mmu_entry(int i { uint32_t value; spi_flash_disable_interrupts_caches_and_other_cpu(); - value = DPORT_REG_READ((uint32_t)&DPORT_PRO_FLASH_MMU_TABLE[index]); + value = DPORT_REG_READ((uint32_t)&SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[index]); spi_flash_enable_interrupts_caches_and_other_cpu(); return value; } @@ -379,7 +339,7 @@ void spi_flash_mmap_dump(void) for (it = LIST_FIRST(&s_mmap_entries_head); it != NULL; it = LIST_NEXT(it, entries)) { printf("handle=%d page=%d count=%d\n", it->handle, it->page, it->count); } - for (int i = 0; i < REGIONS_COUNT * PAGES_PER_REGION; ++i) { + for (int i = 0; i < SOC_MMU_REGIONS_COUNT * SOC_MMU_PAGES_PER_REGION; ++i) { if (s_mmap_page_refcnt[i] != 0) { uint32_t paddr = spi_flash_protected_read_mmu_entry(i); printf("page %d: refcnt=%d paddr=%d\n", i, (int) s_mmap_page_refcnt[i], paddr); @@ -398,7 +358,7 @@ uint32_t IRAM_ATTR spi_flash_mmap_get_free_pages(spi_flash_mmap_memory_t memory) get_mmu_region(memory,®ion_begin,®ion_size,®ion_addr); DPORT_INTERRUPT_DISABLE(); for (int i = region_begin; i < region_begin + region_size; ++i) { - if (s_mmap_page_refcnt[i] == 0 && DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_PRO_FLASH_MMU_TABLE[i]) == INVALID_ENTRY_VAL) { + if (s_mmap_page_refcnt[i] == 0 && DPORT_SEQUENCE_REG_READ((uint32_t)&SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i]) == SOC_MMU_INVALID_ENTRY_VAL) { count++; } } @@ -412,16 +372,13 @@ size_t spi_flash_cache2phys(const void *cached) intptr_t c = (intptr_t)cached; size_t cache_page; int offset = 0; -#if !CONFIG_IDF_TARGET_ESP32C3 - if (c >= VADDR1_START_ADDR && c < VADDR1_FIRST_USABLE_ADDR) { -#else - if (c >= SOC_IRAM_LOW && c < VADDR1_FIRST_USABLE_ADDR) { -#endif + if (c >= SOC_MMU_VADDR1_START_ADDR && c < SOC_MMU_VADDR1_FIRST_USABLE_ADDR) { /* IRAM address, doesn't map to flash */ return SPI_FLASH_CACHE2PHYS_FAIL; - } else if (c < VADDR1_FIRST_USABLE_ADDR) { + } + if (c < SOC_MMU_VADDR1_FIRST_USABLE_ADDR) { /* expect cache is in DROM */ - cache_page = (c - VADDR0_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + DROM0_PAGES_START; + cache_page = (c - SOC_MMU_VADDR0_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + SOC_MMU_DROM0_PAGES_START; #if CONFIG_SPIRAM_RODATA if (c >= (uint32_t)&_rodata_reserved_start && c <= (uint32_t)&_rodata_reserved_end) { offset = rodata_flash2spiram_offset(); @@ -429,7 +386,7 @@ size_t spi_flash_cache2phys(const void *cached) #endif } else { /* expect cache is in IROM */ - cache_page = (c - VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + IROM0_PAGES_START; + cache_page = (c - SOC_MMU_VADDR1_START_ADDR) / SPI_FLASH_MMU_PAGE_SIZE + SOC_MMU_IROM0_PAGES_START; #if CONFIG_SPIRAM_FETCH_INSTRUCTIONS if (c >= (uint32_t)&_instruction_reserved_start && c <= (uint32_t)&_instruction_reserved_end) { offset = instruction_flash2spiram_offset(); @@ -442,11 +399,11 @@ size_t spi_flash_cache2phys(const void *cached) return SPI_FLASH_CACHE2PHYS_FAIL; } uint32_t phys_page = spi_flash_protected_read_mmu_entry(cache_page); - if (phys_page == INVALID_ENTRY_VAL) { + if (phys_page == SOC_MMU_INVALID_ENTRY_VAL) { /* page is not mapped */ return SPI_FLASH_CACHE2PHYS_FAIL; } - uint32_t phys_offs = ((phys_page & MMU_ADDR_MASK) + offset) * SPI_FLASH_MMU_PAGE_SIZE; + uint32_t phys_offs = ((phys_page & SOC_MMU_ADDR_MASK) + offset) * SPI_FLASH_MMU_PAGE_SIZE; return phys_offs | (c & (SPI_FLASH_MMU_PAGE_SIZE-1)); } @@ -457,25 +414,25 @@ const void *IRAM_ATTR spi_flash_phys2cache(size_t phys_offs, spi_flash_mmap_memo intptr_t base; if (memory == SPI_FLASH_MMAP_DATA) { - start = DROM0_PAGES_START; - end = DROM0_PAGES_END; - base = VADDR0_START_ADDR; - page_delta = DROM0_PAGES_START > IROM0_PAGES_START ? DROM0_PAGES_START : 0; + start = SOC_MMU_DROM0_PAGES_START; + end = SOC_MMU_DROM0_PAGES_END; + base = SOC_MMU_VADDR0_START_ADDR; + page_delta = SOC_MMU_DROM0_PAGES_START; } else { - start = PRO_IRAM0_FIRST_USABLE_PAGE; - end = IROM0_PAGES_END; - base = VADDR1_START_ADDR; - page_delta = DROM0_PAGES_START > IROM0_PAGES_START ? 0: IROM0_PAGES_START; + start = SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE; + end = SOC_MMU_IROM0_PAGES_END; + base = SOC_MMU_VADDR1_START_ADDR; + page_delta = SOC_MMU_IROM0_PAGES_START; } spi_flash_disable_interrupts_caches_and_other_cpu(); DPORT_INTERRUPT_DISABLE(); for (int i = start; i < end; i++) { - uint32_t mmu_value = DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_PRO_FLASH_MMU_TABLE[i]); + uint32_t mmu_value = DPORT_SEQUENCE_REG_READ((uint32_t)&SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i]); #if CONFIG_SPIRAM_FETCH_INSTRUCTIONS if (phys_page >= instruction_flash_start_page_get() && phys_page <= instruction_flash_end_page_get()) { if (mmu_value & MMU_ACCESS_SPIRAM) { mmu_value += instruction_flash2spiram_offset(); - mmu_value = (mmu_value & MMU_ADDR_MASK) | MMU_ACCESS_FLASH; + mmu_value = (mmu_value & SOC_MMU_ADDR_MASK) | MMU_ACCESS_FLASH; } } #endif @@ -483,11 +440,11 @@ const void *IRAM_ATTR spi_flash_phys2cache(size_t phys_offs, spi_flash_mmap_memo if (phys_page >= rodata_flash_start_page_get() && phys_page <= rodata_flash_start_page_get()) { if (mmu_value & MMU_ACCESS_SPIRAM) { mmu_value += rodata_flash2spiram_offset(); - mmu_value = (mmu_value & MMU_ADDR_MASK) | MMU_ACCESS_FLASH; + mmu_value = (mmu_value & SOC_MMU_ADDR_MASK) | MMU_ACCESS_FLASH; } } #endif - if (mmu_value == PAGE_IN_FLASH(phys_page)) { + if (mmu_value == SOC_MMU_PAGE_IN_FLASH(phys_page)) { i -= page_delta; intptr_t cache_page = base + (SPI_FLASH_MMU_PAGE_SIZE * i); DPORT_INTERRUPT_RESTORE(); @@ -507,22 +464,22 @@ static bool IRAM_ATTR is_page_mapped_in_cache(uint32_t phys_page, const void **o *out_ptr = NULL; /* SPI_FLASH_MMAP_DATA */ - start[0] = DROM0_PAGES_START; - end[0] = DROM0_PAGES_END; + start[0] = SOC_MMU_DROM0_PAGES_START; + end[0] = SOC_MMU_DROM0_PAGES_END; /* SPI_FLASH_MMAP_INST */ - start[1] = PRO_IRAM0_FIRST_USABLE_PAGE; - end[1] = IROM0_PAGES_END; + start[1] = SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE; + end[1] = SOC_MMU_IROM0_PAGES_END; DPORT_INTERRUPT_DISABLE(); for (int j = 0; j < 2; j++) { for (int i = start[j]; i < end[j]; i++) { - if (DPORT_SEQUENCE_REG_READ((uint32_t)&DPORT_PRO_FLASH_MMU_TABLE[i]) == PAGE_IN_FLASH(phys_page)) { + if (DPORT_SEQUENCE_REG_READ((uint32_t)&SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i]) == SOC_MMU_PAGE_IN_FLASH(phys_page)) { #if !CONFIG_IDF_TARGET_ESP32 if (j == 0) { /* SPI_FLASH_MMAP_DATA */ - *out_ptr = (const void *)(VADDR0_START_ADDR + SPI_FLASH_MMU_PAGE_SIZE * (i - start[0])); + *out_ptr = (const void *)(SOC_MMU_VADDR0_START_ADDR + SPI_FLASH_MMU_PAGE_SIZE * (i - start[0])); } else { /* SPI_FLASH_MMAP_INST */ - *out_ptr = (const void *)(VADDR1_FIRST_USABLE_ADDR + SPI_FLASH_MMU_PAGE_SIZE * (i - start[1])); + *out_ptr = (const void *)(SOC_MMU_VADDR1_FIRST_USABLE_ADDR + SPI_FLASH_MMU_PAGE_SIZE * (i - start[1])); } #endif DPORT_INTERRUPT_RESTORE(); From 06ec032c0caf0f09d61845691f9de1dacbda1427 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 17 Dec 2020 10:28:03 +1100 Subject: [PATCH 3/3] spi_flash: Simplify init-time size check --- components/spi_flash/esp_flash_spi_init.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/components/spi_flash/esp_flash_spi_init.c b/components/spi_flash/esp_flash_spi_init.c index 64cef8c75e..d362b7b354 100644 --- a/components/spi_flash/esp_flash_spi_init.c +++ b/components/spi_flash/esp_flash_spi_init.c @@ -261,13 +261,13 @@ esp_err_t esp_flash_init_default_chip(void) if (default_chip.size < legacy_chip->chip_size) { ESP_EARLY_LOGE(TAG, "Detected size(%dk) smaller than the size in the binary image header(%dk). Probe failed.", default_chip.size/1024, legacy_chip->chip_size/1024); return ESP_ERR_FLASH_SIZE_NOT_MATCH; - } else if (default_chip.size > legacy_chip->chip_size) { - ESP_EARLY_LOGW(TAG, "Detected size(%dk) larger than the size in the binary image header(%dk). Using the size in the binary image header.", default_chip.size/1024, legacy_chip->chip_size/1024); - default_chip.size = legacy_chip->chip_size; - } else { - default_chip.size = legacy_chip->chip_size; } + if (default_chip.size > legacy_chip->chip_size) { + ESP_EARLY_LOGW(TAG, "Detected size(%dk) larger than the size in the binary image header(%dk). Using the size in the binary image header.", default_chip.size/1024, legacy_chip->chip_size/1024); + } + default_chip.size = legacy_chip->chip_size; + esp_flash_default_chip = &default_chip; return ESP_OK; }