diff --git a/components/efuse/esp32/esp_efuse_utility.c b/components/efuse/esp32/esp_efuse_utility.c index f50d511921..0d6db9c0bc 100644 --- a/components/efuse/esp32/esp_efuse_utility.c +++ b/components/efuse/esp32/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -70,9 +70,16 @@ esp_err_t esp_efuse_utility_check_errors(void) // Burn values written to the efuse write registers esp_err_t esp_efuse_utility_burn_chip(void) +{ + return esp_efuse_utility_burn_chip_opt(false, true); +} + +esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; #ifdef CONFIG_EFUSE_VIRTUAL + (void) ignore_coding_errors; + (void) verify_written_data; ESP_LOGW(TAG, "Virtual efuses enabled: Not really burning eFuses"); for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) { int subblock = 0; @@ -128,7 +135,7 @@ esp_err_t esp_efuse_utility_burn_chip(void) memcpy(backup_write_data, (void *)start_write_addr[num_block], w_data_len); int repeat_burn_op = 1; bool correct_written_data; - bool coding_error_before = efuse_hal_is_coding_error_in_block(num_block); + bool coding_error_before = !ignore_coding_errors && efuse_hal_is_coding_error_in_block(num_block); if (coding_error_before) { ESP_LOGW(TAG, "BLOCK%d already has a coding error", num_block); } @@ -139,12 +146,12 @@ esp_err_t esp_efuse_utility_burn_chip(void) efuse_hal_program(0); // BURN a block bool coding_error_after = efuse_hal_is_coding_error_in_block(num_block); - coding_error_occurred = (coding_error_before != coding_error_after) && coding_error_before == false; + coding_error_occurred = !ignore_coding_errors && (coding_error_before != coding_error_after) && !coding_error_before; if (coding_error_occurred) { ESP_LOGW(TAG, "BLOCK%d got a coding error", num_block); } - correct_written_data = esp_efuse_utility_is_correct_written_data(num_block, r_data_len); + correct_written_data = (verify_written_data) ? esp_efuse_utility_is_correct_written_data(num_block, r_data_len) : true; if (!correct_written_data || coding_error_occurred) { ESP_LOGW(TAG, "BLOCK%d: next retry to fix an error [%d/3]...", num_block, repeat_burn_op); memcpy((void *)start_write_addr[num_block], (void *)backup_write_data, w_data_len); diff --git a/components/efuse/esp32c2/esp_efuse_utility.c b/components/efuse/esp32c2/esp_efuse_utility.c index cefe171561..e66281cde4 100644 --- a/components/efuse/esp32c2/esp_efuse_utility.c +++ b/components/efuse/esp32c2/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -60,9 +60,16 @@ esp_err_t esp_efuse_utility_check_errors(void) // Burn values written to the efuse write registers esp_err_t esp_efuse_utility_burn_chip(void) +{ + return esp_efuse_utility_burn_chip_opt(false, true); +} + +esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; #ifdef CONFIG_EFUSE_VIRTUAL + (void) ignore_coding_errors; + (void) verify_written_data; ESP_LOGW(TAG, "Virtual efuses enabled: Not really burning eFuses"); for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) { int subblock = 0; @@ -110,7 +117,7 @@ esp_err_t esp_efuse_utility_burn_chip(void) hal_memcpy(backup_write_data, (void *)EFUSE_PGM_DATA0_REG, sizeof(backup_write_data)); int repeat_burn_op = 1; bool correct_written_data; - bool coding_error_before = efuse_hal_is_coding_error_in_block(num_block); + bool coding_error_before = !ignore_coding_errors && efuse_hal_is_coding_error_in_block(num_block); if (coding_error_before) { ESP_LOGW(TAG, "BLOCK%d already has a coding error", num_block); } @@ -128,12 +135,12 @@ esp_err_t esp_efuse_utility_burn_chip(void) break; } } - coding_error_occurred = (coding_error_before != coding_error_after) && coding_error_before == false; + coding_error_occurred = !ignore_coding_errors && (coding_error_before != coding_error_after) && !coding_error_before; if (coding_error_occurred) { ESP_LOGW(TAG, "BLOCK%d got a coding error", num_block); } - correct_written_data = esp_efuse_utility_is_correct_written_data(num_block, r_data_len); + correct_written_data = (verify_written_data) ? esp_efuse_utility_is_correct_written_data(num_block, r_data_len) : true; if (!correct_written_data || coding_error_occurred) { ESP_LOGW(TAG, "BLOCK%d: next retry to fix an error [%d/3]...", num_block, repeat_burn_op); hal_memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)backup_write_data, sizeof(backup_write_data)); diff --git a/components/efuse/esp32c3/esp_efuse_utility.c b/components/efuse/esp32c3/esp_efuse_utility.c index 8608b12390..237fe0aebb 100644 --- a/components/efuse/esp32c3/esp_efuse_utility.c +++ b/components/efuse/esp32c3/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -90,9 +90,16 @@ esp_err_t esp_efuse_utility_check_errors(void) // Burn values written to the efuse write registers esp_err_t esp_efuse_utility_burn_chip(void) +{ + return esp_efuse_utility_burn_chip_opt(false, true); +} + +esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; #ifdef CONFIG_EFUSE_VIRTUAL + (void) ignore_coding_errors; + (void) verify_written_data; ESP_LOGW(TAG, "Virtual efuses enabled: Not really burning eFuses"); for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) { int subblock = 0; @@ -140,7 +147,7 @@ esp_err_t esp_efuse_utility_burn_chip(void) hal_memcpy(backup_write_data, (void *)EFUSE_PGM_DATA0_REG, sizeof(backup_write_data)); int repeat_burn_op = 1; bool correct_written_data; - bool coding_error_before = efuse_hal_is_coding_error_in_block(num_block); + bool coding_error_before = !ignore_coding_errors && efuse_hal_is_coding_error_in_block(num_block); if (coding_error_before) { ESP_LOGW(TAG, "BLOCK%d already has a coding error", num_block); } @@ -158,12 +165,12 @@ esp_err_t esp_efuse_utility_burn_chip(void) break; } } - coding_error_occurred = (coding_error_before != coding_error_after) && coding_error_before == false; + coding_error_occurred = !ignore_coding_errors && (coding_error_before != coding_error_after) && !coding_error_before; if (coding_error_occurred) { ESP_LOGW(TAG, "BLOCK%d got a coding error", num_block); } - correct_written_data = esp_efuse_utility_is_correct_written_data(num_block, r_data_len); + correct_written_data = (verify_written_data) ? esp_efuse_utility_is_correct_written_data(num_block, r_data_len) : true; if (!correct_written_data || coding_error_occurred) { ESP_LOGW(TAG, "BLOCK%d: next retry to fix an error [%d/3]...", num_block, repeat_burn_op); hal_memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)backup_write_data, sizeof(backup_write_data)); diff --git a/components/efuse/esp32c5/esp_efuse_utility.c b/components/efuse/esp32c5/esp_efuse_utility.c index 7077777cfc..39712b77f1 100644 --- a/components/efuse/esp32c5/esp_efuse_utility.c +++ b/components/efuse/esp32c5/esp_efuse_utility.c @@ -81,6 +81,11 @@ esp_err_t esp_efuse_utility_check_errors(void) // Burn values written to the efuse write registers esp_err_t esp_efuse_utility_burn_chip(void) +{ + return esp_efuse_utility_burn_chip_opt(false, true); +} + +esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { // TODO: [ESP32C5] IDF-8674 abort(); diff --git a/components/efuse/esp32c6/esp_efuse_utility.c b/components/efuse/esp32c6/esp_efuse_utility.c index 6227364a1b..0278565e13 100644 --- a/components/efuse/esp32c6/esp_efuse_utility.c +++ b/components/efuse/esp32c6/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -75,9 +75,16 @@ esp_err_t esp_efuse_utility_check_errors(void) // Burn values written to the efuse write registers esp_err_t esp_efuse_utility_burn_chip(void) +{ + return esp_efuse_utility_burn_chip_opt(false, true); +} + +esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; #ifdef CONFIG_EFUSE_VIRTUAL + (void) ignore_coding_errors; + (void) verify_written_data; ESP_LOGW(TAG, "Virtual efuses enabled: Not really burning eFuses"); for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) { int subblock = 0; @@ -125,7 +132,7 @@ esp_err_t esp_efuse_utility_burn_chip(void) hal_memcpy(backup_write_data, (void *)EFUSE_PGM_DATA0_REG, sizeof(backup_write_data)); int repeat_burn_op = 1; bool correct_written_data; - bool coding_error_before = efuse_hal_is_coding_error_in_block(num_block); + bool coding_error_before = !ignore_coding_errors && efuse_hal_is_coding_error_in_block(num_block); if (coding_error_before) { ESP_LOGW(TAG, "BLOCK%d already has a coding error", num_block); } @@ -143,12 +150,12 @@ esp_err_t esp_efuse_utility_burn_chip(void) break; } } - coding_error_occurred = (coding_error_before != coding_error_after) && coding_error_before == false; + coding_error_occurred = !ignore_coding_errors && (coding_error_before != coding_error_after) && !coding_error_before; if (coding_error_occurred) { ESP_LOGW(TAG, "BLOCK%d got a coding error", num_block); } - correct_written_data = esp_efuse_utility_is_correct_written_data(num_block, r_data_len); + correct_written_data = (verify_written_data) ? esp_efuse_utility_is_correct_written_data(num_block, r_data_len) : true; if (!correct_written_data || coding_error_occurred) { ESP_LOGW(TAG, "BLOCK%d: next retry to fix an error [%d/3]...", num_block, repeat_burn_op); hal_memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)backup_write_data, sizeof(backup_write_data)); diff --git a/components/efuse/esp32h2/esp_efuse_utility.c b/components/efuse/esp32h2/esp_efuse_utility.c index b0f9783f68..7d0c66c9c8 100644 --- a/components/efuse/esp32h2/esp_efuse_utility.c +++ b/components/efuse/esp32h2/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -75,9 +75,16 @@ esp_err_t esp_efuse_utility_check_errors(void) // Burn values written to the efuse write registers esp_err_t esp_efuse_utility_burn_chip(void) +{ + return esp_efuse_utility_burn_chip_opt(false, true); +} + +esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; #ifdef CONFIG_EFUSE_VIRTUAL + (void) ignore_coding_errors; + (void) verify_written_data; ESP_LOGW(TAG, "Virtual efuses enabled: Not really burning eFuses"); for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) { int subblock = 0; @@ -125,7 +132,7 @@ esp_err_t esp_efuse_utility_burn_chip(void) hal_memcpy(backup_write_data, (void *)EFUSE_PGM_DATA0_REG, sizeof(backup_write_data)); int repeat_burn_op = 1; bool correct_written_data; - bool coding_error_before = efuse_hal_is_coding_error_in_block(num_block); + bool coding_error_before = !ignore_coding_errors && efuse_hal_is_coding_error_in_block(num_block); if (coding_error_before) { ESP_LOGW(TAG, "BLOCK%d already has a coding error", num_block); } @@ -143,12 +150,12 @@ esp_err_t esp_efuse_utility_burn_chip(void) break; } } - coding_error_occurred = (coding_error_before != coding_error_after) && coding_error_before == false; + coding_error_occurred = !ignore_coding_errors && (coding_error_before != coding_error_after) && !coding_error_before; if (coding_error_occurred) { ESP_LOGW(TAG, "BLOCK%d got a coding error", num_block); } - correct_written_data = esp_efuse_utility_is_correct_written_data(num_block, r_data_len); + correct_written_data = (verify_written_data) ? esp_efuse_utility_is_correct_written_data(num_block, r_data_len) : true; if (!correct_written_data || coding_error_occurred) { ESP_LOGW(TAG, "BLOCK%d: next retry to fix an error [%d/3]...", num_block, repeat_burn_op); hal_memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)backup_write_data, sizeof(backup_write_data)); diff --git a/components/efuse/esp32p4/esp_efuse_utility.c b/components/efuse/esp32p4/esp_efuse_utility.c index 0a5cfd61a3..e095721eff 100644 --- a/components/efuse/esp32p4/esp_efuse_utility.c +++ b/components/efuse/esp32p4/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -75,9 +75,16 @@ esp_err_t esp_efuse_utility_check_errors(void) // Burn values written to the efuse write registers esp_err_t esp_efuse_utility_burn_chip(void) +{ + return esp_efuse_utility_burn_chip_opt(false, true); +} + +esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; #ifdef CONFIG_EFUSE_VIRTUAL + (void) ignore_coding_errors; + (void) verify_written_data; ESP_LOGW(TAG, "Virtual efuses enabled: Not really burning eFuses"); for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) { int subblock = 0; @@ -125,7 +132,7 @@ esp_err_t esp_efuse_utility_burn_chip(void) hal_memcpy(backup_write_data, (void *)EFUSE_PGM_DATA0_REG, sizeof(backup_write_data)); int repeat_burn_op = 1; bool correct_written_data; - bool coding_error_before = efuse_hal_is_coding_error_in_block(num_block); + bool coding_error_before = !ignore_coding_errors && efuse_hal_is_coding_error_in_block(num_block); if (coding_error_before) { ESP_LOGW(TAG, "BLOCK%d already has a coding error", num_block); } @@ -143,12 +150,12 @@ esp_err_t esp_efuse_utility_burn_chip(void) break; } } - coding_error_occurred = (coding_error_before != coding_error_after) && coding_error_before == false; + coding_error_occurred = !ignore_coding_errors && (coding_error_before != coding_error_after) && !coding_error_before; if (coding_error_occurred) { ESP_LOGW(TAG, "BLOCK%d got a coding error", num_block); } - correct_written_data = esp_efuse_utility_is_correct_written_data(num_block, r_data_len); + correct_written_data = (verify_written_data) ? esp_efuse_utility_is_correct_written_data(num_block, r_data_len) : true; if (!correct_written_data || coding_error_occurred) { ESP_LOGW(TAG, "BLOCK%d: next retry to fix an error [%d/3]...", num_block, repeat_burn_op); hal_memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)backup_write_data, sizeof(backup_write_data)); diff --git a/components/efuse/esp32s2/esp_efuse_utility.c b/components/efuse/esp32s2/esp_efuse_utility.c index b37996e1ef..2a9635fbc3 100644 --- a/components/efuse/esp32s2/esp_efuse_utility.c +++ b/components/efuse/esp32s2/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -75,9 +75,16 @@ esp_err_t esp_efuse_utility_check_errors(void) // Burn values written to the efuse write registers esp_err_t esp_efuse_utility_burn_chip(void) +{ + return esp_efuse_utility_burn_chip_opt(false, true); +} + +esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; #ifdef CONFIG_EFUSE_VIRTUAL + (void) ignore_coding_errors; + (void) verify_written_data; ESP_LOGW(TAG, "Virtual efuses enabled: Not really burning eFuses"); for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) { int subblock = 0; @@ -125,7 +132,7 @@ esp_err_t esp_efuse_utility_burn_chip(void) hal_memcpy(backup_write_data, (void *)EFUSE_PGM_DATA0_REG, sizeof(backup_write_data)); int repeat_burn_op = 1; bool correct_written_data; - bool coding_error_before = efuse_hal_is_coding_error_in_block(num_block); + bool coding_error_before = !ignore_coding_errors && efuse_hal_is_coding_error_in_block(num_block); if (coding_error_before) { ESP_LOGW(TAG, "BLOCK%d already has a coding error", num_block); } @@ -143,12 +150,12 @@ esp_err_t esp_efuse_utility_burn_chip(void) break; } } - coding_error_occurred = (coding_error_before != coding_error_after) && coding_error_before == false; + coding_error_occurred = !ignore_coding_errors && (coding_error_before != coding_error_after) && !coding_error_before; if (coding_error_occurred) { ESP_LOGW(TAG, "BLOCK%d got a coding error", num_block); } - correct_written_data = esp_efuse_utility_is_correct_written_data(num_block, r_data_len); + correct_written_data = (verify_written_data) ? esp_efuse_utility_is_correct_written_data(num_block, r_data_len) : true; if (!correct_written_data || coding_error_occurred) { ESP_LOGW(TAG, "BLOCK%d: next retry to fix an error [%d/3]...", num_block, repeat_burn_op); hal_memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)backup_write_data, sizeof(backup_write_data)); diff --git a/components/efuse/esp32s3/esp_efuse_utility.c b/components/efuse/esp32s3/esp_efuse_utility.c index 2d9cbfae89..1a6540ee00 100644 --- a/components/efuse/esp32s3/esp_efuse_utility.c +++ b/components/efuse/esp32s3/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -75,9 +75,16 @@ esp_err_t esp_efuse_utility_check_errors(void) // Burn values written to the efuse write registers esp_err_t esp_efuse_utility_burn_chip(void) +{ + return esp_efuse_utility_burn_chip_opt(false, true); +} + +esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data) { esp_err_t error = ESP_OK; #ifdef CONFIG_EFUSE_VIRTUAL + (void) ignore_coding_errors; + (void) verify_written_data; ESP_LOGW(TAG, "Virtual efuses enabled: Not really burning eFuses"); for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) { int subblock = 0; @@ -125,7 +132,7 @@ esp_err_t esp_efuse_utility_burn_chip(void) hal_memcpy(backup_write_data, (void *)EFUSE_PGM_DATA0_REG, sizeof(backup_write_data)); int repeat_burn_op = 1; bool correct_written_data; - bool coding_error_before = efuse_hal_is_coding_error_in_block(num_block); + bool coding_error_before = !ignore_coding_errors && efuse_hal_is_coding_error_in_block(num_block); if (coding_error_before) { ESP_LOGW(TAG, "BLOCK%d already has a coding error", num_block); } @@ -143,12 +150,12 @@ esp_err_t esp_efuse_utility_burn_chip(void) break; } } - coding_error_occurred = (coding_error_before != coding_error_after) && coding_error_before == false; + coding_error_occurred = !ignore_coding_errors && (coding_error_before != coding_error_after) && !coding_error_before; if (coding_error_occurred) { ESP_LOGW(TAG, "BLOCK%d got a coding error", num_block); } - correct_written_data = esp_efuse_utility_is_correct_written_data(num_block, r_data_len); + correct_written_data = (verify_written_data) ? esp_efuse_utility_is_correct_written_data(num_block, r_data_len) : true; if (!correct_written_data || coding_error_occurred) { ESP_LOGW(TAG, "BLOCK%d: next retry to fix an error [%d/3]...", num_block, repeat_burn_op); hal_memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)backup_write_data, sizeof(backup_write_data)); diff --git a/components/efuse/include/esp_efuse.h b/components/efuse/include/esp_efuse.h index fa075f91ac..be3aca8e18 100644 --- a/components/efuse/include/esp_efuse.h +++ b/components/efuse/include/esp_efuse.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -783,6 +783,29 @@ esp_err_t esp_secure_boot_read_key_digests(esp_secure_boot_key_digests_t *truste */ esp_err_t esp_efuse_check_errors(void); +/** + * @brief Destroys the data in the given efuse block, if possible. + * + * Data destruction occurs through the following steps: + * 1) Destroy data in the block: + * - If write protection is inactive for the block, then unset bits are burned. + * - If write protection is active, the block remains unaltered. + * 2) Set read protection for the block if possible (check write-protection for RD_DIS). + * In this case, data becomes inaccessible, and the software reads it as all zeros. + * If write protection is enabled and read protection can not be set, + * data in the block remains readable (returns an error). + * + * Do not use the batch mode with this function as it does the burning itself! + * + * @param[in] block A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX + * + * @return + * - ESP_OK: Successful. + * - ESP_FAIL: Data remained readable because the block is write-protected + * and read protection can not be set. + */ +esp_err_t esp_efuse_destroy_block(esp_efuse_block_t block); + #ifdef __cplusplus } #endif diff --git a/components/efuse/private_include/esp_efuse_utility.h b/components/efuse/private_include/esp_efuse_utility.h index 930b11e2df..b17fb41198 100644 --- a/components/efuse/private_include/esp_efuse_utility.h +++ b/components/efuse/private_include/esp_efuse_utility.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -114,6 +114,23 @@ esp_err_t esp_efuse_utility_burn_efuses(void); */ esp_err_t esp_efuse_utility_burn_chip(void); +/** + * @brief Chip specific operations to perform the burn of values written to the efuse write registers. + * + * If CONFIG_EFUSE_VIRTUAL is set, writing will not be performed. + * After the function is completed, the writing registers are cleared. + * + * @param[in] ignore_coding_errors If this is true and any coding errors occur, + * they will be ignored and no further attempts + * will be made to correct them. + * @param[in] verify_written_data If this is true, then after burning it will check that all data is set correctly. + * + * @return + * - ESP_OK: The operation was successfully completed. + * - ESP_FAIL: The operation was not successfully completed. + */ +esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify_written_data); + /** * @brief Returns the number of array elements for placing these "bits" in an array with the length of each element equal to "size_of_base". */ diff --git a/components/efuse/src/esp_efuse_api.c b/components/efuse/src/esp_efuse_api.c index 968d95432c..29ed9fbb7a 100644 --- a/components/efuse/src/esp_efuse_api.c +++ b/components/efuse/src/esp_efuse_api.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -292,3 +292,64 @@ esp_err_t esp_efuse_check_errors(void) { return esp_efuse_utility_check_errors(); } + +static esp_err_t destroy_block(esp_efuse_block_t block) +{ +#if CONFIG_IDF_TARGET_ESP32C2 + bool is_read_protected = esp_efuse_read_field_bit(ESP_EFUSE_RD_DIS_KEY0_LOW) && esp_efuse_read_field_bit(ESP_EFUSE_RD_DIS_KEY0_HI); +#else + bool is_read_protected = esp_efuse_get_key_dis_read(block); +#endif + bool is_read_protection_locked = esp_efuse_read_field_bit(ESP_EFUSE_WR_DIS_RD_DIS); + bool is_write_protected = esp_efuse_get_key_dis_write(block); + + // 1. Destroy data in the block, if possible. + if (!is_write_protected) { + // The block is not write-protected, so the data in that block can be overwritten. + // Set the rest unset bits to 1 + // If it is already read-protected then data is all zeros and + unsigned blk_len_bit = 256; +#if CONFIG_IDF_TARGET_ESP32 + if (esp_efuse_get_coding_scheme(block) == EFUSE_CODING_SCHEME_3_4) { + blk_len_bit = 192; + } +#endif // CONFIG_IDF_TARGET_ESP32 + uint32_t data[8 + 3]; // 8 words are data and 3 words are RS coding data + esp_efuse_read_block(block, data, 0, blk_len_bit); + // Inverse data to set only unset bit + for (unsigned i = 0; i < blk_len_bit / 32; i++) { + data[i] = ~data[i]; + } + esp_efuse_write_block(block, data, 0, blk_len_bit); + esp_efuse_utility_burn_chip_opt(true, false); + ESP_LOGI(TAG, "Data has been destroyed in BLOCK%d", block); + } + + // 2. Additionally we set the read-protection. + // Or if data can not be destroyed due to Block is write-protected. + if (!is_read_protected && !is_read_protection_locked) { +#if CONFIG_IDF_TARGET_ESP32C2 + esp_efuse_write_field_bit(ESP_EFUSE_RD_DIS_KEY0_LOW); + esp_efuse_write_field_bit(ESP_EFUSE_RD_DIS_KEY0_HI); +#else + esp_efuse_set_key_dis_read(block); +#endif + ESP_LOGI(TAG, "Data access has been disabled in BLOCK%d (read-protection is on)", block); + } else if (is_write_protected) { + ESP_LOGE(TAG, "Nothing is destroyed, data remains available in BLOCK%d", block); + ESP_LOGE(TAG, "BLOCK is already write-protected and read protection can not be set either"); + return ESP_FAIL; + } + return ESP_OK; +} + +esp_err_t esp_efuse_destroy_block(esp_efuse_block_t block) +{ + if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) { + return ESP_ERR_INVALID_ARG; + } + EFUSE_LOCK_ACQUIRE_RECURSIVE(); + esp_err_t error = destroy_block(block); + EFUSE_LOCK_RELEASE_RECURSIVE(); + return error; +} diff --git a/docs/en/api-reference/system/efuse.rst b/docs/en/api-reference/system/efuse.rst index 5f51568c41..33a6c7fdfb 100644 --- a/docs/en/api-reference/system/efuse.rst +++ b/docs/en/api-reference/system/efuse.rst @@ -287,6 +287,7 @@ Access to the fields is via a pointer to the description structure. API function * :cpp:func:`esp_efuse_find_purpose` - Finds a key block with the particular purpose set. * :cpp:func:`esp_efuse_get_keypurpose_dis_write` - Returns a write protection of the key purpose field for an eFuse key block (for esp32 always true). * :cpp:func:`esp_efuse_key_block_unused` - Returns true if the key block is unused, false otherwise. +* :cpp:func:`esp_efuse_destroy_block` - Destroys the data in this eFuse block. There are two things to do (1) if write protection is not set, then the remaining unset bits are burned, (2) set read protection for this block if it is not locked. For frequently used fields, special functions are made, like this :cpp:func:`esp_efuse_get_pkg_ver`.