From 1c2f8b8ce08cb905e7fe5f29c394ac3ad925fe93 Mon Sep 17 00:00:00 2001 From: laokaiyao Date: Wed, 14 Aug 2024 19:02:59 +0800 Subject: [PATCH] feat(bootloader): support to check efuse block revision change(bootloader): remove ignore efuse check flag (temp) change(bootloader): use int for the minimum efuse blk rev (temp) --- .../include/bootloader_common.h | 16 +++++++++- .../src/bootloader_common_loader.c | 29 +++++++++++++++++-- .../bootloader_support/src/bootloader_init.c | 15 +++++++--- .../bootloader_support/src/esp_image_format.c | 17 ++++++++--- components/esp_app_format/esp_app_desc.c | 2 ++ .../esp_app_format/include/esp_app_desc.h | 4 ++- .../port/esp32/Kconfig.hw_support | 17 +++++++++++ .../port/esp32c2/Kconfig.hw_support | 18 ++++++++++++ .../port/esp32c3/Kconfig.hw_support | 17 +++++++++++ .../port/esp32c5/Kconfig.hw_support | 17 +++++++++++ .../port/esp32c6/Kconfig.hw_support | 17 +++++++++++ .../port/esp32c61/Kconfig.hw_support | 17 +++++++++++ .../port/esp32h2/Kconfig.hw_support | 17 +++++++++++ .../port/esp32p4/Kconfig.hw_support | 17 +++++++++++ .../port/esp32s2/Kconfig.hw_support | 17 +++++++++++ .../port/esp32s3/Kconfig.hw_support | 17 +++++++++++ .../port/linux/Kconfig.hw_support | 8 +++++ components/hal/efuse_hal.c | 7 ++++- components/hal/esp32/include/hal/efuse_ll.h | 7 ++++- components/hal/include/hal/efuse_hal.h | 10 ++++++- components/soc/include/soc/chip_revision.h | 8 ++++- .../en/api-reference/system/chip_revision.rst | 15 ++++------ .../api-reference/system/chip_revision.rst | 15 ++++------ 23 files changed, 288 insertions(+), 36 deletions(-) diff --git a/components/bootloader_support/include/bootloader_common.h b/components/bootloader_support/include/bootloader_common.h index 75d10ad482..4f819a13d1 100644 --- a/components/bootloader_support/include/bootloader_common.h +++ b/components/bootloader_support/include/bootloader_common.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -181,6 +181,20 @@ uint32_t bootloader_common_get_chip_ver_pkg(void); */ esp_err_t bootloader_common_check_chip_validity(const esp_image_header_t* img_hdr, esp_image_type type); +#if !CONFIG_IDF_TARGET_ESP32 +/** + * @brief Check the eFuse block revision + * + * @param[in] min_rev_full The required minimum revision of the eFuse block + * @param[in] max_rev_full The required maximum revision of the eFuse block + * @return + * - ESP_OK: The eFuse block revision is in the required range. + * - ESP_OK: DISABLE_BLK_VERSION_MAJOR has been set in the eFuse of the SoC. No requirements shall be checked at this time. + * - ESP_FAIL: The eFuse block revision of this chip does not match the requirement of the current image. + */ +esp_err_t bootloader_common_check_efuse_blk_validity(uint32_t min_rev_full, uint32_t max_rev_full); +#endif // !CONFIG_IDF_TARGET_ESP32 + /** * @brief Configure VDDSDIO, call this API to rise VDDSDIO to 1.9V when VDDSDIO regulator is enabled as 1.8V mode. */ diff --git a/components/bootloader_support/src/bootloader_common_loader.c b/components/bootloader_support/src/bootloader_common_loader.c index dc33aa7bd1..2d29ac6dbf 100644 --- a/components/bootloader_support/src/bootloader_common_loader.c +++ b/components/bootloader_support/src/bootloader_common_loader.c @@ -27,7 +27,7 @@ #include "esp_rom_caps.h" #define ESP_PARTITION_HASH_LEN 32 /* SHA-256 digest length */ -#define IS_MAX_REV_SET(max_chip_rev_full) (((max_chip_rev_full) != 65535) && ((max_chip_rev_full) != 0)) +#define IS_FIELD_SET(rev_full) (((rev_full) != 65535) && ((rev_full) != 0)) static const char* TAG = "boot_comm"; @@ -57,6 +57,31 @@ int bootloader_common_get_active_otadata(esp_ota_select_entry_t *two_otadata) return bootloader_common_select_otadata(two_otadata, valid_two_otadata, true); } +#if !CONFIG_IDF_TARGET_ESP32 +esp_err_t bootloader_common_check_efuse_blk_validity(uint32_t min_rev_full, uint32_t max_rev_full) +{ + esp_err_t err = ESP_OK; +#ifndef CONFIG_IDF_ENV_FPGA + // Check whether the efuse block version satisfy the requirements of current image. + uint32_t revision = efuse_hal_blk_version(); + uint32_t major_rev = revision / 100; + uint32_t minor_rev = revision % 100; + if (IS_FIELD_SET(min_rev_full) && !ESP_EFUSE_BLK_REV_ABOVE(revision, min_rev_full)) { + ESP_LOGE(TAG, "Image requires efuse blk rev >= v%"PRIu32".%"PRIu32", but chip is v%"PRIu32".%"PRIu32, + min_rev_full / 100, min_rev_full % 100, major_rev, minor_rev); + err = ESP_FAIL; + } + // If burnt `disable_blk_version_major` bit, skip the max version check + if ((IS_FIELD_SET(max_rev_full) && (revision > max_rev_full) && !efuse_hal_get_disable_blk_version_major())) { + ESP_LOGE(TAG, "Image requires efuse blk rev <= v%"PRIu32".%"PRIu32", but chip is v%"PRIu32".%"PRIu32, + max_rev_full / 100, max_rev_full % 100, major_rev, minor_rev); + err = ESP_FAIL; + } +#endif + return err; +} +#endif // !CONFIG_IDF_TARGET_ESP32 + esp_err_t bootloader_common_check_chip_validity(const esp_image_header_t* img_hdr, esp_image_type type) { esp_err_t err = ESP_OK; @@ -80,7 +105,7 @@ esp_err_t bootloader_common_check_chip_validity(const esp_image_header_t* img_hd } if (type == ESP_IMAGE_APPLICATION) { unsigned max_rev = img_hdr->max_chip_rev_full; - if ((IS_MAX_REV_SET(max_rev) && (revision > max_rev) && !efuse_hal_get_disable_wafer_version_major())) { + if ((IS_FIELD_SET(max_rev) && (revision > max_rev) && !efuse_hal_get_disable_wafer_version_major())) { ESP_LOGE(TAG, "Image requires chip rev <= v%d.%d, but chip is v%d.%d", max_rev / 100, max_rev % 100, major_rev, minor_rev); diff --git a/components/bootloader_support/src/bootloader_init.c b/components/bootloader_support/src/bootloader_init.c index 6289936986..bff1b922dc 100644 --- a/components/bootloader_support/src/bootloader_init.c +++ b/components/bootloader_support/src/bootloader_init.c @@ -43,10 +43,17 @@ esp_err_t bootloader_read_bootloader_header(void) esp_err_t bootloader_check_bootloader_validity(void) { - unsigned int revision = efuse_hal_chip_revision(); - unsigned int major = revision / 100; - unsigned int minor = revision % 100; - ESP_EARLY_LOGI(TAG, "chip revision: v%d.%d", major, minor); + unsigned int chip_revision = efuse_hal_chip_revision(); + unsigned int chip_major_rev = chip_revision / 100; + unsigned int chip_minor_rev = chip_revision % 100; + ESP_EARLY_LOGI(TAG, "chip revision: v%d.%d", chip_major_rev, chip_minor_rev); +/* ESP32 doesn't have more memory and more efuse bits for block major version. */ +#if !CONFIG_IDF_TARGET_ESP32 + unsigned int efuse_revision = efuse_hal_blk_version(); + unsigned int efuse_major_rev = efuse_revision / 100; + unsigned int efuse_minor_rev = efuse_revision % 100; + ESP_EARLY_LOGI(TAG, "efuse block revision: v%d.%d", efuse_major_rev, efuse_minor_rev); +#endif // !CONFIG_IDF_TARGET_ESP32 /* compare with the one set in bootloader image header */ if (bootloader_common_check_chip_validity(&bootloader_image_hdr, ESP_IMAGE_BOOTLOADER) != ESP_OK) { return ESP_FAIL; diff --git a/components/bootloader_support/src/esp_image_format.c b/components/bootloader_support/src/esp_image_format.c index 60498bab4e..6b2f88a7ba 100644 --- a/components/bootloader_support/src/esp_image_format.c +++ b/components/bootloader_support/src/esp_image_format.c @@ -691,19 +691,28 @@ static esp_err_t process_segment_data(int segment, intptr_t load_addr, uint32_t const uint32_t *src = data; -#if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK // Case I: Bootloader verifying application // Case II: Bootloader verifying bootloader - // Anti-rollback check should handle only Case I from above. + // The esp_app_desc_t structure is located in DROM and is always in segment #0. + // Anti-rollback check and efuse block version check should handle only Case I from above. if (segment == 0 && metadata->start_addr != ESP_BOOTLOADER_OFFSET) { +/* ESP32 doesn't have more memory and more efuse bits for block major version. */ +#if !CONFIG_IDF_TARGET_ESP32 + const esp_app_desc_t *app_desc = (const esp_app_desc_t *)src; + esp_err_t ret = bootloader_common_check_efuse_blk_validity(app_desc->min_efuse_blk_rev_full, app_desc->max_efuse_blk_rev_full); + if (ret != ESP_OK) { + bootloader_munmap(data); + return ret; + } +#endif // !CONFIG_IDF_TARGET_ESP32 +#if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK ESP_LOGD(TAG, "additional anti-rollback check 0x%"PRIx32, data_addr); - // The esp_app_desc_t structure is located in DROM and is always in segment #0. size_t len = process_esp_app_desc_data(src, sha_handle, checksum, metadata); data_len -= len; src += len / 4; // In BOOTLOADER_BUILD, for DROM (segment #0) we do not load it into dest (only map it), do_load = false. - } #endif // CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK + } for (size_t i = 0; i < data_len; i += 4) { int w_i = i / 4; // Word index diff --git a/components/esp_app_format/esp_app_desc.c b/components/esp_app_format/esp_app_desc.c index e40c9fd5a7..27b821256d 100644 --- a/components/esp_app_format/esp_app_desc.c +++ b/components/esp_app_format/esp_app_desc.c @@ -57,6 +57,8 @@ const __attribute__((weak)) __attribute__((section(".rodata_desc"))) esp_app_de .time = "", .date = "", #endif + .min_efuse_blk_rev_full = CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL, + .max_efuse_blk_rev_full = CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL, }; #ifndef CONFIG_APP_EXCLUDE_PROJECT_VER_VAR diff --git a/components/esp_app_format/include/esp_app_desc.h b/components/esp_app_format/include/esp_app_desc.h index 1bafd95202..b4201a4d05 100644 --- a/components/esp_app_format/include/esp_app_desc.h +++ b/components/esp_app_format/include/esp_app_desc.h @@ -33,7 +33,9 @@ typedef struct { char date[16]; /*!< Compile date*/ char idf_ver[32]; /*!< Version IDF */ uint8_t app_elf_sha256[32]; /*!< sha256 of elf file */ - uint32_t reserv2[20]; /*!< reserv2 */ + uint16_t min_efuse_blk_rev_full; /*!< Minimal eFuse block revision supported by image, in format: major * 100 + minor */ + uint16_t max_efuse_blk_rev_full; /*!< Maximal eFuse block revision supported by image, in format: major * 100 + minor */ + uint32_t reserv2[19]; /*!< reserv2 */ } esp_app_desc_t; /** @cond */ diff --git a/components/esp_hw_support/port/esp32/Kconfig.hw_support b/components/esp_hw_support/port/esp32/Kconfig.hw_support index 81eb5f3ded..732dc6cd49 100644 --- a/components/esp_hw_support/port/esp32/Kconfig.hw_support +++ b/components/esp_hw_support/port/esp32/Kconfig.hw_support @@ -66,3 +66,20 @@ config ESP32_REV_MAX_FULL config ESP_REV_MAX_FULL int default ESP32_REV_MAX_FULL + +config ESP_EFUSE_BLOCK_REV_MIN_FULL + int "Minimum Supported ESP32 eFuse Block Revision" + default 0 + help + Required minimum eFuse Block revision. ESP-IDF will check it at the 2nd bootloader stage + whether the current image can work correctly for this eFuse Block revision. + So that to avoid running an incompatible image on a SoC that contains breaking change in the eFuse Block. + If you want to update this value to run the image that not compatible with the current eFuse Block revision, + please contact to Espressif's business team for details: + https://www.espressif.com.cn/en/contact-us/sales-questions + +config ESP_EFUSE_BLOCK_REV_MAX_FULL + int + default 99 + comment "Maximum Supported ESP32 eFuse Block Revision (eFuse Block Rev v0.99)" + # The revision in the comment must correspond to the default value of ESP_EFUSE_BLOCK_REV_MAX_FULL diff --git a/components/esp_hw_support/port/esp32c2/Kconfig.hw_support b/components/esp_hw_support/port/esp32c2/Kconfig.hw_support index eb203c654e..18a6f608ef 100644 --- a/components/esp_hw_support/port/esp32c2/Kconfig.hw_support +++ b/components/esp_hw_support/port/esp32c2/Kconfig.hw_support @@ -47,3 +47,21 @@ config ESP_REV_MAX_FULL config ESP32C2_REV2_DEVELOPMENT bool "Develop on ESP32-C2 v2.0 (Preview)" default y if IDF_CI_BUILD + +config ESP_EFUSE_BLOCK_REV_MIN_FULL + int "Minimum Supported ESP32-C2 eFuse Block Revision" + default 0 + help + Required minimum eFuse Block revision. ESP-IDF will check it at the 2nd bootloader stage + whether the current image can work correctly for this eFuse Block revision. + So that to avoid running an incompatible image on a SoC that contains breaking change in the eFuse Block. + If you want to update this value to run the image that not compatible with the current eFuse Block revision, + please contact to Espressif's business team for details: + https://www.espressif.com.cn/en/contact-us/sales-questions + + +config ESP_EFUSE_BLOCK_REV_MAX_FULL + int + default 99 + comment "Maximum Supported ESP32-C2 eFuse Block Revision (eFuse Block Rev v0.99)" + # The revision in the comment must correspond to the default value of ESP_EFUSE_BLOCK_REV_MAX_FULL diff --git a/components/esp_hw_support/port/esp32c3/Kconfig.hw_support b/components/esp_hw_support/port/esp32c3/Kconfig.hw_support index 8e7c12f8d7..332762e1fe 100644 --- a/components/esp_hw_support/port/esp32c3/Kconfig.hw_support +++ b/components/esp_hw_support/port/esp32c3/Kconfig.hw_support @@ -54,3 +54,20 @@ config ESP32C3_REV_MAX_FULL config ESP_REV_MAX_FULL int default ESP32C3_REV_MAX_FULL + +config ESP_EFUSE_BLOCK_REV_MIN_FULL + int "Minimum Supported ESP32-C3 eFuse Block Revision" + default 100 + help + Required minimum eFuse Block revision. ESP-IDF will check it at the 2nd bootloader stage + whether the current image can work correctly for this eFuse Block revision. + So that to avoid running an incompatible image on a SoC that contains breaking change in the eFuse Block. + If you want to update this value to run the image that not compatible with the current eFuse Block revision, + please contact to Espressif's business team for details: + https://www.espressif.com.cn/en/contact-us/sales-questions + +config ESP_EFUSE_BLOCK_REV_MAX_FULL + int + default 199 + comment "Maximum Supported ESP32-C3 eFuse Block Revision (eFuse Block Rev v1.99)" + # The revision in the comment must correspond to the default value of ESP_EFUSE_BLOCK_REV_MAX_FULL diff --git a/components/esp_hw_support/port/esp32c5/Kconfig.hw_support b/components/esp_hw_support/port/esp32c5/Kconfig.hw_support index 87910b7d1c..4d40c5c547 100644 --- a/components/esp_hw_support/port/esp32c5/Kconfig.hw_support +++ b/components/esp_hw_support/port/esp32c5/Kconfig.hw_support @@ -39,3 +39,20 @@ config ESP32C5_REV_MAX_FULL config ESP_REV_MAX_FULL int default ESP32C5_REV_MAX_FULL + +config ESP_EFUSE_BLOCK_REV_MIN_FULL + int "Minimum Supported ESP32-C5 eFuse Block Revision" + default 0 + help + Required minimum eFuse Block revision. ESP-IDF will check it at the 2nd bootloader stage + whether the current image can work correctly for this eFuse Block revision. + So that to avoid running an incompatible image on a SoC that contains breaking change in the eFuse Block. + If you want to update this value to run the image that not compatible with the current eFuse Block revision, + please contact to Espressif's business team for details: + https://www.espressif.com.cn/en/contact-us/sales-questions + +config ESP_EFUSE_BLOCK_REV_MAX_FULL + int + default 99 + comment "Maximum Supported ESP32-C5 eFuse Block Revision (eFuse Block Rev v0.99)" + # The revision in the comment must correspond to the default value of ESP_EFUSE_BLOCK_REV_MAX_FULL diff --git a/components/esp_hw_support/port/esp32c6/Kconfig.hw_support b/components/esp_hw_support/port/esp32c6/Kconfig.hw_support index c77f67f9ac..1d44206e52 100644 --- a/components/esp_hw_support/port/esp32c6/Kconfig.hw_support +++ b/components/esp_hw_support/port/esp32c6/Kconfig.hw_support @@ -42,3 +42,20 @@ config ESP32C6_REV_MAX_FULL config ESP_REV_MAX_FULL int default ESP32C6_REV_MAX_FULL + +config ESP_EFUSE_BLOCK_REV_MIN_FULL + int "Minimum Supported ESP32-C6 eFuse Block Revision" + default 0 + help + Required minimum eFuse Block revision. ESP-IDF will check it at the 2nd bootloader stage + whether the current image can work correctly for this eFuse Block revision. + So that to avoid running an incompatible image on a SoC that contains breaking change in the eFuse Block. + If you want to update this value to run the image that not compatible with the current eFuse Block revision, + please contact to Espressif's business team for details: + https://www.espressif.com.cn/en/contact-us/sales-questions + +config ESP_EFUSE_BLOCK_REV_MAX_FULL + int + default 99 + comment "Maximum Supported ESP32-C6 eFuse Block Revision (eFuse Block Rev v0.99)" + # The revision in the comment must correspond to the default value of ESP_EFUSE_BLOCK_REV_MAX_FULL diff --git a/components/esp_hw_support/port/esp32c61/Kconfig.hw_support b/components/esp_hw_support/port/esp32c61/Kconfig.hw_support index abcdde702e..7cb0fe1f89 100644 --- a/components/esp_hw_support/port/esp32c61/Kconfig.hw_support +++ b/components/esp_hw_support/port/esp32c61/Kconfig.hw_support @@ -39,3 +39,20 @@ config ESP32C61_REV_MAX_FULL config ESP_REV_MAX_FULL int default ESP32C61_REV_MAX_FULL + +config ESP_EFUSE_BLOCK_REV_MIN_FULL + int "Minimum Supported ESP32-C61 eFuse Block Revision" + default 0 + help + Required minimum eFuse Block revision. ESP-IDF will check it at the 2nd bootloader stage + whether the current image can work correctly for this eFuse Block revision. + So that to avoid running an incompatible image on a SoC that contains breaking change in the eFuse Block. + If you want to update this value to run the image that not compatible with the current eFuse Block revision, + please contact to Espressif's business team for details: + https://www.espressif.com.cn/en/contact-us/sales-questions + +config ESP_EFUSE_BLOCK_REV_MAX_FULL + int + default 99 + comment "Maximum Supported ESP32-C61 eFuse Block Revision (eFuse Block Rev v0.99)" + # The revision in the comment must correspond to the default value of ESP_EFUSE_BLOCK_REV_MAX_FULL diff --git a/components/esp_hw_support/port/esp32h2/Kconfig.hw_support b/components/esp_hw_support/port/esp32h2/Kconfig.hw_support index f5678dfd29..e12d9e2a63 100644 --- a/components/esp_hw_support/port/esp32h2/Kconfig.hw_support +++ b/components/esp_hw_support/port/esp32h2/Kconfig.hw_support @@ -50,3 +50,20 @@ config ESP_REV_MAX_FULL config ESP32H2_REV100_DEVELOPMENT bool "Develop on ESP32-H2 v1.0 and above (Preview)" default y if IDF_CI_BUILD + +config ESP_EFUSE_BLOCK_REV_MIN_FULL + int "Minimum Supported ESP32-H2 eFuse Block Revision" + default 0 + help + Required minimum eFuse Block revision. ESP-IDF will check it at the 2nd bootloader stage + whether the current image can work correctly for this eFuse Block revision. + So that to avoid running an incompatible image on a SoC that contains breaking change in the eFuse Block. + If you want to update this value to run the image that not compatible with the current eFuse Block revision, + please contact to Espressif's business team for details: + https://www.espressif.com.cn/en/contact-us/sales-questions + +config ESP_EFUSE_BLOCK_REV_MAX_FULL + int + default 99 + comment "Maximum Supported ESP32-H2 eFuse Block Revision (eFuse Block Rev v0.99)" + # The revision in the comment must correspond to the default value of ESP_EFUSE_BLOCK_REV_MAX_FULL diff --git a/components/esp_hw_support/port/esp32p4/Kconfig.hw_support b/components/esp_hw_support/port/esp32p4/Kconfig.hw_support index 2471aaa602..fe31a3aebe 100644 --- a/components/esp_hw_support/port/esp32p4/Kconfig.hw_support +++ b/components/esp_hw_support/port/esp32p4/Kconfig.hw_support @@ -42,3 +42,20 @@ config ESP32P4_REV_MAX_FULL config ESP_REV_MAX_FULL int default ESP32P4_REV_MAX_FULL + +config ESP_EFUSE_BLOCK_REV_MIN_FULL + int "Minimum Supported ESP32-P4 eFuse Block Revision" + default 0 + help + Required minimum eFuse Block revision. ESP-IDF will check it at the 2nd bootloader stage + whether the current image can work correctly for this eFuse Block revision. + So that to avoid running an incompatible image on a SoC that contains breaking change in the eFuse Block. + If you want to update this value to run the image that not compatible with the current eFuse Block revision, + please contact to Espressif's business team for details: + https://www.espressif.com.cn/en/contact-us/sales-questions + +config ESP_EFUSE_BLOCK_REV_MAX_FULL + int + default 99 + comment "Maximum Supported ESP32-P4 eFuse Block Revision (eFuse Block Rev v0.99)" + # The revision in the comment must correspond to the default value of ESP_EFUSE_BLOCK_REV_MAX_FULL diff --git a/components/esp_hw_support/port/esp32s2/Kconfig.hw_support b/components/esp_hw_support/port/esp32s2/Kconfig.hw_support index de3d319f20..ff19fab704 100644 --- a/components/esp_hw_support/port/esp32s2/Kconfig.hw_support +++ b/components/esp_hw_support/port/esp32s2/Kconfig.hw_support @@ -42,3 +42,20 @@ config ESP32S2_REV_MAX_FULL config ESP_REV_MAX_FULL int default ESP32S2_REV_MAX_FULL + +config ESP_EFUSE_BLOCK_REV_MIN_FULL + int "Minimum Supported ESP32-S2 eFuse Block Revision" + default 2 + help + Required minimum eFuse Block revision. ESP-IDF will check it at the 2nd bootloader stage + whether the current image can work correctly for this eFuse Block revision. + So that to avoid running an incompatible image on a SoC that contains breaking change in the eFuse Block. + If you want to update this value to run the image that not compatible with the current eFuse Block revision, + please contact to Espressif's business team for details: + https://www.espressif.com.cn/en/contact-us/sales-questions + +config ESP_EFUSE_BLOCK_REV_MAX_FULL + int + default 99 + comment "Maximum Supported ESP32-S2 eFuse Block Revision (eFuse Block Rev v0.99)" + # The revision in the comment must correspond to the default value of ESP_EFUSE_BLOCK_REV_MAX_FULL diff --git a/components/esp_hw_support/port/esp32s3/Kconfig.hw_support b/components/esp_hw_support/port/esp32s3/Kconfig.hw_support index 5b2401e399..791d8bd578 100644 --- a/components/esp_hw_support/port/esp32s3/Kconfig.hw_support +++ b/components/esp_hw_support/port/esp32s3/Kconfig.hw_support @@ -45,3 +45,20 @@ config ESP32S3_REV_MAX_FULL config ESP_REV_MAX_FULL int default ESP32S3_REV_MAX_FULL + +config ESP_EFUSE_BLOCK_REV_MIN_FULL + int "Minimum Supported ESP32-S3 eFuse Block Revision" + default 0 + help + Required minimum eFuse Block revision. ESP-IDF will check it at the 2nd bootloader stage + whether the current image can work correctly for this eFuse Block revision. + So that to avoid running an incompatible image on a SoC that contains breaking change in the eFuse Block. + If you want to update this value to run the image that not compatible with the current eFuse Block revision, + please contact to Espressif's business team for details: + https://www.espressif.com.cn/en/contact-us/sales-questions + +config ESP_EFUSE_BLOCK_REV_MAX_FULL + int + default 199 + comment "Maximum Supported ESP32-S3 eFuse Block Revision (eFuse Block Rev v1.99)" + # The revision in the comment must correspond to the default value of ESP_EFUSE_BLOCK_REV_MAX_FULL diff --git a/components/esp_hw_support/port/linux/Kconfig.hw_support b/components/esp_hw_support/port/linux/Kconfig.hw_support index e2ffe761bd..58d3c6f0a4 100644 --- a/components/esp_hw_support/port/linux/Kconfig.hw_support +++ b/components/esp_hw_support/port/linux/Kconfig.hw_support @@ -5,3 +5,11 @@ config ESP_REV_MIN_FULL config ESP_REV_MAX_FULL int default 999 + +config ESP_EFUSE_BLOCK_REV_MIN_FULL + int + default 0 + +config ESP_EFUSE_BLOCK_REV_MAX_FULL + int + default 999 diff --git a/components/hal/efuse_hal.c b/components/hal/efuse_hal.c index 8c15849d8f..ae0a86de57 100644 --- a/components/hal/efuse_hal.c +++ b/components/hal/efuse_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -34,6 +34,11 @@ IRAM_ATTR bool efuse_hal_get_disable_wafer_version_major(void) return efuse_ll_get_disable_wafer_version_major(); } +IRAM_ATTR bool efuse_hal_get_disable_blk_version_major(void) +{ + return efuse_ll_get_disable_blk_version_major(); +} + IRAM_ATTR bool efuse_hal_flash_encryption_enabled(void) { uint32_t flash_crypt_cnt = efuse_ll_get_flash_crypt_cnt(); diff --git a/components/hal/esp32/include/hal/efuse_ll.h b/components/hal/esp32/include/hal/efuse_ll.h index 62e6b267f8..cc92448b9c 100644 --- a/components/hal/esp32/include/hal/efuse_ll.h +++ b/components/hal/esp32/include/hal/efuse_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -119,6 +119,11 @@ __attribute__((always_inline)) static inline bool efuse_ll_get_disable_wafer_ver return false; } +__attribute__((always_inline)) static inline bool efuse_ll_get_disable_blk_version_major(void) +{ + return false; +} + __attribute__((always_inline)) static inline bool efuse_ll_get_blk_version_major(void) { return 0; diff --git a/components/hal/include/hal/efuse_hal.h b/components/hal/include/hal/efuse_hal.h index ce4aaf1eee..73f092ee00 100644 --- a/components/hal/include/hal/efuse_hal.h +++ b/components/hal/include/hal/efuse_hal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -51,6 +51,14 @@ bool efuse_hal_flash_encryption_enabled(void); */ bool efuse_hal_get_disable_wafer_version_major(void); +/** + * @brief Returns the status of whether the app start-up (and OTA) + * will check the efuse block version or not. + * + * @return true - Skip the efuse block version check. + */ +bool efuse_hal_get_disable_blk_version_major(void); + /** * @brief Returns major chip version */ diff --git a/components/soc/include/soc/chip_revision.h b/components/soc/include/soc/chip_revision.h index fbdc94a02c..3654469ef4 100644 --- a/components/soc/include/soc/chip_revision.h +++ b/components/soc/include/soc/chip_revision.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -31,6 +31,12 @@ extern "C" { #define ESP_CHIP_REV_ABOVE(rev, min_rev) ((min_rev) <= (rev)) #define ESP_CHIP_REV_MAJOR_AND_ABOVE(rev, min_rev) (((rev) / 100 == (min_rev) / 100) && ((rev) >= (min_rev))) +/** + * eFuse block revision strategy is same as chip revision + */ +#define ESP_EFUSE_BLK_REV_ABOVE(rev, min_rev) ESP_CHIP_REV_ABOVE(rev, min_rev) +#define ESP_EFUSE_BLK_REV_MAJOR_AND_ABOVE(rev, min_rev) ESP_CHIP_REV_MAJOR_AND_ABOVE(rev, min_rev) + #ifdef __cplusplus } #endif diff --git a/docs/en/api-reference/system/chip_revision.rst b/docs/en/api-reference/system/chip_revision.rst index 2e36dcc960..1af4903cc3 100644 --- a/docs/en/api-reference/system/chip_revision.rst +++ b/docs/en/api-reference/system/chip_revision.rst @@ -89,8 +89,8 @@ These APIs helps to get eFuse block revision from eFuses: The following Kconfig definitions (in ``major * 100 + minor`` format) that can help add the eFuse block revision dependency to the code: -- :ref:`CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL` -- :ref:`CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL` +- ``CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL`` +- ``CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL`` .. _revision_limitation: @@ -103,7 +103,7 @@ The minimum chip revision can be configured via the :ref:`CONFIG_{IDF_TARGET_CFG The maximum chip revision cannot be configured and is automatically determined by the current ESP-IDF version being used. ESP-IDF will refuse to boot any chip revision exceeding the maximum chip revision. Given that it is impossible for a particular ESP-IDF version to foresee all future chip revisions, the maximum chip revision is usually set to ``maximum supported MAJOR version + 99``. The "Ignore Maximum Revision" eFuse can be set to bypass the maximum revision limitation. However, the software is not guaranteed to work if the maximum revision is ignored. -The eFuse block revision is similar to the chip revision, but it mainly affects the coefficients that are specified in the eFuse (e.g. ADC calibration coefficients). If eFuse block revision is not important in your application, you can also ignore this check by enabling :ref:`CONFIG_ESP_IGNORE_EFUSE_BLOCK_REV_CHECK` +The eFuse block revision is similar to the chip revision, but it mainly affects the coefficients that are specified in the eFuse (e.g. ADC calibration coefficients). Below is the information about troubleshooting when the chip revision fails the compatibility check. Then there are technical details of the checking and software behavior on earlier version of ESP-IDF. @@ -141,7 +141,7 @@ For the chip revision, the 2nd stage bootloader and the application binary image For the eFuse revision, the requirements are stored in :cpp:type:`esp_app_desc_t`, which is contained in the application binary image. We only check the application image because the eFuse block revision mostly affects the ADC calibration, which does not really matter in the bootloader. There are 2 fields related to eFuse block revisions: - ``min_efuse_blk_rev_full`` - Minimum eFuse block MINOR revision required by image in format: ``major * 100 + minor``. Its value is determined by ``CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL``. -- ``max_efuse_blk_rev_full`` - Maximum eFuse block MINOR revision required by image in format: ``major * 100 + minor``. Its value is determined by ``CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL``. Since it is a hardware specific value, it should not be changed by user. Espressif shall update it appropriately when a new eFuse block version is supported in ESP-IDF. +- ``max_efuse_blk_rev_full`` - Maximum eFuse block MINOR revision required by image in format: ``major * 100 + minor``. Its value is determined by ``CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL``. It reflects whether the current IDF version supports this efuse block format or not, and should not be changed by the user. Maximum And Minimum Revision Restrictions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -154,12 +154,7 @@ The order for checking the minimum and maximum revisions during application boot 3. Then the 2nd stage bootloader checks the revision requirements of the application. It extracts the minimum and maximum revisions of the chip from the application image header, and the eFuse block from the segment header. Then the bootloader checks these versions against the chip and eFuse block revision from eFuses. If the these revisions are less than their minimum revision or higher than the maximum revision, the bootloader refuses to boot up and aborts. However, if the ignore maximum revision bit is set, the maximum revision constraint can be ignored. The ignore bits are set by the customer themselves when there is confirmation that the software is able to work with this chip revision or eFuse block revision. -4. Then at the start-up stage of the application image, the efuse block revision will be checked. The minimum and maximum requirements of the eFuse block revision come from the following Kconfig macros, - - * :ref:`CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL` - * :ref:`CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL` - -5. Furthermore, at the OTA update stage, the running application checks if the new software matches the chip revision and eFuse block revision. It extracts the minimum and maximum chip revisions from the header of the new application image and the eFuse block constraints from the application description to check against the these revisions from eFuses. It checks for revisions matching in the same way that the bootloader does, so that the chip and eFuse block revisions are between their min and max revisions (logic of ignoring max revision also applies). +4. Furthermore, at the OTA update stage, the running application checks if the new software matches the chip revision and eFuse block revision. It extracts the minimum and maximum chip revisions from the header of the new application image and the eFuse block constraints from the application description to check against the these revisions from eFuses. It checks for revisions matching in the same way that the bootloader does, so that the chip and eFuse block revisions are between their min and max revisions (logic of ignoring max revision also applies). Backward Compatibility with Bootloaders Built by Older ESP-IDF Versions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/zh_CN/api-reference/system/chip_revision.rst b/docs/zh_CN/api-reference/system/chip_revision.rst index a89b7415ff..a909da71d7 100644 --- a/docs/zh_CN/api-reference/system/chip_revision.rst +++ b/docs/zh_CN/api-reference/system/chip_revision.rst @@ -89,8 +89,8 @@ EFuse 块版本 API 下列 Kconfig 选项(格式为 ``major * 100 + minor``)可以将 eFuse 块版本依赖添加到代码中: -- :ref:`CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL` -- :ref:`CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL` +- ``CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL`` +- ``CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL`` .. _revision_limitation: @@ -103,7 +103,7 @@ ESP-IDF 兼容性检查 最大芯片版本号无法指定,只能由当前使用的 ESP-IDF 版本自动决定。ESP-IDF 会拒绝启动任何超过最大芯片版本号的芯片版本。由于特定版本的 ESP-IDF 无法预知未来的芯片版本更新,因此最大芯片版本号通常设置为 ``maximum supported MAJOR version + 99``。可以设置 “忽略最大版本” eFuse 来绕过最大版本限制,但这不能确保软件正常工作。 -EFuse 块版本号与芯片版本号类似,但是它主要影响在 eFuse 中指定的参数(如 ADC 校正参数等)。如果 eFuse 块版本号在您的应用中并不重要,你可以通过使能 Kconfig 选项 :ref:`CONFIG_ESP_IGNORE_EFUSE_BLOCK_REV_CHECK` 来禁用 eFuse 块版本号检查。 +EFuse 块版本号与芯片版本号类似,但是它主要影响在 eFuse 中指定的参数(如 ADC 校正参数等)。 下文介绍了芯片版本未通过兼容性检查时显示的故障排除信息及解决方法,并描述了在早期 ESP-IDF 版本中与软件行为和兼容性检查相关的技术细节。 @@ -141,7 +141,7 @@ EFuse 块版本号与芯片版本号类似,但是它主要影响在 eFuse 中 而 eFuse 块版本的要求则存储在 :cpp:type:`esp_app_desc_t` 结构体中。该结构体对象位于应用程序的二进制进项文件中。由于 eFuse 块版本信息主要影响 ADC 校准,而二级引导程序的镜像不涉及 ADC,因此我们只需要检查应用程序镜像的 eFuse 块版本信息。有 2 个与 eFuse 块版本相关的字段: - ``min_efuse_blk_rev_full`` - 镜像所需 eFuse 块的最小版本号,格式为 ``major * 100 + minor``。其值由 ``CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL`` 确定。 -- ``max_efuse_blk_rev_full`` - 镜像所需 eFuse 块的最大版本号,格式为 ``major * 100 + minor``。其值由 ``CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL`` 确定。这个值由硬件决定,用户不应对其进行修改,仅当 ESP-IDF 支持新版本时由乐鑫官方进行更改。 +- ``max_efuse_blk_rev_full`` - 镜像所需 eFuse 块的最大版本号,格式为 ``major * 100 + minor``。其值由 ``CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL`` 确定。它反映了当前 ESP-IDF 版本能支持的最大 eFuse 块版本号,不应由用户修改。 最大和最小版本限制 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -154,12 +154,7 @@ EFuse 块版本号与芯片版本号类似,但是它主要影响在 eFuse 中 3. 然后,第 2 阶段引导启动程序会检查应用程序的版本要求。它从应用程序镜像的标头中读取支持的芯片最小和最大版本,以及从段的标头中读取 eFuse 块版本信息,并与 eFuse 中的芯片版本进行比较。如果该芯片版本或 eFuse 块版本低于各自的最小版本或高于最大版本,引导程序会拒绝启动并中止。然而,如果设置了忽略最大版本位,则可以忽略最大版本限制。软件确定可以使用此芯片版本时,用户可以自行设置忽略位。 -4. 接着在应用程序的启动阶段将会检查 eFuse 块版本信息。允许的 eFuse 块最大和最小版本由以下 Kconfig 宏指定: - - * :ref:`CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL` - * :ref:`CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL` - -5. 在空中升级 (OTA) 阶段,运行中的应用程序会检查新软件是否与芯片版本及 eFuse 块版本相匹配。它会从新应用程序镜像的标头中提取最小和最大芯片版本,以及应用程序描述中提取最大和最小 eFuse 块版本,并与 eFuse 中的芯片版本和块版本进行比较。应用程序检查版本匹配的方式与引导启动程序相同,即芯片版本和 eFuse 块版本须处在最小和最大版本之间(忽略最大版本的逻辑也相同)。 +4. 在空中升级 (OTA) 阶段,运行中的应用程序会检查新软件是否与芯片版本及 eFuse 块版本相匹配。它会从新应用程序镜像的标头中提取最小和最大芯片版本,以及应用程序描述中提取最大和最小 eFuse 块版本,并与 eFuse 中的芯片版本和块版本进行比较。应用程序检查版本匹配的方式与引导启动程序相同,即芯片版本和 eFuse 块版本须处在最小和最大版本之间(忽略最大版本的逻辑也相同)。 向后兼容旧版 ESP-IDF 构建的引导启动程序 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^