diff --git a/components/efuse/include/esp_efuse.h b/components/efuse/include/esp_efuse.h index 5e0d3d1277..0413801fab 100644 --- a/components/efuse/include/esp_efuse.h +++ b/components/efuse/include/esp_efuse.h @@ -763,6 +763,20 @@ esp_err_t esp_efuse_write_keys(esp_efuse_purpose_t purposes[], uint8_t keys[][32 #endif // not CONFIG_IDF_TARGET_ESP32 +/** + * @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 6f790604e9..3dcab77a8e 100644 --- a/components/efuse/private_include/esp_efuse_utility.h +++ b/components/efuse/private_include/esp_efuse_utility.h @@ -154,6 +154,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/esp32/esp_efuse_utility.c b/components/efuse/src/esp32/esp_efuse_utility.c index 5a7de78183..d4f67a72e1 100644 --- a/components/efuse/src/esp32/esp_efuse_utility.c +++ b/components/efuse/src/esp32/esp_efuse_utility.c @@ -126,6 +126,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_efuses(void) { diff --git a/components/efuse/src/esp32c3/esp_efuse_utility.c b/components/efuse/src/esp32c3/esp_efuse_utility.c index be87dd220f..bf4b6d12cd 100644 --- a/components/efuse/src/esp32c3/esp_efuse_utility.c +++ b/components/efuse/src/esp32c3/esp_efuse_utility.c @@ -120,6 +120,27 @@ void esp_efuse_utility_clear_program_registers(void) ets_efuse_clear_program_registers(); } + +esp_err_t esp_efuse_utility_check_errors(void) +{ + if (REG_GET_BIT(EFUSE_RD_REPEAT_DATA3_REG, EFUSE_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_read(); + return ESP_FAIL; + } + } + } + } + return ESP_OK; +} + // Burn values written to the efuse write registers esp_err_t esp_efuse_utility_burn_efuses(void) { diff --git a/components/efuse/src/esp32s2/esp_efuse_utility.c b/components/efuse/src/esp32s2/esp_efuse_utility.c index dfedee218d..d179586b88 100644 --- a/components/efuse/src/esp32s2/esp_efuse_utility.c +++ b/components/efuse/src/esp32s2/esp_efuse_utility.c @@ -96,6 +96,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_efuses(void) { diff --git a/components/efuse/src/esp32s3/esp_efuse_utility.c b/components/efuse/src/esp32s3/esp_efuse_utility.c index 044509d295..6c3482e61b 100644 --- a/components/efuse/src/esp32s3/esp_efuse_utility.c +++ b/components/efuse/src/esp32s3/esp_efuse_utility.c @@ -96,6 +96,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_efuses(void) { diff --git a/components/efuse/src/esp_efuse_api.c b/components/efuse/src/esp_efuse_api.c index 51ca7d2a90..db62019f9c 100644 --- a/components/efuse/src/esp_efuse_api.c +++ b/components/efuse/src/esp_efuse_api.c @@ -283,6 +283,10 @@ 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(); +} #ifndef CONFIG_IDF_TARGET_ESP32 diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index f22a78a276..f34e6d68f3 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -23,7 +23,7 @@ #include "esp_system.h" #include "esp_rom_uart.h" - +#include "esp_efuse.h" #include "esp_clk_internal.h" #include "esp_rom_efuse.h" #include "esp_rom_sys.h" @@ -340,6 +340,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 /* 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);