From 0a71dce1ef8f4da038587dbbba2b0b2753c2df67 Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Wed, 11 Aug 2021 12:20:17 +0500 Subject: [PATCH 1/2] reset_reasons: EFUSE_RST is treated as POWERON_RST ESP32 does not have the EFUSE_RST, the rest chips has this reset reason. --- components/bootloader_support/src/esp_image_format.c | 6 +++++- components/esp_rom/include/esp32s2/rom/rtc.h | 1 + components/esp_system/port/soc/esp32c3/clk.c | 6 +++++- components/esp_system/port/soc/esp32c3/reset_reason.c | 3 +++ components/soc/esp32c3/include/soc/soc_caps.h | 2 +- 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/components/bootloader_support/src/esp_image_format.c b/components/bootloader_support/src/esp_image_format.c index 6d83b506f1..ad81bc5443 100644 --- a/components/bootloader_support/src/esp_image_format.c +++ b/components/bootloader_support/src/esp_image_format.c @@ -259,7 +259,11 @@ esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metad #if CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS mode = ESP_IMAGE_LOAD_NO_VALIDATE; #elif CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON - if (rtc_get_reset_reason(0) == POWERON_RESET) { + if (rtc_get_reset_reason(0) == POWERON_RESET +#if SOC_EFUSE_HAS_EFUSE_RST_BUG + || rtc_get_reset_reason(0) == EFUSE_RESET +#endif + ) { mode = ESP_IMAGE_LOAD_NO_VALIDATE; } #endif // CONFIG_BOOTLOADER_SKIP_... diff --git a/components/esp_rom/include/esp32s2/rom/rtc.h b/components/esp_rom/include/esp32s2/rom/rtc.h index 535dc64a9a..dcbce7f7a0 100644 --- a/components/esp_rom/include/esp32s2/rom/rtc.h +++ b/components/esp_rom/include/esp32s2/rom/rtc.h @@ -94,6 +94,7 @@ typedef enum { TG1WDT_CPU_RESET = 17, /**<17, Time Group1 reset CPU*/ SUPER_WDT_RESET = 18, /**<18, super watchdog reset digital core and rtc module*/ GLITCH_RTC_RESET = 19, /**<19, glitch reset digital core and rtc module*/ + EFUSE_RESET = 20, /**<20, efuse reset digital core*/ } RESET_REASON; typedef enum { diff --git a/components/esp_system/port/soc/esp32c3/clk.c b/components/esp_system/port/soc/esp32c3/clk.c index d3b63ef5e7..2cad1cc9fc 100644 --- a/components/esp_system/port/soc/esp32c3/clk.c +++ b/components/esp_system/port/soc/esp32c3/clk.c @@ -77,7 +77,11 @@ static const char *TAG = "clk"; rtc_config_t cfg = RTC_CONFIG_DEFAULT(); RESET_REASON rst_reas; rst_reas = rtc_get_reset_reason(0); - if (rst_reas == POWERON_RESET) { + if (rst_reas == POWERON_RESET +#if SOC_EFUSE_HAS_EFUSE_RST_BUG + || rst_reas == EFUSE_RESET +#endif + ) { cfg.cali_ocode = 1; } rtc_init(cfg); diff --git a/components/esp_system/port/soc/esp32c3/reset_reason.c b/components/esp_system/port/soc/esp32c3/reset_reason.c index 98e93d5934..e962ed38b2 100644 --- a/components/esp_system/port/soc/esp32c3/reset_reason.c +++ b/components/esp_system/port/soc/esp32c3/reset_reason.c @@ -25,6 +25,9 @@ static esp_reset_reason_t get_reset_reason(RESET_REASON rtc_reset_reason, esp_re { switch (rtc_reset_reason) { case POWERON_RESET: +#if SOC_EFUSE_HAS_EFUSE_RST_BUG + case EFUSE_RESET: +#endif return ESP_RST_POWERON; case RTC_SW_CPU_RESET: diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index 5189f7b341..5dd7719896 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -18,7 +18,7 @@ /*-------------------------- COMMON CAPS ---------------------------------------*/ #define SOC_SUPPORTS_SECURE_DL_MODE 1 #define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS 3 - +#define SOC_EFUSE_HAS_EFUSE_RST_BUG 1 /*-------------------------- AES CAPS -----------------------------------------*/ #define SOC_AES_SUPPORT_DMA (1) From 714bc66e0e6b589214df182c970a53da201ef410 Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Mon, 30 Aug 2021 18:28:31 +0500 Subject: [PATCH 2/2] efuse: Checks errors of 4x coding scheme for BLOCK0 if so then abort --- components/efuse/include/esp_efuse.h | 14 +++++++++++++ .../efuse/private_include/esp_efuse_utility.h | 14 +++++++++++++ .../efuse/src/esp32/esp_efuse_utility.c | 5 +++++ .../efuse/src/esp32c3/esp_efuse_utility.c | 21 +++++++++++++++++++ .../efuse/src/esp32s2/esp_efuse_utility.c | 5 +++++ .../efuse/src/esp32s3/esp_efuse_utility.c | 5 +++++ components/efuse/src/esp_efuse_api.c | 4 ++++ components/esp_system/port/cpu_start.c | 6 +++++- 8 files changed, 73 insertions(+), 1 deletion(-) 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);