Skip to content

Commit 1c2f8b8

Browse files
committed
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)
1 parent f3879f7 commit 1c2f8b8

File tree

23 files changed

+288
-36
lines changed

23 files changed

+288
-36
lines changed

components/bootloader_support/include/bootloader_common.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -181,6 +181,20 @@ uint32_t bootloader_common_get_chip_ver_pkg(void);
181181
*/
182182
esp_err_t bootloader_common_check_chip_validity(const esp_image_header_t* img_hdr, esp_image_type type);
183183

184+
#if !CONFIG_IDF_TARGET_ESP32
185+
/**
186+
* @brief Check the eFuse block revision
187+
*
188+
* @param[in] min_rev_full The required minimum revision of the eFuse block
189+
* @param[in] max_rev_full The required maximum revision of the eFuse block
190+
* @return
191+
* - ESP_OK: The eFuse block revision is in the required range.
192+
* - ESP_OK: DISABLE_BLK_VERSION_MAJOR has been set in the eFuse of the SoC. No requirements shall be checked at this time.
193+
* - ESP_FAIL: The eFuse block revision of this chip does not match the requirement of the current image.
194+
*/
195+
esp_err_t bootloader_common_check_efuse_blk_validity(uint32_t min_rev_full, uint32_t max_rev_full);
196+
#endif // !CONFIG_IDF_TARGET_ESP32
197+
184198
/**
185199
* @brief Configure VDDSDIO, call this API to rise VDDSDIO to 1.9V when VDDSDIO regulator is enabled as 1.8V mode.
186200
*/

components/bootloader_support/src/bootloader_common_loader.c

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#include "esp_rom_caps.h"
2828

2929
#define ESP_PARTITION_HASH_LEN 32 /* SHA-256 digest length */
30-
#define IS_MAX_REV_SET(max_chip_rev_full) (((max_chip_rev_full) != 65535) && ((max_chip_rev_full) != 0))
30+
#define IS_FIELD_SET(rev_full) (((rev_full) != 65535) && ((rev_full) != 0))
3131

3232
static const char* TAG = "boot_comm";
3333

@@ -57,6 +57,31 @@ int bootloader_common_get_active_otadata(esp_ota_select_entry_t *two_otadata)
5757
return bootloader_common_select_otadata(two_otadata, valid_two_otadata, true);
5858
}
5959

