arch/risc-v: improve E-Fuse support for ESP32-C3|C6|H2

This commit fixes E-Fuse driver to get proper block and bit offset.
Also adds support for virtual and flash E-Fuses.

Signed-off-by: Filipe Cavalcanti <filipe.cavalcanti@espressif.com>
This commit is contained in:
Filipe Cavalcanti 2025-07-14 10:51:45 -03:00 committed by Alan C. Assis
parent ba3a79505e
commit 42254ffcbe
9 changed files with 153 additions and 10 deletions

View file

@ -96,6 +96,14 @@ ifeq ($(CONFIG_ESPRESSIF_BOOTLOADER_MCUBOOT),y)
$(if $(CONFIG_ESPRESSIF_USBSERIAL),$(call cfg_val,CONFIG_ESP_CONSOLE_UART_NUM,0)) \
$(call cfg_val,CONFIG_BOOTLOADER_LOG_LEVEL,3) \
} >> $(BOOTLOADER_CONFIG)
ifeq ($(CONFIG_ESPRESSIF_EFUSE_VIRTUAL_KEEP_IN_FLASH),y)
$(Q) { \
$(call cfg_en,CONFIG_EFUSE_VIRTUAL) \
$(call cfg_en,CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH) \
$(call cfg_val,CONFIG_EFUSE_VIRTUAL_OFFSET,$(CONFIG_ESPRESSIF_EFUSE_VIRTUAL_KEEP_IN_FLASH_OFFSET)) \
$(call cfg_val,CONFIG_EFUSE_VIRTUAL_SIZE,$(CONFIG_ESPRESSIF_EFUSE_VIRTUAL_KEEP_IN_FLASH_SIZE)) \
} >> $(BOOTLOADER_CONFIG)
endif
endif
ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y)

View file

@ -170,7 +170,7 @@ config ESPRESSIF_BOOTLOADER_MCUBOOT
config ESPRESSIF_MCUBOOT_VERSION
string "MCUboot version"
depends on ESPRESSIF_BOOTLOADER_MCUBOOT
default "20f98e0a975c24864872e0df5701eb1082e9c957"
default "aa4fa2b6e17361dd3ce16a60883059778fd147a9"
choice ESPRESSIF_ESPTOOL_TARGET_SLOT
prompt "Target slot for image flashing"
@ -217,7 +217,7 @@ comment "Application Image OTA Update support"
config ESPRESSIF_OTA_PRIMARY_SLOT_OFFSET
hex "Application image primary slot offset"
default 0x10000
default 0x20000
config ESPRESSIF_OTA_PRIMARY_SLOT_DEVPATH
string "Application image primary slot device path"
@ -225,7 +225,7 @@ config ESPRESSIF_OTA_PRIMARY_SLOT_DEVPATH
config ESPRESSIF_OTA_SECONDARY_SLOT_OFFSET
hex "Application image secondary slot offset"
default 0x110000
default 0x120000
config ESPRESSIF_OTA_SECONDARY_SLOT_DEVPATH
string "Application image secondary slot device path"
@ -237,7 +237,7 @@ config ESPRESSIF_OTA_SLOT_SIZE
config ESPRESSIF_OTA_SCRATCH_OFFSET
hex "Scratch partition offset"
default 0x210000
default 0x220000
config ESPRESSIF_OTA_SCRATCH_SIZE
hex "Scratch partition size"
@ -499,17 +499,49 @@ config ESPRESSIF_DMA
select ARCH_DMA
config ESPRESSIF_EFUSE
bool "EFUSE support"
bool "E-Fuse support"
default n
---help---
Enable efuse support.
config ESPRESSIF_EFUSE_VIRTUAL
bool "Virtual EFUSE support"
bool "Virtual E-Fuses support"
depends on ESPRESSIF_EFUSE
default n
---help---
Enable virtual efuse support to simulate eFuse operations in RAM, changes will be reverted each reboot
Enable virtual E-Fuse support to simulate E-Fuse operations in RAM.
Changes will be reverted each reboot unless enabling ESPRESSIF_EFUSE_VIRTUAL_KEEP_IN_FLASH.
config ESPRESSIF_EFUSE_VIRTUAL_KEEP_IN_FLASH
bool "Keep E-Fuses in flash"
depends on ESPRESSIF_EFUSE_VIRTUAL
---help---
In addition to the "Virtual E-Fuses support" option, this option just adds
a feature to keep E-Fuses after reboots in flash memory.
During startup, the E-Fuses are copied from flash or,
in case if flash is empty, from real E-Fuse to RAM and then update flash.
This mode is useful when need to keep changes after reboots (testing secure_boot,
flash_encryption or using MCUBoot + encryption).
if ESPRESSIF_EFUSE_VIRTUAL_KEEP_IN_FLASH
config ESPRESSIF_EFUSE_VIRTUAL_KEEP_IN_FLASH_OFFSET
hex "E-Fuses offset in flash"
depends on ESPRESSIF_EFUSE_VIRTUAL_KEEP_IN_FLASH
default 0x10000 if ESPRESSIF_BOOTLOADER_MCUBOOT
default 0x250000 if !ESPRESSIF_BOOTLOADER_MCUBOOT
---help---
Offset in flash where the E-Fuses will be stored when using the "E-Fuses size to keep in flash" option.
config ESPRESSIF_EFUSE_VIRTUAL_KEEP_IN_FLASH_SIZE
hex "E-Fuses size to keep in flash"
depends on ESPRESSIF_EFUSE_VIRTUAL_KEEP_IN_FLASH
default 0x2000
---help---
Size of E-Fuse region to keep in flash.
endif # ESPRESSIF_EFUSE_VIRTUAL_KEEP_IN_FLASH
config ESPRESSIF_HR_TIMER
bool
@ -1861,7 +1893,7 @@ config ESPRESSIF_SPI_FLASH_USE_32BIT_ADDRESS
config ESPRESSIF_STORAGE_MTD_OFFSET
hex "Storage MTD base address in SPI Flash"
default 0x180000 if !ESPRESSIF_BOOTLOADER_MCUBOOT
default 0x250000 if ESPRESSIF_BOOTLOADER_MCUBOOT
default 0x260000 if ESPRESSIF_BOOTLOADER_MCUBOOT
depends on ESPRESSIF_MTD
---help---
MTD base address in SPI Flash.

