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.
This commit is contained in:
Tiago Medicci Serrano 2023-12-22 10:23:27 -03:00 committed by Xiang Xiao
parent 2954551ef6
commit 0ecc3aaad2
4 changed files with 159 additions and 2 deletions

View File

@ -111,8 +111,8 @@ CHIP_CSRCS += esp32_himem.c
CHIP_CSRCS += esp32_himem_chardev.c CHIP_CSRCS += esp32_himem_chardev.c
endif endif
ifeq ($(CONFIG_ESP32_EFUSE),y)
CHIP_CSRCS += esp32_efuse.c CHIP_CSRCS += esp32_efuse.c
ifeq ($(CONFIG_ESP32_EFUSE),y)
CHIP_CSRCS += esp32_efuse_table.c CHIP_CSRCS += esp32_efuse_table.c
CHIP_CSRCS += esp32_efuse_lowerhalf.c CHIP_CSRCS += esp32_efuse_lowerhalf.c
endif endif

View File

@ -68,6 +68,7 @@ uint32_t g_start_efuse_wrreg[4] =
* Private Prototypes * Private Prototypes
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_ESP32_EFUSE
static int esp_efuse_set_timing(void); static int esp_efuse_set_timing(void);
void esp_efuse_burn_efuses(void); void esp_efuse_burn_efuses(void);
static uint32_t get_mask(uint32_t bit_count, uint32_t shift); 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); int *bits_counter);
static void esp_efuse_write_reg(uint32_t blk, uint32_t num_reg, static void esp_efuse_write_reg(uint32_t blk, uint32_t num_reg,
uint32_t value); 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 * Private Functions
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_ESP32_EFUSE
static int esp_efuse_set_timing(void) static int esp_efuse_set_timing(void)
{ {
uint32_t apb_freq_mhz = esp_clk_apb_freq() / 1000000; 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); 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 * 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 */ /* Read value from EFUSE, writing it into an array */
int esp_efuse_read_field(const efuse_desc_t *field[], void *dst, 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 */

View File

@ -18,6 +18,16 @@
* *
****************************************************************************/ ****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/efuse/efuse.h>
/****************************************************************************
* Public Types
****************************************************************************/
/* Type of eFuse blocks for ESP32 */ /* Type of eFuse blocks for ESP32 */
typedef enum typedef enum
@ -52,6 +62,24 @@ typedef int (*efuse_func_proc_t) (unsigned int num_reg,
* Public Functions Prototypes * 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, int esp_efuse_read_field(const efuse_desc_t *field[], void *dst,
size_t dst_size_bits); 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); void esp_efuse_burn_efuses(void);
int esp32_efuse_initialize(const char *devpath); int esp32_efuse_initialize(const char *devpath);
#endif /* CONFIG_ESP32_EFUSE */

View File

@ -24,6 +24,7 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <debug.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
@ -35,6 +36,7 @@
#include "xtensa_attr.h" #include "xtensa_attr.h"
#include "esp32_clockconfig.h" #include "esp32_clockconfig.h"
#include "esp32_efuse.h"
#include "esp32_region.h" #include "esp32_region.h"
#include "esp32_start.h" #include "esp32_start.h"
#include "esp32_spiram.h" #include "esp32_spiram.h"
@ -91,8 +93,9 @@ extern uint8_t _image_drom_size[];
* ROM Function Prototypes * ROM Function Prototypes
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_ESP32_APP_FORMAT_MCUBOOT
extern int ets_printf(const char *fmt, ...) printf_like(1, 2); 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_enable(int cpu);
extern void cache_read_disable(int cpu); extern void cache_read_disable(int cpu);
extern void cache_flush(int cpu); extern void cache_flush(int cpu);
@ -143,6 +146,7 @@ static noreturn_function void __esp32_start(void)
{ {
uint32_t sp; uint32_t sp;
uint32_t regval unused_data; uint32_t regval unused_data;
uint32_t chip_rev;
/* Make sure that normal interrupts are disabled. This is really only an /* 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 * 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'); 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 defined(CONFIG_ESP32_SPIRAM_BOOT_INIT)
if (esp_spiram_init() != OK) if (esp_spiram_init() != OK)
{ {