From 37423083bb6879526b49f4cdea785b399066c87d Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Mon, 24 Aug 2020 11:09:33 +0800 Subject: [PATCH] spi_flash: add config option to override flash size in bootloader header Sometimes the flash size read from bootloader is not correct. This may forbid SPI Flash driver from reading the the area larger than the size in bootloader header. When the new config option is enabled, the latest configured ESPTOOLPY_FLAHSIZE in the app header will be used to override the value read from bootloader header. --- .../include/bootloader_flash_config.h | 8 ++++++++ .../include/esp_image_format.h | 8 ++++++++ .../src/bootloader_flash_config_esp32.c | 5 +++++ .../src/bootloader_flash_config_esp32s2.c | 5 +++++ .../bootloader_support/src/esp_image_format.c | 18 ++++++++++++++++++ components/esp_system/port/cpu_start.c | 17 +++++++++++++---- components/spi_flash/Kconfig | 8 ++++++++ 7 files changed, 65 insertions(+), 4 deletions(-) diff --git a/components/bootloader_support/include/bootloader_flash_config.h b/components/bootloader_support/include/bootloader_flash_config.h index 453677307f..6074faca2b 100644 --- a/components/bootloader_support/include/bootloader_flash_config.h +++ b/components/bootloader_support/include/bootloader_flash_config.h @@ -28,6 +28,14 @@ extern "C" { */ void bootloader_flash_update_id(void); +/** + * @brief Update the flash size in g_rom_flashchip (global esp_rom_spiflash_chip_t structure). + * + * @param size The size to store, in bytes. + * @return None + */ +void bootloader_flash_update_size(uint32_t size); + /** * @brief Set the flash CS setup and hold time. * diff --git a/components/bootloader_support/include/esp_image_format.h b/components/bootloader_support/include/esp_image_format.h index 928a29adf6..f495933a16 100644 --- a/components/bootloader_support/include/esp_image_format.h +++ b/components/bootloader_support/include/esp_image_format.h @@ -169,6 +169,14 @@ esp_err_t esp_image_verify_bootloader(uint32_t *length); */ esp_err_t esp_image_verify_bootloader_data(esp_image_metadata_t *data); +/** + * @brief Get the flash size of the image + * + * @param app_flash_size The value configured in the image header + * @return Actual size, in bytes. + */ +int esp_image_get_flash_size(esp_image_flash_size_t app_flash_size); + typedef struct { uint32_t drom_addr; diff --git a/components/bootloader_support/src/bootloader_flash_config_esp32.c b/components/bootloader_support/src/bootloader_flash_config_esp32.c index d5cb056156..2477d25e62 100644 --- a/components/bootloader_support/src/bootloader_flash_config_esp32.c +++ b/components/bootloader_support/src/bootloader_flash_config_esp32.c @@ -33,6 +33,11 @@ void bootloader_flash_update_id(void) g_rom_flashchip.device_id = bootloader_read_flash_id(); } +void bootloader_flash_update_size(uint32_t size) +{ + g_rom_flashchip.chip_size = size; +} + void IRAM_ATTR bootloader_flash_cs_timing_config(void) { SET_PERI_REG_MASK(SPI_USER_REG(0), SPI_CS_HOLD_M | SPI_CS_SETUP_M); diff --git a/components/bootloader_support/src/bootloader_flash_config_esp32s2.c b/components/bootloader_support/src/bootloader_flash_config_esp32s2.c index 1edc4a957b..183329cbe6 100644 --- a/components/bootloader_support/src/bootloader_flash_config_esp32s2.c +++ b/components/bootloader_support/src/bootloader_flash_config_esp32s2.c @@ -36,6 +36,11 @@ void bootloader_flash_update_id() g_rom_flashchip.device_id = bootloader_read_flash_id(); } +void bootloader_flash_update_size(uint32_t size) +{ + g_rom_flashchip.chip_size = size; +} + void IRAM_ATTR bootloader_flash_cs_timing_config() { SET_PERI_REG_MASK(SPI_MEM_USER_REG(0), SPI_MEM_CS_HOLD_M | SPI_MEM_CS_SETUP_M); diff --git a/components/bootloader_support/src/esp_image_format.c b/components/bootloader_support/src/esp_image_format.c index 92df9fd2f8..2d02329019 100644 --- a/components/bootloader_support/src/esp_image_format.c +++ b/components/bootloader_support/src/esp_image_format.c @@ -850,3 +850,21 @@ static esp_err_t verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_i bootloader_munmap(hash); return ESP_OK; } + +int esp_image_get_flash_size(esp_image_flash_size_t app_flash_size) +{ + switch (app_flash_size) { + case ESP_IMAGE_FLASH_SIZE_1MB: + return 1 * 1024 * 1024; + case ESP_IMAGE_FLASH_SIZE_2MB: + return 2 * 1024 * 1024; + case ESP_IMAGE_FLASH_SIZE_4MB: + return 4 * 1024 * 1024; + case ESP_IMAGE_FLASH_SIZE_8MB: + return 8 * 1024 * 1024; + case ESP_IMAGE_FLASH_SIZE_16MB: + return 16 * 1024 * 1024; + default: + return 0; + } +} \ No newline at end of file diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index cab15e197c..92080e0004 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -386,10 +386,8 @@ void IRAM_ATTR call_start_cpu0(void) #endif bootloader_flash_update_id(); -#if CONFIG_IDF_TARGET_ESP32 -#if !CONFIG_SPIRAM_BOOT_INIT // Read the application binary image header. This will also decrypt the header if the image is encrypted. - esp_image_header_t fhdr = {0}; + __attribute__((unused)) esp_image_header_t fhdr = {0}; #ifdef CONFIG_APP_BUILD_TYPE_ELF_RAM fhdr.spi_mode = ESP_IMAGE_SPI_MODE_DIO; fhdr.spi_speed = ESP_IMAGE_SPI_SPEED_40M; @@ -404,13 +402,24 @@ void IRAM_ATTR call_start_cpu0(void) memcpy(&fhdr, (void *) SOC_DROM_LOW, sizeof(fhdr)); #endif // CONFIG_APP_BUILD_TYPE_ELF_RAM +#if CONFIG_IDF_TARGET_ESP32 +#if !CONFIG_SPIRAM_BOOT_INIT // If psram is uninitialized, we need to improve some flash configuration. bootloader_flash_clock_config(&fhdr); bootloader_flash_gpio_config(&fhdr); bootloader_flash_dummy_config(&fhdr); bootloader_flash_cs_timing_config(); #endif //!CONFIG_SPIRAM_BOOT_INIT -#endif +#endif //CONFIG_IDF_TARGET_ESP32 + +#if CONFIG_SPI_FLASH_SIZE_OVERRIDE + int app_flash_size = esp_image_get_flash_size(fhdr.spi_size); + if (app_flash_size < 1 * 1024 * 1024) { + ESP_LOGE(TAG, "Invalid flash size in app image header."); + abort(); + } + bootloader_flash_update_size(app_flash_size); +#endif //CONFIG_SPI_FLASH_SIZE_OVERRIDE #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE s_cpu_inited[0] = true; diff --git a/components/spi_flash/Kconfig b/components/spi_flash/Kconfig index cb41293a13..c1f6c93b3d 100644 --- a/components/spi_flash/Kconfig +++ b/components/spi_flash/Kconfig @@ -140,6 +140,14 @@ menu "SPI Flash driver" value here ensures that cache (and non-IRAM resident interrupts) remains disabled for shorter duration. + config SPI_FLASH_SIZE_OVERRIDE + bool "Override flash size in bootloader header by ESPTOOLPY_FLASHSIZE" + default n + help + SPI Flash driver uses the flash size configured in bootloader header by default. + Enable this option to override flash size with latest ESPTOOLPY_FLASHSIZE value from + the app header if the size in the bootloader header is incorrect. + menu "Auto-detect flash chips" config SPI_FLASH_SUPPORT_ISSI_CHIP