View file

@ -179,6 +179,10 @@ ifeq ($(CONFIG_CRYPTO_CRYPTODEV_HARDWARE),y)
CHIP_CSRCS += esp_crypto.c
endif
ifeq ($(CONFIG_ESPRESSIF_EFUSE),y)
LDFLAGS += -u esp_efuse_startup_include_func
endif
#############################################################################
# Espressif HAL for 3rd Party Platforms
#############################################################################
@ -249,6 +253,7 @@ context:: chip/$(ESP_HAL_3RDPARTY_REPO)
distclean::
$(call DELFILE,../include/chip/gpio_sig_map.h)
$(call DELFILE,../include/chip/irq.h)
$(call DELFILE,../../../vefuse.bin)
$(call DELDIR,chip/$(ESP_HAL_3RDPARTY_REPO))
INCLUDES += ${INCDIR_PREFIX}$(ARCH_SRCDIR)$(DELIM)common$(DELIM)espressif

View file

@ -103,6 +103,13 @@ static struct esp_efuse_lowerhalf_s g_esp_efuse_lowerhalf =
* Description:
* Read value from EFUSE, writing it into an array.
*
* The field[0]->bit_offset received from the upper half represents
* the bit offset taking into consideration that each block is 256 bits.
* This is necessary as we have multiple blocks of 256 bits.
*
* Example: To read data from USER_DATA (EFUSE_BLK3), from bit 16 onwards,
* then bit_offset should be 3*256 + 16.
* Input Parameters:
* lower - A pointer the publicly visible representation of
* the "lower-half" driver state structure
@ -120,10 +127,27 @@ static int esp_efuse_lowerhalf_read(struct efuse_lowerhalf_s *lower,
uint8_t *data, size_t bits_len)
{
int ret = OK;
uint8_t blk_num = field[0]->bit_offset / ESP_EFUSE_BLK_LEN;
esp_efuse_desc_t recv =
{
.efuse_block = blk_num,
.bit_start = field[0]->bit_offset - blk_num * ESP_EFUSE_BLK_LEN,
.bit_count = field[0]->bit_count
};
const esp_efuse_desc_t *desc[] =
{
&recv,
NULL
};
minfo("read from blk_num: %d, bit_start: %d, bit_count: %d\n",
blk_num, recv.bit_start, recv.bit_count);
/* Read the requested field */
ret = esp_efuse_read_field_blob((const esp_efuse_desc_t**)field,
ret = esp_efuse_read_field_blob((const esp_efuse_desc_t**)&desc,
data,
bits_len);
@ -136,6 +160,13 @@ static int esp_efuse_lowerhalf_read(struct efuse_lowerhalf_s *lower,
* Description:
* Write array to EFUSE.
*
* The field[0]->bit_offset received from the upper half represents
* the bit offset taking into consideration that each block is 256 bits.
* This is necessary as we have multiple blocks of 256 bits.
*
* Example: To write data to USER_DATA (EFUSE_BLK3), from bit 16 onwards,
* then bit_offset should be 3*256 + 16.
*
* Input Parameters:
* lower - A pointer the publicly visible representation of
* the "lower-half" driver state structure
@ -155,10 +186,26 @@ static int esp_efuse_lowerhalf_write(struct efuse_lowerhalf_s *lower,
{
irqstate_t flags;
int ret = OK;
uint8_t blk_num = field[0]->bit_offset / ESP_EFUSE_BLK_LEN;
esp_efuse_desc_t recv =
{
.efuse_block = blk_num,
.bit_start = field[0]->bit_offset - blk_num * ESP_EFUSE_BLK_LEN,
.bit_count = field[0]->bit_count
};
const esp_efuse_desc_t *desc[] =
{
&recv,
NULL
};
minfo("write to blk_num: %d, bit_start: %d, bit_count: %d\n",
blk_num, recv.bit_start, recv.bit_count);
flags = enter_critical_section();
ret = esp_efuse_write_field_blob((const esp_efuse_desc_t**)field,
ret = esp_efuse_write_field_blob((const esp_efuse_desc_t**)&desc,
data,
bits_len);
@ -256,6 +303,7 @@ int esp_efuse_initialize(const char *devpath)
}
#ifdef CONFIG_ESPRESSIF_EFUSE_VIRTUAL
mwarn("Virtual E-Fuses are enabled\n");
esp_efuse_utility_update_virt_blocks();
#endif

View file

@ -40,6 +40,12 @@ extern "C"
#define EXTERN extern
#endif
/****************************************************************************
* Pre-processor definitions
****************************************************************************/
#define ESP_EFUSE_BLK_LEN 256
/****************************************************************************
* Public Functions Prototypes
****************************************************************************/

View file

@ -107,6 +107,7 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)boot
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)src$(DELIM)esp_efuse_api.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)src$(DELIM)esp_efuse_utility.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)src$(DELIM)esp_efuse_fields.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)src$(DELIM)esp_efuse_startup.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)esp_efuse_fields.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)esp_efuse_rtc_calib.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)esp_efuse_table.c
@ -220,4 +221,10 @@ ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y)
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_rom$(DELIM)patches$(DELIM)esp_rom_spiflash.c
LDFLAGS += --wrap=bootloader_print_banner
else
ifeq ($(CONFIG_ESPRESSIF_EFUSE_VIRTUAL_KEEP_IN_FLASH),y)
# Special case for bootloader_flash when using efuse virtual mode
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)bootloader_flash$(DELIM)src$(DELIM)bootloader_flash.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)bootloader_flash$(DELIM)src$(DELIM)bootloader_flash_config_${CHIP_SERIES}.c
endif
endif

