diff --git a/components/efuse/esp32/esp_efuse_utility.c b/components/efuse/esp32/esp_efuse_utility.c index c57672ecd3..f50d511921 100644 --- a/components/efuse/esp32/esp_efuse_utility.c +++ b/components/efuse/esp32/esp_efuse_utility.c @@ -63,6 +63,11 @@ void esp_efuse_utility_clear_program_registers(void) efuse_hal_clear_program_registers(); } +esp_err_t esp_efuse_utility_check_errors(void) +{ + return ESP_OK; +} + // Burn values written to the efuse write registers esp_err_t esp_efuse_utility_burn_chip(void) { diff --git a/components/efuse/esp32c2/esp_efuse_utility.c b/components/efuse/esp32c2/esp_efuse_utility.c index 207cf638dc..2d3baf6d2b 100644 --- a/components/efuse/esp32c2/esp_efuse_utility.c +++ b/components/efuse/esp32c2/esp_efuse_utility.c @@ -54,6 +54,11 @@ void esp_efuse_utility_clear_program_registers(void) ets_efuse_clear_program_registers(); } +esp_err_t esp_efuse_utility_check_errors(void) +{ + return ESP_OK; +} + // Burn values written to the efuse write registers esp_err_t esp_efuse_utility_burn_chip(void) { diff --git a/components/efuse/esp32c3/esp_efuse_utility.c b/components/efuse/esp32c3/esp_efuse_utility.c index 5270737c8a..e5052a0f90 100644 --- a/components/efuse/esp32c3/esp_efuse_utility.c +++ b/components/efuse/esp32c3/esp_efuse_utility.c @@ -68,6 +68,26 @@ void esp_efuse_utility_clear_program_registers(void) efuse_hal_clear_program_registers(); } +esp_err_t esp_efuse_utility_check_errors(void) +{ + if (efuse_ll_get_err_rst_enable()) { + for (unsigned i = 0; i < 5; i++) { + uint32_t error_reg = REG_READ(EFUSE_RD_REPEAT_ERR0_REG + i * 4); + if (error_reg) { + uint32_t data_reg = REG_READ(EFUSE_RD_REPEAT_DATA0_REG + i * 4); + if (error_reg & data_reg) { + // For 0001 situation (4x coding scheme): + // an error bit points that data bit is wrong in case the data bit equals 1. (need to reboot in this case). + ESP_EARLY_LOGE(TAG, "Error in EFUSE_RD_REPEAT_DATA%d_REG of BLOCK0 (error_reg=0x%08x, data_reg=0x%08x). Need to reboot", i, error_reg, data_reg); + efuse_hal_read(); + return ESP_FAIL; + } + } + } + } + return ESP_OK; +} + // Burn values written to the efuse write registers esp_err_t esp_efuse_utility_burn_chip(void) { diff --git a/components/efuse/esp32h2/esp_efuse_utility.c b/components/efuse/esp32h2/esp_efuse_utility.c index 5270737c8a..812221848a 100644 --- a/components/efuse/esp32h2/esp_efuse_utility.c +++ b/components/efuse/esp32h2/esp_efuse_utility.c @@ -68,6 +68,11 @@ void esp_efuse_utility_clear_program_registers(void) efuse_hal_clear_program_registers(); } +esp_err_t esp_efuse_utility_check_errors(void) +{ + return ESP_OK; +} + // Burn values written to the efuse write registers esp_err_t esp_efuse_utility_burn_chip(void) { diff --git a/components/efuse/esp32s2/esp_efuse_utility.c b/components/efuse/esp32s2/esp_efuse_utility.c index 7d0a25e4aa..057fe1167f 100644 --- a/components/efuse/esp32s2/esp_efuse_utility.c +++ b/components/efuse/esp32s2/esp_efuse_utility.c @@ -68,6 +68,11 @@ void esp_efuse_utility_clear_program_registers(void) efuse_hal_clear_program_registers(); } +esp_err_t esp_efuse_utility_check_errors(void) +{ + return ESP_OK; +} + // Burn values written to the efuse write registers esp_err_t esp_efuse_utility_burn_chip(void) { diff --git a/components/efuse/esp32s3/esp_efuse_utility.c b/components/efuse/esp32s3/esp_efuse_utility.c index e601ba39e0..2b126c9a2f 100644 --- a/components/efuse/esp32s3/esp_efuse_utility.c +++ b/components/efuse/esp32s3/esp_efuse_utility.c @@ -68,6 +68,11 @@ void esp_efuse_utility_clear_program_registers(void) efuse_hal_clear_program_registers(); } +esp_err_t esp_efuse_utility_check_errors(void) +{ + return ESP_OK; +} + // Burn values written to the efuse write registers esp_err_t esp_efuse_utility_burn_chip(void) { diff --git a/components/efuse/include/esp_efuse.h b/components/efuse/include/esp_efuse.h index c19e75c8df..3b2cd650bf 100644 --- a/components/efuse/include/esp_efuse.h +++ b/components/efuse/include/esp_efuse.h @@ -765,6 +765,20 @@ esp_err_t esp_efuse_write_keys(const esp_efuse_purpose_t purposes[], uint8_t key esp_err_t esp_secure_boot_read_key_digests(ets_secure_boot_key_digests_t *trusted_keys); #endif +/** + * @brief Checks eFuse errors in BLOCK0. + * + * @note Refers to ESP32-C3 only. + * + * It does a BLOCK0 check if eFuse EFUSE_ERR_RST_ENABLE is set. + * If BLOCK0 has an error, it prints the error and returns ESP_FAIL, which should be treated as esp_restart. + * + * @return + * - ESP_OK: No errors in BLOCK0. + * - ESP_FAIL: Error in BLOCK0 requiring reboot. + */ +esp_err_t esp_efuse_check_errors(void); + #ifdef __cplusplus } #endif diff --git a/components/efuse/private_include/esp_efuse_utility.h b/components/efuse/private_include/esp_efuse_utility.h index 0fd026e3e7..eff98482b8 100644 --- a/components/efuse/private_include/esp_efuse_utility.h +++ b/components/efuse/private_include/esp_efuse_utility.h @@ -160,6 +160,20 @@ void esp_efuse_utility_erase_virt_blocks(void); */ esp_err_t esp_efuse_utility_apply_new_coding_scheme(void); +/** + * @brief Checks eFuse errors in BLOCK0. + * + * @note Refers to ESP32-C3 only. + * + * It does a BLOCK0 check if eFuse EFUSE_ERR_RST_ENABLE is set. + * If BLOCK0 has an error, it prints the error and returns ESP_FAIL, which should be treated as esp_restart. + * + * @return + * - ESP_OK: No errors in BLOCK0. + * - ESP_FAIL: Error in BLOCK0 requiring reboot. + */ +esp_err_t esp_efuse_utility_check_errors(void); + /** * @brief Efuse read operation: copies data from physical efuses to efuse read registers. */ diff --git a/components/efuse/src/esp_efuse_api.c b/components/efuse/src/esp_efuse_api.c index 09c55bb50c..968d95432c 100644 --- a/components/efuse/src/esp_efuse_api.c +++ b/components/efuse/src/esp_efuse_api.c @@ -287,3 +287,8 @@ esp_err_t esp_efuse_batch_write_commit(void) } return ESP_OK; } + +esp_err_t esp_efuse_check_errors(void) +{ + return esp_efuse_utility_check_errors(); +} diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index aa5ec0d2e7..b126349cf4 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -345,6 +345,10 @@ void IRAM_ATTR call_start_cpu0(void) Cache_Resume_DCache(0); #endif // CONFIG_IDF_TARGET_ESP32S3 + if (esp_efuse_check_errors() != ESP_OK) { + esp_restart(); + } + #if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 /* Configure the Cache MMU size for instruction and rodata in flash. */ extern uint32_t Cache_Set_IDROM_MMU_Size(uint32_t irom_size, uint32_t drom_size);