From c563d799fe95e482edbe3be2f152c49c60b786aa Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Wed, 11 Aug 2021 19:06:48 +0500 Subject: [PATCH] efuse: Checks errors of 4x coding scheme for BLOCK0 if so then abort --- components/efuse/esp32/esp_efuse_utility.c | 5 +++++ components/efuse/esp32c3/esp_efuse_utility.c | 20 +++++++++++++++++++ components/efuse/esp32h2/esp_efuse_utility.c | 5 +++++ components/efuse/esp32s2/esp_efuse_utility.c | 5 +++++ components/efuse/esp32s3/esp_efuse_utility.c | 5 +++++ components/efuse/include/esp_efuse.h | 14 +++++++++++++ .../efuse/private_include/esp_efuse_utility.h | 14 +++++++++++++ components/efuse/src/esp_efuse_api.c | 5 +++++ components/esp_system/port/cpu_start.c | 4 ++++ 9 files changed, 77 insertions(+) diff --git a/components/efuse/esp32/esp_efuse_utility.c b/components/efuse/esp32/esp_efuse_utility.c index c226936bdc..8075cf3981 100644 --- a/components/efuse/esp32/esp_efuse_utility.c +++ b/components/efuse/esp32/esp_efuse_utility.c @@ -118,6 +118,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/esp32c3/esp_efuse_utility.c b/components/efuse/esp32c3/esp_efuse_utility.c index 5cd15b0151..2e2c8a35ba 100644 --- a/components/efuse/esp32c3/esp_efuse_utility.c +++ b/components/efuse/esp32c3/esp_efuse_utility.c @@ -120,6 +120,26 @@ 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_chip(void) { diff --git a/components/efuse/esp32h2/esp_efuse_utility.c b/components/efuse/esp32h2/esp_efuse_utility.c index aae6038e2f..e85770cef9 100644 --- a/components/efuse/esp32h2/esp_efuse_utility.c +++ b/components/efuse/esp32h2/esp_efuse_utility.c @@ -95,6 +95,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/esp32s2/esp_efuse_utility.c b/components/efuse/esp32s2/esp_efuse_utility.c index 79b963fab8..1572e051df 100644 --- a/components/efuse/esp32s2/esp_efuse_utility.c +++ b/components/efuse/esp32s2/esp_efuse_utility.c @@ -88,6 +88,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/esp32s3/esp_efuse_utility.c b/components/efuse/esp32s3/esp_efuse_utility.c index f94efc8506..b2bc5b0580 100644 --- a/components/efuse/esp32s3/esp_efuse_utility.c +++ b/components/efuse/esp32s3/esp_efuse_utility.c @@ -113,6 +113,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/include/esp_efuse.h b/components/efuse/include/esp_efuse.h index 02300ccfa7..435b5e100f 100644 --- a/components/efuse/include/esp_efuse.h +++ b/components/efuse/include/esp_efuse.h @@ -761,6 +761,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 e09b5d39d1..93cab16fcc 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -353,6 +353,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 /* 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);