This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 0ecc3aaad27ee3bb9ea862dee2a832f985a81385
Author: Tiago Medicci Serrano <tiago.medi...@espressif.com>
AuthorDate: Fri Dec 22 10:23:27 2023 -0300

    esp32: Explicitly fail on boot-up for unsupported ESP32 versions.
    
    ESP32 is supported on NuttX starting from chip revision 3.0. This,
    however, didn't prevent the user from using older chip revisions,
    which caused unexpected behaviors. This commit checks chip revision
    before finishing booting NuttX.
---
 arch/xtensa/src/esp32/Make.defs     |   2 +-
 arch/xtensa/src/esp32/esp32_efuse.c | 103 ++++++++++++++++++++++++++++++++++++
 arch/xtensa/src/esp32/esp32_efuse.h |  30 +++++++++++
 arch/xtensa/src/esp32/esp32_start.c |  26 ++++++++-
 4 files changed, 159 insertions(+), 2 deletions(-)

diff --git a/arch/xtensa/src/esp32/Make.defs b/arch/xtensa/src/esp32/Make.defs
index b71e77879e..2b4f908cfd 100644
--- a/arch/xtensa/src/esp32/Make.defs
+++ b/arch/xtensa/src/esp32/Make.defs
@@ -111,8 +111,8 @@ CHIP_CSRCS += esp32_himem.c
 CHIP_CSRCS += esp32_himem_chardev.c
 endif
 
-ifeq ($(CONFIG_ESP32_EFUSE),y)
 CHIP_CSRCS += esp32_efuse.c
+ifeq ($(CONFIG_ESP32_EFUSE),y)
 CHIP_CSRCS += esp32_efuse_table.c
 CHIP_CSRCS += esp32_efuse_lowerhalf.c
 endif
diff --git a/arch/xtensa/src/esp32/esp32_efuse.c 
b/arch/xtensa/src/esp32/esp32_efuse.c
index 12f2ddd514..df7518520c 100644
--- a/arch/xtensa/src/esp32/esp32_efuse.c
+++ b/arch/xtensa/src/esp32/esp32_efuse.c
@@ -68,6 +68,7 @@ uint32_t g_start_efuse_wrreg[4] =
  * Private Prototypes
  ****************************************************************************/
 
+#ifdef CONFIG_ESP32_EFUSE
 static int esp_efuse_set_timing(void);
 void esp_efuse_burn_efuses(void);
 static uint32_t get_mask(uint32_t bit_count, uint32_t shift);
@@ -90,11 +91,17 @@ static int esp_efuse_fill_buff(uint32_t num_reg, int 
bit_offset,
                                int *bits_counter);
 static void esp_efuse_write_reg(uint32_t blk, uint32_t num_reg,
                                 uint32_t value);
+#endif /* CONFIG_ESP32_EFUSE */
+
+static uint32_t efuse_hal_get_major_chip_version(void);
+static uint32_t efuse_hal_get_minor_chip_version(void);
 
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
 
+#ifdef CONFIG_ESP32_EFUSE
+
 static int esp_efuse_set_timing(void)
 {
   uint32_t apb_freq_mhz = esp_clk_apb_freq() / 1000000;
@@ -429,10 +436,105 @@ static void esp_efuse_write_reg(uint32_t blk, uint32_t 
num_reg,
   putreg32(reg_to_write, addr_wr_reg);
 }
 
+#endif /* CONFIG_ESP32_EFUSE */
+
+/****************************************************************************
+ * Name: efuse_hal_get_major_chip_version
+ *
+ * Description:
+ *   Retrieves the major version of the chip. It reads the version
+ *   information from specific registers and combines them to determine
+ *   the major version.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   The major version of the chip as an unsigned 32-bit integer.
+ *
+ ****************************************************************************/
+
+IRAM_ATTR static uint32_t efuse_hal_get_major_chip_version(void)
+{
+  uint8_t eco_bit0;
+  uint8_t eco_bit1;
+  uint8_t eco_bit2;
+  uint32_t combine_value;
+  uint32_t chip_ver = 0;
+
+  eco_bit0 = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_REV1);
+  eco_bit1 = REG_GET_FIELD(EFUSE_BLK0_RDATA5_REG, EFUSE_RD_CHIP_VER_REV2);
+  eco_bit2 = (getreg32(APB_CTRL_DATE_REG) & 0x80000000) >> 31;
+  combine_value = (eco_bit2 << 2) | (eco_bit1 << 1) | eco_bit0;
+
+  switch (combine_value)
+    {
+      case 0:
+          chip_ver = 0;
+          break;
+      case 1:
+          chip_ver = 1;
+          break;
+      case 3:
+          chip_ver = 2;
+          break;
+      case 7:
+          chip_ver = 3;
+          break;
+      default:
+          chip_ver = 0;
+          break;
+    }
+
+  return chip_ver;
+}
+
+/****************************************************************************
+ * Name: efuse_hal_get_minor_chip_version
+ *
+ * Description:
+ *   Retrieves the minor version of the chip. It reads the version
+ *   information from a specific register.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   The minor version of the chip as an unsigned 32-bit integer.
+ *
+ ****************************************************************************/
+
+IRAM_ATTR static uint32_t efuse_hal_get_minor_chip_version(void)
+{
+  return REG_GET_FIELD(EFUSE_BLK0_RDATA5_REG, EFUSE_RD_WAFER_VERSION_MINOR);
+}
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
 
