Skip to content

Commit

Permalink
Merge branch 'feature/check_efuse_blk_after_ota' into 'master'
Browse files Browse the repository at this point in the history
feat(bootloader): support to check efuse block revision

Closes IDF-10718

See merge request espressif/esp-idf!30772
  • Loading branch information
L-KAYA committed Aug 26, 2024
2 parents 18e8e18 + da4a7f7 commit c9df77e
Show file tree
Hide file tree
Showing 23 changed files with 352 additions and 34 deletions.
16 changes: 15 additions & 1 deletion components/bootloader_support/include/bootloader_common.h
Original file line number Diff line number Diff line change
@@ -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
*/
Expand Down Expand Up @@ -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.
*/
Expand Down
29 changes: 27 additions & 2 deletions components/bootloader_support/src/bootloader_common_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down
15 changes: 11 additions & 4 deletions components/bootloader_support/src/bootloader_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
17 changes: 13 additions & 4 deletions components/bootloader_support/src/esp_image_format.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions components/esp_app_format/esp_app_desc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion components/esp_app_format/include/esp_app_desc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
17 changes: 17 additions & 0 deletions components/esp_hw_support/port/esp32/Kconfig.hw_support
Original file line number Diff line number Diff line change
Expand Up @@ -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
18 changes: 18 additions & 0 deletions components/esp_hw_support/port/esp32c2/Kconfig.hw_support
Original file line number Diff line number Diff line change
Expand Up @@ -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
17 changes: 17 additions & 0 deletions components/esp_hw_support/port/esp32c3/Kconfig.hw_support
Original file line number Diff line number Diff line change
Expand Up @@ -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 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-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
17 changes: 17 additions & 0 deletions components/esp_hw_support/port/esp32c5/Kconfig.hw_support
Original file line number Diff line number Diff line change
Expand Up @@ -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
17 changes: 17 additions & 0 deletions components/esp_hw_support/port/esp32c6/Kconfig.hw_support
Original file line number Diff line number Diff line change
Expand Up @@ -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
17 changes: 17 additions & 0 deletions components/esp_hw_support/port/esp32c61/Kconfig.hw_support
Original file line number Diff line number Diff line change
Expand Up @@ -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
17 changes: 17 additions & 0 deletions components/esp_hw_support/port/esp32h2/Kconfig.hw_support
Original file line number Diff line number Diff line change
Expand Up @@ -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
17 changes: 17 additions & 0 deletions components/esp_hw_support/port/esp32p4/Kconfig.hw_support
Original file line number Diff line number Diff line change
Expand Up @@ -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
17 changes: 17 additions & 0 deletions components/esp_hw_support/port/esp32s2/Kconfig.hw_support
Original file line number Diff line number Diff line change
Expand Up @@ -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 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-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
17 changes: 17 additions & 0 deletions components/esp_hw_support/port/esp32s3/Kconfig.hw_support
Original file line number Diff line number Diff line change
Expand Up @@ -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
8 changes: 8 additions & 0 deletions components/esp_hw_support/port/linux/Kconfig.hw_support
Original file line number Diff line number Diff line change
Expand Up @@ -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
7 changes: 6 additions & 1 deletion components/hal/efuse_hal.c
Original file line number Diff line number Diff line change
@@ -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
*/
Expand Down Expand Up @@ -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();
Expand Down
Loading

0 comments on commit c9df77e

Please sign in to comment.