Browse Source

efuse: Checks errors of 4x coding scheme for BLOCK0 if so then abort

KonstantinKondrashov 4 years ago
parent
commit
5ec9baff36

+ 5 - 0
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)
 {

+ 5 - 0
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)
 {

+ 20 - 0
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)
 {

+ 5 - 0
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)
 {

+ 5 - 0
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)
 {

+ 5 - 0
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)
 {

+ 14 - 0
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

+ 14 - 0
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.
  */

+ 5 - 0
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();
+}

+ 4 - 0
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);