View file

@ -112,6 +112,7 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)boot
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)bootloader_efuse.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)src$(DELIM)esp_efuse_api.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)src$(DELIM)esp_efuse_utility.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)src$(DELIM)esp_efuse_startup.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)esp_efuse_fields.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)esp_efuse_rtc_calib.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)esp_efuse_table.c
@ -242,4 +243,10 @@ ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y)
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)src$(DELIM)esp_efuse_fields.c
LDFLAGS += --wrap=bootloader_print_banner
else
ifeq ($(CONFIG_ESPRESSIF_EFUSE_VIRTUAL_KEEP_IN_FLASH),y)
# Special case for bootloader_flash when using efuse virtual mode
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)bootloader_flash$(DELIM)src$(DELIM)bootloader_flash.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)bootloader_flash$(DELIM)src$(DELIM)bootloader_flash_config_${CHIP_SERIES}.c
endif
endif

View file

@ -104,10 +104,12 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)boot
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)bootloader_efuse.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)src$(DELIM)esp_efuse_api.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)src$(DELIM)esp_efuse_utility.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)src$(DELIM)esp_efuse_startup.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)esp_efuse_fields.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)esp_efuse_rtc_calib.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)esp_efuse_table.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)esp_efuse_utility.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)esp_efuse_table_v0.0_v1.1.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)src$(DELIM)efuse_controller$(DELIM)keys$(DELIM)with_key_purposes$(DELIM)esp_efuse_api_key.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_common$(DELIM)src$(DELIM)esp_err_to_name.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)adc_share_hw_ctrl.c
@ -222,4 +224,10 @@ ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y)
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)src$(DELIM)esp_efuse_fields.c
LDFLAGS += --wrap=bootloader_print_banner
else
ifeq ($(CONFIG_ESPRESSIF_EFUSE_VIRTUAL_KEEP_IN_FLASH),y)
# Special case for bootloader_flash when using efuse virtual mode
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)bootloader_flash$(DELIM)src$(DELIM)bootloader_flash.c
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)bootloader_flash$(DELIM)src$(DELIM)bootloader_flash_config_${CHIP_SERIES}.c
endif
endif

