Merge branch 'feature/efuse_rst_is_treated_as_poweron_rst_v4.4' into 'release/v4.4'

reset_reasons: EFUSE_RST is treated as POWERON_RST + checks errors of eFuse BLOCK0 (v4.4)

See merge request espressif/esp-idf!17871
This commit is contained in:
Jiang Jiang Jian
2022-07-01 10:43:40 +08:00
15 changed files with 104 additions and 28 deletions

View File

@ -250,7 +250,11 @@ esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metad
#if CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS #if CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS
mode = ESP_IMAGE_LOAD_NO_VALIDATE; mode = ESP_IMAGE_LOAD_NO_VALIDATE;
#elif CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON #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; mode = ESP_IMAGE_LOAD_NO_VALIDATE;
} }
#endif // CONFIG_BOOTLOADER_SKIP_... #endif // CONFIG_BOOTLOADER_SKIP_...

View File

@ -118,6 +118,11 @@ void esp_efuse_utility_clear_program_registers(void)
efuse_hal_clear_program_registers(); 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 // Burn values written to the efuse write registers
esp_err_t esp_efuse_utility_burn_chip(void) esp_err_t esp_efuse_utility_burn_chip(void)
{ {

View File

@ -120,6 +120,26 @@ void esp_efuse_utility_clear_program_registers(void)
ets_efuse_clear_program_registers(); 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 // Burn values written to the efuse write registers
esp_err_t esp_efuse_utility_burn_chip(void) esp_err_t esp_efuse_utility_burn_chip(void)
{ {

View File

@ -95,6 +95,11 @@ void esp_efuse_utility_clear_program_registers(void)
ets_efuse_clear_program_registers(); 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 // Burn values written to the efuse write registers
esp_err_t esp_efuse_utility_burn_chip(void) esp_err_t esp_efuse_utility_burn_chip(void)
{ {

View File

@ -88,6 +88,11 @@ void esp_efuse_utility_clear_program_registers(void)
ets_efuse_clear_program_registers(); 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 // Burn values written to the efuse write registers
esp_err_t esp_efuse_utility_burn_chip(void) esp_err_t esp_efuse_utility_burn_chip(void)
{ {

View File

@ -113,6 +113,11 @@ void esp_efuse_utility_clear_program_registers(void)
ets_efuse_clear_program_registers(); 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 // Burn values written to the efuse write registers
esp_err_t esp_efuse_utility_burn_chip(void) esp_err_t esp_efuse_utility_burn_chip(void)
{ {

View File

@ -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); esp_err_t esp_secure_boot_read_key_digests(ets_secure_boot_key_digests_t *trusted_keys);
#endif #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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -160,6 +160,20 @@ void esp_efuse_utility_erase_virt_blocks(void);
*/ */
esp_err_t esp_efuse_utility_apply_new_coding_scheme(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. * @brief Efuse read operation: copies data from physical efuses to efuse read registers.
*/ */

View File

@ -287,3 +287,8 @@ esp_err_t esp_efuse_batch_write_commit(void)
} }
return ESP_OK; return ESP_OK;
} }
esp_err_t esp_efuse_check_errors(void)
{
return esp_efuse_utility_check_errors();
}

View File

@ -97,6 +97,7 @@ typedef enum {
TG1WDT_CPU_RESET = 17, /**<17, Time Group1 reset CPU*/ TG1WDT_CPU_RESET = 17, /**<17, Time Group1 reset CPU*/
SUPER_WDT_RESET = 18, /**<18, super watchdog reset digital core and rtc module*/ 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*/ GLITCH_RTC_RESET = 19, /**<19, glitch reset digital core and rtc module*/
EFUSE_RESET = 20, /**<20, efuse reset digital core*/
} RESET_REASON; } RESET_REASON;
// Check if the reset reason defined in ROM is compatible with soc/reset_reasons.h // Check if the reset reason defined in ROM is compatible with soc/reset_reasons.h
@ -113,6 +114,7 @@ _Static_assert((soc_reset_reason_t)RTCWDT_BROWN_OUT_RESET == RESET_REASON_SYS_BR
_Static_assert((soc_reset_reason_t)RTCWDT_RTC_RESET == RESET_REASON_SYS_RTC_WDT, "RTCWDT_RTC_RESET != RESET_REASON_SYS_RTC_WDT"); _Static_assert((soc_reset_reason_t)RTCWDT_RTC_RESET == RESET_REASON_SYS_RTC_WDT, "RTCWDT_RTC_RESET != RESET_REASON_SYS_RTC_WDT");
_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)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)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 { typedef enum {
NO_SLEEP = 0, NO_SLEEP = 0,

View File

@ -353,6 +353,10 @@ void IRAM_ATTR call_start_cpu0(void)
Cache_Resume_DCache(0); Cache_Resume_DCache(0);
#endif // CONFIG_IDF_TARGET_ESP32S3 #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 #if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
/* Configure the Cache MMU size for instruction and rodata in flash. */ /* 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); extern uint32_t Cache_Set_IDROM_MMU_Size(uint32_t irom_size, uint32_t drom_size);

View File

@ -69,7 +69,11 @@ static const char *TAG = "clk";
rtc_config_t cfg = RTC_CONFIG_DEFAULT(); rtc_config_t cfg = RTC_CONFIG_DEFAULT();
soc_reset_reason_t rst_reas; soc_reset_reason_t rst_reas;
rst_reas = esp_rom_get_reset_reason(0); 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; cfg.cali_ocode = 1;
} }
rtc_init(cfg); rtc_init(cfg);

View File

@ -1,16 +1,8 @@
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// 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.
#include "esp_system.h" #include "esp_system.h"
#include "esp_rom_sys.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) { switch (rtc_reset_reason) {
case RESET_REASON_CHIP_POWER_ON: case RESET_REASON_CHIP_POWER_ON:
#if SOC_EFUSE_HAS_EFUSE_RST_BUG
case RESET_REASON_CORE_EFUSE_CRC:
#endif
return ESP_RST_POWERON; return ESP_RST_POWERON;
case RESET_REASON_CPU0_SW: case RESET_REASON_CPU0_SW:

View File

@ -30,6 +30,7 @@
#define SOC_SUPPORTS_SECURE_DL_MODE 1 #define SOC_SUPPORTS_SECURE_DL_MODE 1
#define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS 3 #define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS 3
#define SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS 1 #define SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS 1
#define SOC_EFUSE_HAS_EFUSE_RST_BUG 1
/*-------------------------- AES CAPS -----------------------------------------*/ /*-------------------------- AES CAPS -----------------------------------------*/

View File

@ -1,16 +1,8 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// 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.
#pragma once #pragma once
@ -51,6 +43,7 @@ typedef enum {
RESET_REASON_CPU0_MWDT1 = 0x11, // Main watch dog 1 resets CPU 0 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_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_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; } soc_reset_reason_t;
#ifdef __cplusplus #ifdef __cplusplus