From 46f0313d6b12c887306a2d797955c35c0a7c362e 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. --- .../bootloader_support/src/esp_image_format.c | 6 +++++- components/esp_rom/include/esp32s2/rom/rtc.h | 2 ++ components/esp_system/port/soc/esp32c3/clk.c | 6 +++++- .../port/soc/esp32c3/reset_reason.c | 21 +++++++------------ .../esp32c3/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32c3/include/soc/soc_caps.h | 1 + .../soc/esp32s2/include/soc/reset_reasons.h | 19 ++++++----------- tools/ci/check_copyright_ignore.txt | 2 -- 8 files changed, 31 insertions(+), 30 deletions(-) diff --git a/components/bootloader_support/src/esp_image_format.c b/components/bootloader_support/src/esp_image_format.c index 93d41ff814..c404cdb550 100644 --- a/components/bootloader_support/src/esp_image_format.c +++ b/components/bootloader_support/src/esp_image_format.c @@ -256,7 +256,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 (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON) { + if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON +#if SOC_EFUSE_HAS_EFUSE_RST_BUG + || esp_rom_get_reset_reason(0) == RESET_REASON_CORE_EFUSE_CRC +#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 1c1b03ba8c..7ea8fef116 100644 --- a/components/esp_rom/include/esp32s2/rom/rtc.h +++ b/components/esp_rom/include/esp32s2/rom/rtc.h @@ -89,6 +89,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; // Check if the reset reason defined in ROM is compatible with soc/reset_reasons.h @@ -106,6 +107,7 @@ _Static_assert((soc_reset_reason_t)RTCWDT_RTC_RESET == RESET_REASON_SYS_RTC_WDT, _Static_assert((soc_reset_reason_t)TG1WDT_CPU_RESET == RESET_REASON_CPU0_MWDT1, "TG1WDT_CPU_RESET != RESET_REASON_CPU0_MWDT1"); _Static_assert((soc_reset_reason_t)SUPER_WDT_RESET == RESET_REASON_SYS_SUPER_WDT, "SUPER_WDT_RESET != RESET_REASON_SYS_SUPER_WDT"); _Static_assert((soc_reset_reason_t)GLITCH_RTC_RESET == RESET_REASON_SYS_CLK_GLITCH, "GLITCH_RTC_RESET != RESET_REASON_SYS_CLK_GLITCH"); +_Static_assert((soc_reset_reason_t)EFUSE_RESET == RESET_REASON_CORE_EFUSE_CRC, "EFUSE_RESET != RESET_REASON_CORE_EFUSE_CRC"); typedef enum { NO_SLEEP = 0, diff --git a/components/esp_system/port/soc/esp32c3/clk.c b/components/esp_system/port/soc/esp32c3/clk.c index 7d608c91c6..bd597453e1 100644 --- a/components/esp_system/port/soc/esp32c3/clk.c +++ b/components/esp_system/port/soc/esp32c3/clk.c @@ -68,7 +68,11 @@ static const char *TAG = "clk"; rtc_config_t cfg = RTC_CONFIG_DEFAULT(); soc_reset_reason_t rst_reas; rst_reas = esp_rom_get_reset_reason(0); - if (rst_reas == RESET_REASON_CHIP_POWER_ON) { + if (rst_reas == RESET_REASON_CHIP_POWER_ON +#if SOC_EFUSE_HAS_EFUSE_RST_BUG + || rst_reas == RESET_REASON_CORE_EFUSE_CRC +#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 47171b8ef5..465e804154 100644 --- a/components/esp_system/port/soc/esp32c3/reset_reason.c +++ b/components/esp_system/port/soc/esp32c3/reset_reason.c @@ -1,16 +1,8 @@ -// Copyright 2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "esp_system.h" #include "esp_rom_sys.h" @@ -26,6 +18,9 @@ static esp_reset_reason_t get_reset_reason(soc_reset_reason_t rtc_reset_reason, { switch (rtc_reset_reason) { case RESET_REASON_CHIP_POWER_ON: +#if SOC_EFUSE_HAS_EFUSE_RST_BUG + case RESET_REASON_CORE_EFUSE_CRC: +#endif return ESP_RST_POWERON; case RESET_REASON_CPU0_SW: diff --git a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in index 4ebedf8127..9b0ff5c5e3 100644 --- a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in @@ -55,6 +55,10 @@ config SOC_EFUSE_KEY_PURPOSE_FIELD bool default y +config SOC_EFUSE_HAS_EFUSE_RST_BUG + bool + default y + config SOC_RTC_FAST_MEM_SUPPORTED bool default y diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index e6c9e9ddeb..1a9f6fe0de 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -38,6 +38,7 @@ #define SOC_WIFI_SUPPORTED 1 #define SOC_SUPPORTS_SECURE_DL_MODE 1 #define SOC_EFUSE_KEY_PURPOSE_FIELD 1 +#define SOC_EFUSE_HAS_EFUSE_RST_BUG 1 #define SOC_RTC_FAST_MEM_SUPPORTED 1 #define SOC_I2S_SUPPORTED 1 #define SOC_RMT_SUPPORTED 1 diff --git a/components/soc/esp32s2/include/soc/reset_reasons.h b/components/soc/esp32s2/include/soc/reset_reasons.h index 62c744aac4..2a75b4cba8 100644 --- a/components/soc/esp32s2/include/soc/reset_reasons.h +++ b/components/soc/esp32s2/include/soc/reset_reasons.h @@ -1,16 +1,8 @@ -// Copyright 2021 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -51,6 +43,7 @@ typedef enum { RESET_REASON_CPU0_MWDT1 = 0x11, // Main watch dog 1 resets CPU 0 RESET_REASON_SYS_SUPER_WDT = 0x12, // Super watch dog resets the digital core and rtc module RESET_REASON_SYS_CLK_GLITCH = 0x13, // Glitch on clock resets the digital core and rtc module + RESET_REASON_CORE_EFUSE_CRC = 0x14, // eFuse CRC error resets the digital core } soc_reset_reason_t; #ifdef __cplusplus diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index 4dfd30df98..360acbcd5e 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -681,7 +681,6 @@ components/esp_system/port/soc/esp32/intr.c components/esp_system/port/soc/esp32/reset_reason.c components/esp_system/port/soc/esp32c3/apb_backup_dma.c components/esp_system/port/soc/esp32c3/cache_err_int.h -components/esp_system/port/soc/esp32c3/reset_reason.c components/esp_system/port/soc/esp32h2/apb_backup_dma.c components/esp_system/port/soc/esp32h2/cache_err_int.h components/esp_system/port/soc/esp32h2/reset_reason.c @@ -1357,7 +1356,6 @@ components/soc/esp32s2/include/soc/ledc_reg.h components/soc/esp32s2/include/soc/ledc_struct.h components/soc/esp32s2/include/soc/memprot_defs.h components/soc/esp32s2/include/soc/nrx_reg.h -components/soc/esp32s2/include/soc/reset_reasons.h components/soc/esp32s2/include/soc/rtc_cntl_reg.h components/soc/esp32s2/include/soc/rtc_cntl_struct.h components/soc/esp32s2/include/soc/rtc_i2c_reg.h From 5ec9baff36634f538db8b14007bbe90a9539ac9d Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Wed, 11 Aug 2021 19:06:48 +0500 Subject: [PATCH 2/2] efuse: Checks errors of 4x coding scheme for BLOCK0 if so then abort --- components/efuse/esp32/esp_efuse_utility.c | 5 +++++ components/efuse/esp32c2/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 ++++ 10 files changed, 82 insertions(+) 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);