View file

@ -24,6 +24,18 @@
CHIP_SERIES = $(patsubst "%",%,$(CONFIG_ESPRESSIF_CHIP_SERIES))
# MCUBoot requires a region in flash for the E-Fuse virtual mode.
# To avoid erasing this region, flash a dummy empty file to the
# virtual E-Fuse offset.
VIRTUAL_EFUSE_BIN := vefuse.bin
ifeq ($(CONFIG_ESPRESSIF_EFUSE_VIRTUAL_KEEP_IN_FLASH),y)
EFUSE_FLASH_OFFSET := $(CONFIG_ESPRESSIF_EFUSE_VIRTUAL_KEEP_IN_FLASH_OFFSET)
else
EFUSE_FLASH_OFFSET := 0x10000
endif
# These are the macros that will be used in the NuttX make system to compile
# and assemble source files and to insert the resulting object files into an
# archive. These replace the default definitions at tools/Config.mk
@ -69,7 +81,16 @@ ifdef ESPTOOL_BINDIR
endif
endif
define MAKE_VIRTUAL_EFUSE_BIN
$(Q)if [ ! -f "$(VIRTUAL_EFUSE_BIN)" ]; then \
dd if=/dev/zero of=$(VIRTUAL_EFUSE_BIN) count=0 status=none; \
fi
endef
ifeq ($(CONFIG_ESPRESSIF_BOOTLOADER_MCUBOOT),y)
ESPTOOL_BINS += $(EFUSE_FLASH_OFFSET) $(VIRTUAL_EFUSE_BIN)
ifeq ($(CONFIG_ESPRESSIF_ESPTOOL_TARGET_PRIMARY),y)
VERIFIED := --confirm
APP_OFFSET := $(CONFIG_ESPRESSIF_OTA_PRIMARY_SLOT_OFFSET)
@ -146,6 +167,7 @@ endif
define POSTBUILD
$(call MKIMAGE)
$(if $(CONFIG_ESPRESSIF_BOOTLOADER_MCUBOOT),$(call MAKE_VIRTUAL_EFUSE_BIN))
$(if $(CONFIG_ESPRESSIF_MERGE_BINS),$(call MERGEBIN))
endef