+/****************************************************************************
+ * Name: esp_efuse_hal_chip_revision
+ *
+ * Description:
+ *   Returns the chip version in the format: Major * 100 + Minor.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   The chip version as an unsigned 32-bit integer.
+ *
+ ****************************************************************************/
+
+IRAM_ATTR uint32_t esp_efuse_hal_chip_revision(void)
+{
+  return (efuse_hal_get_major_chip_version() * 100) +
+         efuse_hal_get_minor_chip_version();
+}
+
+#ifdef CONFIG_ESP32_EFUSE
+
 /* Read value from EFUSE, writing it into an array */
 
 int esp_efuse_read_field(const efuse_desc_t *field[], void *dst,
@@ -499,3 +601,4 @@ void esp_efuse_burn_efuses(void)
     };
 }
 
+#endif /* CONFIG_ESP32_EFUSE */
diff --git a/arch/xtensa/src/esp32/esp32_efuse.h 
b/arch/xtensa/src/esp32/esp32_efuse.h
index 51497ba318..904693d3fc 100644
--- a/arch/xtensa/src/esp32/esp32_efuse.h
+++ b/arch/xtensa/src/esp32/esp32_efuse.h
@@ -18,6 +18,16 @@
  *
  ****************************************************************************/
 
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/efuse/efuse.h>
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
 /* Type of eFuse blocks for ESP32 */
 
 typedef enum
@@ -52,6 +62,24 @@ typedef int (*efuse_func_proc_t) (unsigned int num_reg,
  * Public Functions Prototypes
  ****************************************************************************/
 
+/****************************************************************************
+ * Name: esp_efuse_hal_chip_revision
+ *
+ * Description:
+ *   Returns the chip version in the format: Major * 100 + Minor.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   The chip version as an unsigned 32-bit integer.
+ *
+ ****************************************************************************/
+
+uint32_t esp_efuse_hal_chip_revision(void);
+
+#ifdef CONFIG_ESP32_EFUSE
+
 int esp_efuse_read_field(const efuse_desc_t *field[], void *dst,
                          size_t dst_size_bits);
 
@@ -61,3 +89,5 @@ int esp_efuse_write_field(const efuse_desc_t *field[],
 void esp_efuse_burn_efuses(void);
 
 int esp32_efuse_initialize(const char *devpath);
+
+#endif /* CONFIG_ESP32_EFUSE */
diff --git a/arch/xtensa/src/esp32/esp32_start.c 
b/arch/xtensa/src/esp32/esp32_start.c
index 0422dd7a3e..30679d7840 100644
--- a/arch/xtensa/src/esp32/esp32_start.c
+++ b/arch/xtensa/src/esp32/esp32_start.c
@@ -24,6 +24,7 @@
 
 #include <nuttx/config.h>
 
+#include <debug.h>
 #include <stdint.h>
 #include <string.h>
 #include <assert.h>
@@ -35,6 +36,7 @@
 #include "xtensa_attr.h"
 
 #include "esp32_clockconfig.h"
+#include "esp32_efuse.h"
 #include "esp32_region.h"
 #include "esp32_start.h"
 #include "esp32_spiram.h"
@@ -91,8 +93,9 @@ extern uint8_t _image_drom_size[];
  * ROM Function Prototypes
  ****************************************************************************/
 
-#ifdef CONFIG_ESP32_APP_FORMAT_MCUBOOT
 extern int ets_printf(const char *fmt, ...) printf_like(1, 2);
+
+#ifdef CONFIG_ESP32_APP_FORMAT_MCUBOOT
 extern void cache_read_enable(int cpu);
 extern void cache_read_disable(int cpu);
 extern void cache_flush(int cpu);
@@ -143,6 +146,7 @@ static noreturn_function void __esp32_start(void)
 {
   uint32_t sp;
   uint32_t regval unused_data;
+  uint32_t chip_rev;
 
   /* Make sure that normal interrupts are disabled.  This is really only an
    * issue when we are started in un-usual ways (such as from IRAM).  In this
@@ -222,6 +226,26 @@ static noreturn_function void __esp32_start(void)
 
   showprogress('A');
 
+  chip_rev = esp_efuse_hal_chip_revision();
+
+  _info("ESP32 chip revision is v%d.%01d\n", chip_rev / 100, chip_rev % 100);
+
+  if (chip_rev < 300)
+    {
+#ifndef ESP32_IGNORE_CHIP_REVISION_CHECK
+      ets_printf("ERROR: NuttX supports ESP32 chip revision >= v3.0"
+                 " (chip revision is v%d.%01d)\n",
+                 chip_rev / 100, chip_rev % 100);
+      PANIC();
+#endif
+      ets_printf("WARNING: NuttX supports ESP32 chip revision >= v3.0"
+                 " (chip is v%d.%01d).\n"
+                 "Ignoring this error and continuing because "
+                 "`ESP32_IGNORE_CHIP_REVISION_CHECK` is set...\n"
+                 "THIS MAY NOT WORK! DON'T USE THIS CHIP IN PRODUCTION!\n",
+                 chip_rev / 100, chip_rev % 100);
+    }
+
 #if defined(CONFIG_ESP32_SPIRAM_BOOT_INIT)
   if (esp_spiram_init() != OK)
     {

Reply via email to