60+
#if !CONFIG_IDF_TARGET_ESP32
61+
esp_err_t bootloader_common_check_efuse_blk_validity(uint32_t min_rev_full, uint32_t max_rev_full)
62+
{
63+
esp_err_t err = ESP_OK;
64+
#ifndef CONFIG_IDF_ENV_FPGA
65+
// Check whether the efuse block version satisfy the requirements of current image.
66+
uint32_t revision = efuse_hal_blk_version();
67+
uint32_t major_rev = revision / 100;
68+
uint32_t minor_rev = revision % 100;
69+
if (IS_FIELD_SET(min_rev_full) && !ESP_EFUSE_BLK_REV_ABOVE(revision, min_rev_full)) {
70+
ESP_LOGE(TAG, "Image requires efuse blk rev >= v%"PRIu32".%"PRIu32", but chip is v%"PRIu32".%"PRIu32,
71+
min_rev_full / 100, min_rev_full % 100, major_rev, minor_rev);
72+
err = ESP_FAIL;
73+
}
74+
// If burnt `disable_blk_version_major` bit, skip the max version check
75+
if ((IS_FIELD_SET(max_rev_full) && (revision > max_rev_full) && !efuse_hal_get_disable_blk_version_major())) {
76+
ESP_LOGE(TAG, "Image requires efuse blk rev <= v%"PRIu32".%"PRIu32", but chip is v%"PRIu32".%"PRIu32,
77+
max_rev_full / 100, max_rev_full % 100, major_rev, minor_rev);
78+
err = ESP_FAIL;
79+
}
80+
#endif
81+
return err;
82+
}
83+
#endif // !CONFIG_IDF_TARGET_ESP32
84+
6085
esp_err_t bootloader_common_check_chip_validity(const esp_image_header_t* img_hdr, esp_image_type type)
6186
{
6287
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
80105
}
81106
if (type == ESP_IMAGE_APPLICATION) {
82107
unsigned max_rev = img_hdr->max_chip_rev_full;
83-
if ((IS_MAX_REV_SET(max_rev) && (revision > max_rev) && !efuse_hal_get_disable_wafer_version_major())) {
108+
if ((IS_FIELD_SET(max_rev) && (revision > max_rev) && !efuse_hal_get_disable_wafer_version_major())) {
84109
ESP_LOGE(TAG, "Image requires chip rev <= v%d.%d, but chip is v%d.%d",
85110
max_rev / 100, max_rev % 100,
86111
major_rev, minor_rev);

components/bootloader_support/src/bootloader_init.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,17 @@ esp_err_t bootloader_read_bootloader_header(void)
4343

4444
esp_err_t bootloader_check_bootloader_validity(void)
4545
{
46-
unsigned int revision = efuse_hal_chip_revision();
47-
unsigned int major = revision / 100;
48-
unsigned int minor = revision % 100;
49-
ESP_EARLY_LOGI(TAG, "chip revision: v%d.%d", major, minor);
46+
unsigned int chip_revision = efuse_hal_chip_revision();
47+
unsigned int chip_major_rev = chip_revision / 100;
48+
unsigned int chip_minor_rev = chip_revision % 100;
49+
ESP_EARLY_LOGI(TAG, "chip revision: v%d.%d", chip_major_rev, chip_minor_rev);
50+
/* ESP32 doesn't have more memory and more efuse bits for block major version. */
51+
#if !CONFIG_IDF_TARGET_ESP32
52+
unsigned int efuse_revision = efuse_hal_blk_version();
53+
unsigned int efuse_major_rev = efuse_revision / 100;
54+
unsigned int efuse_minor_rev = efuse_revision % 100;
55+
ESP_EARLY_LOGI(TAG, "efuse block revision: v%d.%d", efuse_major_rev, efuse_minor_rev);
56+
#endif // !CONFIG_IDF_TARGET_ESP32
5057
/* compare with the one set in bootloader image header */
5158
if (bootloader_common_check_chip_validity(&bootloader_image_hdr, ESP_IMAGE_BOOTLOADER) != ESP_OK) {
5259
return ESP_FAIL;

components/bootloader_support/src/esp_image_format.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -691,19 +691,28 @@ static esp_err_t process_segment_data(int segment, intptr_t load_addr, uint32_t
691691

692692
const uint32_t *src = data;
693693

694-
#if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
695694
// Case I: Bootloader verifying application
696695
// Case II: Bootloader verifying bootloader
697-
// Anti-rollback check should handle only Case I from above.
696+
// The esp_app_desc_t structure is located in DROM and is always in segment #0.
697+
// Anti-rollback check and efuse block version check should handle only Case I from above.
698698
if (segment == 0 && metadata->start_addr != ESP_BOOTLOADER_OFFSET) {
699+
/* ESP32 doesn't have more memory and more efuse bits for block major version. */
700+
#if !CONFIG_IDF_TARGET_ESP32
701+
const esp_app_desc_t *app_desc = (const esp_app_desc_t *)src;
702+
esp_err_t ret = bootloader_common_check_efuse_blk_validity(app_desc->min_efuse_blk_rev_full, app_desc->max_efuse_blk_rev_full);
703+
if (ret != ESP_OK) {
704+
bootloader_munmap(data);
705+
return ret;
706+
}
707+
#endif // !CONFIG_IDF_TARGET_ESP32
708+
#if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
699709
ESP_LOGD(TAG, "additional anti-rollback check 0x%"PRIx32, data_addr);
700-
// The esp_app_desc_t structure is located in DROM and is always in segment #0.
701710
size_t len = process_esp_app_desc_data(src, sha_handle, checksum, metadata);
702711
data_len -= len;
703712
src += len / 4;
704713
// In BOOTLOADER_BUILD, for DROM (segment #0) we do not load it into dest (only map it), do_load = false.
705-
}
706714
#endif // CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
715+
}
707716

708717
for (size_t i = 0; i < data_len; i += 4) {
709718
int w_i = i / 4; // Word index

components/esp_app_format/esp_app_desc.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ const __attribute__((weak)) __attribute__((section(".rodata_desc"))) esp_app_de
5757
.time = "",
5858
.date = "",
5959
#endif
60+
.min_efuse_blk_rev_full = CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL,
61+
.max_efuse_blk_rev_full = CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL,
6062
};
6163

6264
#ifndef CONFIG_APP_EXCLUDE_PROJECT_VER_VAR

components/esp_app_format/include/esp_app_desc.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ typedef struct {
3333
char date[16]; /*!< Compile date*/
3434
char idf_ver[32]; /*!< Version IDF */
3535
uint8_t app_elf_sha256[32]; /*!< sha256 of elf file */
36-
uint32_t reserv2[20]; /*!< reserv2 */
36+
uint16_t min_efuse_blk_rev_full; /*!< Minimal eFuse block revision supported by image, in format: major * 100 + minor */
37+
uint16_t max_efuse_blk_rev_full; /*!< Maximal eFuse block revision supported by image, in format: major * 100 + minor */
38+
uint32_t reserv2[19]; /*!< reserv2 */
3739
} esp_app_desc_t;
3840

3941
/** @cond */

components/esp_hw_support/port/esp32/Kconfig.hw_support

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,20 @@ config ESP32_REV_MAX_FULL
6666
config ESP_REV_MAX_FULL
6767
int
6868
default ESP32_REV_MAX_FULL
69+
70+
config ESP_EFUSE_BLOCK_REV_MIN_FULL
71+
int "Minimum Supported ESP32 eFuse Block Revision"
72+
default 0
73+
help
74+
Required minimum eFuse Block revision. ESP-IDF will check it at the 2nd bootloader stage
75+
whether the current image can work correctly for this eFuse Block revision.
76+
So that to avoid running an incompatible image on a SoC that contains breaking change in the eFuse Block.
77+
If you want to update this value to run the image that not compatible with the current eFuse Block revision,
78+
please contact to Espressif's business team for details:
79+
https://www.espressif.com.cn/en/contact-us/sales-questions
80+
81+
config ESP_EFUSE_BLOCK_REV_MAX_FULL
82+
int
83+
default 99
84+
comment "Maximum Supported ESP32 eFuse Block Revision (eFuse Block Rev v0.99)"
85+
# The revision in the comment must correspond to the default value of ESP_EFUSE_BLOCK_REV_MAX_FULL

components/esp_hw_support/port/esp32c2/Kconfig.hw_support

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,21 @@ config ESP_REV_MAX_FULL
4747
config ESP32C2_REV2_DEVELOPMENT
4848
bool "Develop on ESP32-C2 v2.0 (Preview)"
4949
default y if IDF_CI_BUILD
50+
51+
config ESP_EFUSE_BLOCK_REV_MIN_FULL
52+
int "Minimum Supported ESP32-C2 eFuse Block Revision"
53+
default 0
54+
help
55+
Required minimum eFuse Block revision. ESP-IDF will check it at the 2nd bootloader stage
56+
whether the current image can work correctly for this eFuse Block revision.
57+
So that to avoid running an incompatible image on a SoC that contains breaking change in the eFuse Block.
58+
If you want to update this value to run the image that not compatible with the current eFuse Block revision,
59+
please contact to Espressif's business team for details:
60+
https://www.espressif.com.cn/en/contact-us/sales-questions
61+
62+
63+
config ESP_EFUSE_BLOCK_REV_MAX_FULL
64+
int
65+
default 99
66+
comment "Maximum Supported ESP32-C2 eFuse Block Revision (eFuse Block Rev v0.99)"
67+
# The revision in the comment must correspond to the default value of ESP_EFUSE_BLOCK_REV_MAX_FULL

components/esp_hw_support/port/esp32c3/Kconfig.hw_support

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,20 @@ config ESP32C3_REV_MAX_FULL
5454
config ESP_REV_MAX_FULL
5555
int
5656
default ESP32C3_REV_MAX_FULL
57+
58+
config ESP_EFUSE_BLOCK_REV_MIN_FULL
59+
int "Minimum Supported ESP32-C3 eFuse Block Revision"
60+
default 100
61+
help
62+
Required minimum eFuse Block revision. ESP-IDF will check it at the 2nd bootloader stage
63+
whether the current image can work correctly for this eFuse Block revision.
64+
So that to avoid running an incompatible image on a SoC that contains breaking change in the eFuse Block.
65+
If you want to update this value to run the image that not compatible with the current eFuse Block revision,
66+
please contact to Espressif's business team for details:
67+
https://www.espressif.com.cn/en/contact-us/sales-questions
68+
69+
config ESP_EFUSE_BLOCK_REV_MAX_FULL
70+
int
71+
default 199
72+
comment "Maximum Supported ESP32-C3 eFuse Block Revision (eFuse Block Rev v1.99)"
73+
# The revision in the comment must correspond to the default value of ESP_EFUSE_BLOCK_REV_MAX_FULL

components/esp_hw_support/port/esp32c5/Kconfig.hw_support

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,20 @@ config ESP32C5_REV_MAX_FULL
3939
config ESP_REV_MAX_FULL
4040
int
4141
default ESP32C5_REV_MAX_FULL
42+
43+
config ESP_EFUSE_BLOCK_REV_MIN_FULL
44+
int "Minimum Supported ESP32-C5 eFuse Block Revision"
45+
default 0
46+
help
47+
Required minimum eFuse Block revision. ESP-IDF will check it at the 2nd bootloader stage
48+
whether the current image can work correctly for this eFuse Block revision.
49+
So that to avoid running an incompatible image on a SoC that contains breaking change in the eFuse Block.
50+
If you want to update this value to run the image that not compatible with the current eFuse Block revision,
51+
please contact to Espressif's business team for details:
52+
https://www.espressif.com.cn/en/contact-us/sales-questions
53+
54+
config ESP_EFUSE_BLOCK_REV_MAX_FULL
55+
int
56+
default 99
57+
comment "Maximum Supported ESP32-C5 eFuse Block Revision (eFuse Block Rev v0.99)"
58+
# The revision in the comment must correspond to the default value of ESP_EFUSE_BLOCK_REV_MAX_FULL

0 commit comments

Comments
 (0)