Merge branch 'feature/recovery_bootloader_support' into 'master'

feat(bootloader): Support recovery bootloader for ESP32P4

Closes IDF-15653 and IDF-13165

See merge request espressif/esp-idf!48215
This commit is contained in:
Konstantin Kondrashov
2026-05-12 23:24:40 +03:00
27 changed files with 161 additions and 78 deletions

View File

@@ -9,16 +9,12 @@ components/app_update/test_apps:
- if: CONFIG_NAME == "xip_psram_with_rom_impl" and (SOC_SPIRAM_XIP_SUPPORTED == 1 and IDF_TARGET != "esp32s2")
- if: CONFIG_NAME == "recovery_bootloader" and SOC_RECOVERY_BOOTLOADER_SUPPORTED == 1
disable:
- if: IDF_TARGET in ["esp32h21", "esp32h4", "esp32s31"]
- if: IDF_TARGET in ["esp32h21", "esp32h4"]
temporary: true
reason: not supported yet # TODO: [ESP32H21] IDF-11515, [ESP32H4] IDF-12279 [ESP32S31] IDF-14643
- if: IDF_TARGET == "esp32c61" and CONFIG_NAME == "xip_psram_with_rom_impl"
temporary: true
reason: not supported yet # TODO: [ESP32C61] IDF-12784
disable_test:
- if: CONFIG_NAME == "recovery_bootloader" and SOC_RECOVERY_BOOTLOADER_SUPPORTED == 1 and IDF_TARGET == "esp32c61"
temporary: true
reason: lack of runners # TODO: [ESP32C61] IDF-13165
depends_components:
- app_update
- bootloader_support

View File

@@ -1,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- |

View File

@@ -71,7 +71,7 @@ def test_app_update_with_rollback(dut: Dut) -> None:
['recovery_bootloader'],
indirect=True,
)
@idf_parametrize('target', ['esp32c5'], indirect=['target'])
@idf_parametrize('target', ['esp32c5', 'esp32c61', 'esp32p4', 'esp32s31'], indirect=['target'])
def test_recovery_bootloader_update(dut: Dut) -> None:
try:
dut.run_all_single_board_cases(group='recovery_bootloader', timeout=90)

View File

@@ -0,0 +1,3 @@
# ESP32P4 supports the Recovery bootloader feature in ROM from rev3.0
CONFIG_IDF_TARGET="esp32p4"
CONFIG_ESP32P4_REV_MIN_300=y

View File

@@ -0,0 +1,2 @@
# ESP32S31 supports the Recovery bootloader feature in ROM
CONFIG_IDF_TARGET="esp32s31"

View File

@@ -0,0 +1,3 @@
CONFIG_IDF_TARGET="esp32c61"
CONFIG_BOOTLOADER_NUM_PIN_APP_TEST=18
CONFIG_BOOTLOADER_NUM_PIN_FACTORY_RESET=19

View File

@@ -0,0 +1,3 @@
CONFIG_IDF_TARGET="esp32s31"
CONFIG_BOOTLOADER_NUM_PIN_APP_TEST=18
CONFIG_BOOTLOADER_NUM_PIN_FACTORY_RESET=4

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -9,7 +9,7 @@
#include <assert.h>
#include "esp_efuse_table_v3.0.h"
// md5_digest_table d471a4221faaafb88f091d4549ecac55
// md5_digest_table 123e655d603c452435b3df33fa0b32f5
// This file was generated from the file esp_efuse_table_v3.0.csv. DO NOT CHANGE THIS FILE MANUALLY.
// If you want to change some fields, you need to change esp_efuse_table_v3.0.csv file
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
@@ -683,18 +683,19 @@ static const esp_efuse_desc_t RD_DIS_USB_OTG11_EXCHG_PINS[] = {
{EFUSE_BLK0, 38, 1}, // [] rd_dis of USB_OTG11_EXCHG_PINS,
};
static const esp_efuse_desc_t RECOVERY_BOOTLOADER_FLASH_SECTOR_0_1[] = {
{EFUSE_BLK0, 39, 2}, // [] Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled,
static const esp_efuse_desc_t RECOVERY_BOOTLOADER_FLASH_SECTOR[] = {
{EFUSE_BLK0, 39, 2}, // [] 2 bits. Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled,
{EFUSE_BLK0, 42, 1}, // [] 1 bit. Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled,
{EFUSE_BLK0, 53, 4}, // [] 4 bits. Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled,
{EFUSE_BLK0, 63, 1}, // [] 1 bit. Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled,
{EFUSE_BLK0, 64, 3}, // [] 3 bits. Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled,
{EFUSE_BLK0, 67, 1}, // [] 1 bit. Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled,
};
static const esp_efuse_desc_t DIS_USB_JTAG[] = {
{EFUSE_BLK0, 41, 1}, // [] Set this bit to disable function of usb switch to jtag in module of usb device,
};
static const esp_efuse_desc_t RECOVERY_BOOTLOADER_FLASH_SECTOR_2_2[] = {
{EFUSE_BLK0, 42, 1}, // [] Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled,
};
static const esp_efuse_desc_t DIS_FORCE_DOWNLOAD[] = {
{EFUSE_BLK0, 44, 1}, // [] Set this bit to disable the function that forces chip into download mode,
};
@@ -723,10 +724,6 @@ static const esp_efuse_desc_t DIS_DOWNLOAD_MANUAL_ENCRYPT[] = {
{EFUSE_BLK0, 52, 1}, // [] Set this bit to disable flash manual encrypt function (except in SPI boot mode),
};
static const esp_efuse_desc_t RECOVERY_BOOTLOADER_FLASH_SECTOR_3_6[] = {
{EFUSE_BLK0, 53, 4}, // [] Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled,
};
static const esp_efuse_desc_t USB_PHY_SEL[] = {
{EFUSE_BLK0, 57, 1}, // [] 0: intphy(gpio24/25) <---> usb_device 1: intphy(26/27) <---> usb_otg11.1: intphy(gpio26/27) <---> usb_device 1: intphy(24/25) <---> usb_otg11,
};
@@ -735,18 +732,6 @@ static const esp_efuse_desc_t HUK_GEN_STATE[] = {
{EFUSE_BLK0, 58, 5}, // [] Set the bits to control validation of HUK generate mode. Odd of 1 is invalid; even of 1 is valid,
};
static const esp_efuse_desc_t RECOVERY_BOOTLOADER_FLASH_SECTOR_7_7[] = {
{EFUSE_BLK0, 63, 1}, // [] Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled,
};
static const esp_efuse_desc_t RECOVERY_BOOTLOADER_FLASH_SECTOR_8_10[] = {
{EFUSE_BLK0, 64, 3}, // [] Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled,
};
static const esp_efuse_desc_t RECOVERY_BOOTLOADER_FLASH_SECTOR_11_11[] = {
{EFUSE_BLK0, 67, 1}, // [] Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled,
};
static const esp_efuse_desc_t KM_RND_SWITCH_CYCLE[] = {
{EFUSE_BLK0, 68, 1}, // [] Set the bits to control key manager random number switch cycle. 0: control by register. 1: 8 km clk cycles. 2: 16 km cycles. 3: 32 km cycles,
};
@@ -2061,8 +2046,13 @@ const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_USB_OTG11_EXCHG_PINS[] = {
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_RECOVERY_BOOTLOADER_FLASH_SECTOR_0_1[] = {
&RECOVERY_BOOTLOADER_FLASH_SECTOR_0_1[0], // [] Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
const esp_efuse_desc_t* ESP_EFUSE_RECOVERY_BOOTLOADER_FLASH_SECTOR[] = {
&RECOVERY_BOOTLOADER_FLASH_SECTOR[0], // [] 2 bits. Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
&RECOVERY_BOOTLOADER_FLASH_SECTOR[1], // [] 1 bit. Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
&RECOVERY_BOOTLOADER_FLASH_SECTOR[2], // [] 4 bits. Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
&RECOVERY_BOOTLOADER_FLASH_SECTOR[3], // [] 1 bit. Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
&RECOVERY_BOOTLOADER_FLASH_SECTOR[4], // [] 3 bits. Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
&RECOVERY_BOOTLOADER_FLASH_SECTOR[5], // [] 1 bit. Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
NULL
};
@@ -2071,11 +2061,6 @@ const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_JTAG[] = {
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_RECOVERY_BOOTLOADER_FLASH_SECTOR_2_2[] = {
&RECOVERY_BOOTLOADER_FLASH_SECTOR_2_2[0], // [] Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_DIS_FORCE_DOWNLOAD[] = {
&DIS_FORCE_DOWNLOAD[0], // [] Set this bit to disable the function that forces chip into download mode
NULL
@@ -2111,11 +2096,6 @@ const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT[] = {
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_RECOVERY_BOOTLOADER_FLASH_SECTOR_3_6[] = {
&RECOVERY_BOOTLOADER_FLASH_SECTOR_3_6[0], // [] Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_USB_PHY_SEL[] = {
&USB_PHY_SEL[0], // [] 0: intphy(gpio24/25) <---> usb_device 1: intphy(26/27) <---> usb_otg11.1: intphy(gpio26/27) <---> usb_device 1: intphy(24/25) <---> usb_otg11
NULL
@@ -2126,21 +2106,6 @@ const esp_efuse_desc_t* ESP_EFUSE_HUK_GEN_STATE[] = {
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_RECOVERY_BOOTLOADER_FLASH_SECTOR_7_7[] = {
&RECOVERY_BOOTLOADER_FLASH_SECTOR_7_7[0], // [] Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_RECOVERY_BOOTLOADER_FLASH_SECTOR_8_10[] = {
&RECOVERY_BOOTLOADER_FLASH_SECTOR_8_10[0], // [] Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_RECOVERY_BOOTLOADER_FLASH_SECTOR_11_11[] = {
&RECOVERY_BOOTLOADER_FLASH_SECTOR_11_11[0], // [] Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
NULL
};
const esp_efuse_desc_t* ESP_EFUSE_KM_RND_SWITCH_CYCLE[] = {
&KM_RND_SWITCH_CYCLE[0], // [] Set the bits to control key manager random number switch cycle. 0: control by register. 1: 8 km clk cycles. 2: 16 km cycles. 3: 32 km cycles
NULL

View File

@@ -178,9 +178,13 @@ RD_DIS.ADC2_CH5_ATTEN0_INITCODE_DIFF, EFUSE_BLK0, 38, 1, [] rd_dis
RD_DIS.TEMPERATURE_SENSOR, EFUSE_BLK0, 38, 1, [] rd_dis of TEMPERATURE_SENSOR
RD_DIS.USB_DEVICE_EXCHG_PINS, EFUSE_BLK0, 38, 1, [] rd_dis of USB_DEVICE_EXCHG_PINS
RD_DIS.USB_OTG11_EXCHG_PINS, EFUSE_BLK0, 38, 1, [] rd_dis of USB_OTG11_EXCHG_PINS
RECOVERY_BOOTLOADER_FLASH_SECTOR_0_1, EFUSE_BLK0, 39, 2, [] Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
RECOVERY_BOOTLOADER_FLASH_SECTOR, EFUSE_BLK0, 39, 2, [] 2 bits. Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
, EFUSE_BLK0, 42, 1, [] 1 bit. Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
, EFUSE_BLK0, 53, 4, [] 4 bits. Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
, EFUSE_BLK0, 63, 1, [] 1 bit. Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
, EFUSE_BLK0, 64, 3, [] 3 bits. Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
, EFUSE_BLK0, 67, 1, [] 1 bit. Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
DIS_USB_JTAG, EFUSE_BLK0, 41, 1, [] Set this bit to disable function of usb switch to jtag in module of usb device
RECOVERY_BOOTLOADER_FLASH_SECTOR_2_2, EFUSE_BLK0, 42, 1, [] Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
DIS_FORCE_DOWNLOAD, EFUSE_BLK0, 44, 1, [] Set this bit to disable the function that forces chip into download mode
SPI_DOWNLOAD_MSPI_DIS, EFUSE_BLK0, 45, 1, [] Set this bit to disable accessing MSPI flash/MSPI ram by SYS AXI matrix during boot_mode_download
DIS_TWAI, EFUSE_BLK0, 46, 1, [] Set this bit to disable TWAI function
@@ -188,12 +192,8 @@ JTAG_SEL_ENABLE, EFUSE_BLK0, 47, 1, [] Set th
SOFT_DIS_JTAG, EFUSE_BLK0, 48, 3, [] Set odd bits to disable JTAG in the soft way. JTAG can be enabled in HMAC module
DIS_PAD_JTAG, EFUSE_BLK0, 51, 1, [] Set this bit to disable JTAG in the hard way. JTAG is disabled permanently
DIS_DOWNLOAD_MANUAL_ENCRYPT, EFUSE_BLK0, 52, 1, [] Set this bit to disable flash manual encrypt function (except in SPI boot mode)
RECOVERY_BOOTLOADER_FLASH_SECTOR_3_6, EFUSE_BLK0, 53, 4, [] Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
USB_PHY_SEL, EFUSE_BLK0, 57, 1, [] 0: intphy(gpio24/25) <---> usb_device 1: intphy(26/27) <---> usb_otg11.1: intphy(gpio26/27) <---> usb_device 1: intphy(24/25) <---> usb_otg11
HUK_GEN_STATE, EFUSE_BLK0, 58, 5, [] Set the bits to control validation of HUK generate mode. Odd of 1 is invalid; even of 1 is valid
RECOVERY_BOOTLOADER_FLASH_SECTOR_7_7, EFUSE_BLK0, 63, 1, [] Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
RECOVERY_BOOTLOADER_FLASH_SECTOR_8_10, EFUSE_BLK0, 64, 3, [] Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
RECOVERY_BOOTLOADER_FLASH_SECTOR_11_11, EFUSE_BLK0, 67, 1, [] Represents the starting flash sector (flash sector size is 0x1000) of the recovery bootloader used by the ROM bootloader If the primary bootloader fails. 0 and 0xFFF - this feature is disabled
KM_RND_SWITCH_CYCLE, EFUSE_BLK0, 68, 1, [] Set the bits to control key manager random number switch cycle. 0: control by register. 1: 8 km clk cycles. 2: 16 km cycles. 3: 32 km cycles
KM_DEPLOY_ONLY_ONCE, EFUSE_BLK0, 69, 4, [] EFUSE_KM_DEPLOY_ONLY_ONCE and EFUSE_KM_DEPLOY_ONLY_ONCE_H together form one field: {EFUSE_KM_DEPLOY_ONLY_ONCE_H; EFUSE_KM_DEPLOY_ONLY_ONCE[3:0]}. Set each bit to control whether corresponding key can only be deployed once. 1 is true; 0 is false. bit 0: ecsda; bit 1: xts; bit2: hmac; bit3: ds; bit4:psram
, EFUSE_BLK0, 118, 1, [] EFUSE_KM_DEPLOY_ONLY_ONCE and EFUSE_KM_DEPLOY_ONLY_ONCE_H together form one field: {EFUSE_KM_DEPLOY_ONLY_ONCE_H; EFUSE_KM_DEPLOY_ONLY_ONCE[3:0]}. Set each bit to control whether corresponding key can only be deployed once. 1 is true; 0 is false. bit 0: ecsda; bit 1: xts; bit2: hmac; bit3: ds; bit4:psram
Can't render this file because it contains an unexpected character in line 8 and column 53.

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -10,7 +10,7 @@ extern "C" {
#include "esp_efuse.h"
// md5_digest_table d471a4221faaafb88f091d4549ecac55
// md5_digest_table 123e655d603c452435b3df33fa0b32f5
// This file was generated from the file esp_efuse_table_v3.0.csv. DO NOT CHANGE THIS FILE MANUALLY.
// If you want to change some fields, you need to change esp_efuse_table_v3.0.csv file
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
@@ -208,9 +208,8 @@ extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_ADC2_CH5_ATTEN0_INITCODE_DIFF[];
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_TEMPERATURE_SENSOR[];
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_USB_DEVICE_EXCHG_PINS[];
extern const esp_efuse_desc_t* ESP_EFUSE_RD_DIS_USB_OTG11_EXCHG_PINS[];
extern const esp_efuse_desc_t* ESP_EFUSE_RECOVERY_BOOTLOADER_FLASH_SECTOR_0_1[];
extern const esp_efuse_desc_t* ESP_EFUSE_RECOVERY_BOOTLOADER_FLASH_SECTOR[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_USB_JTAG[];
extern const esp_efuse_desc_t* ESP_EFUSE_RECOVERY_BOOTLOADER_FLASH_SECTOR_2_2[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_FORCE_DOWNLOAD[];
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_DOWNLOAD_MSPI_DIS[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_TWAI[];
@@ -218,12 +217,8 @@ extern const esp_efuse_desc_t* ESP_EFUSE_JTAG_SEL_ENABLE[];
extern const esp_efuse_desc_t* ESP_EFUSE_SOFT_DIS_JTAG[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_PAD_JTAG[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT[];
extern const esp_efuse_desc_t* ESP_EFUSE_RECOVERY_BOOTLOADER_FLASH_SECTOR_3_6[];
extern const esp_efuse_desc_t* ESP_EFUSE_USB_PHY_SEL[];
extern const esp_efuse_desc_t* ESP_EFUSE_HUK_GEN_STATE[];
extern const esp_efuse_desc_t* ESP_EFUSE_RECOVERY_BOOTLOADER_FLASH_SECTOR_7_7[];
extern const esp_efuse_desc_t* ESP_EFUSE_RECOVERY_BOOTLOADER_FLASH_SECTOR_8_10[];
extern const esp_efuse_desc_t* ESP_EFUSE_RECOVERY_BOOTLOADER_FLASH_SECTOR_11_11[];
extern const esp_efuse_desc_t* ESP_EFUSE_KM_RND_SWITCH_CYCLE[];
extern const esp_efuse_desc_t* ESP_EFUSE_KM_DEPLOY_ONLY_ONCE[];
extern const esp_efuse_desc_t* ESP_EFUSE_FORCE_USE_KEY_MANAGER_KEY[];

View File

@@ -160,6 +160,11 @@ esp_err_t esp_efuse_enable_ecdsa_p192_curve_mode(void)
#if SOC_RECOVERY_BOOTLOADER_SUPPORTED
esp_err_t esp_efuse_set_recovery_bootloader_offset(const uint32_t offset)
{
#if CONFIG_IDF_TARGET_ESP32P4 && !EFUSE_LL_HAS_RECOVERY_BOOTLOADER
// esp32p4 with version < 3.0 does not have recovery bootloader feature.
ESP_LOGE(TAG, "Recovery bootloader eFuse field is not available for this chip revision");
return ESP_ERR_NOT_SUPPORTED;
#else
// The eFuse field stores the sector number instead of the full address to conserve eFuse bits.
if (efuse_ll_get_recovery_bootloader_sector() == 0) {
ESP_LOGI(TAG, "Recovery bootloader offset has not been set yet.");
@@ -185,6 +190,7 @@ esp_err_t esp_efuse_set_recovery_bootloader_offset(const uint32_t offset)
ESP_LOGI(TAG, "Recovery bootloader offset in eFuse = 0x%" PRIx32, programmed_offset);
return ESP_OK;
#endif
}
#endif // SOC_RECOVERY_BOOTLOADER_SUPPORTED

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -451,6 +451,30 @@ void intr_matrix_set(int cpu_no, uint32_t model_num, uint32_t intr_num);
#define ETS_MEM_BAR() asm volatile ( "" : : : "memory" )
/**
* @brief Returns the offset from which the bootloader image is used to load.
*
* The offset can point to either the PRIMARY or RECOVERY bootloader.
*
* @note The bootloader offset variable in ROM is stored in a memory that will be reclaimed by heap component.
* Read it before the heap is initialized, otherwise it may return an invalid value.
*
* @return The offset of the active bootloader.
*/
uint32_t ets_get_bootloader_offset(void);
/**
* @brief Sets the offset from which the bootloader image is used to load.
*
* The offset can point to either the PRIMARY or RECOVERY bootloader.
*
* @note The bootloader offset variable in ROM is stored in a memory that will be reclaimed by heap component.
* Setting it after the heap is initialized, may corrupt the heap memory.
*
* @param offset The offset value to set for the active bootloader.
*/
void ets_set_bootloader_offset(uint32_t offset);
/**
* @}
*/

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -462,6 +462,30 @@ void intr_matrix_set(int cpu_no, uint32_t model_num, uint32_t intr_num);
#define ETS_MEM_BAR() asm volatile ( "" : : : "memory" )
/**
* @brief Returns the offset from which the bootloader image is used to load.
*
* The offset can point to either the PRIMARY or RECOVERY bootloader.
*
* @note The bootloader offset variable in ROM is stored in a memory that will be reclaimed by heap component.
* Read it before the heap is initialized, otherwise it may return an invalid value.
*
* @return The offset of the active bootloader.
*/
uint32_t ets_get_bootloader_offset(void);
/**
* @brief Sets the offset from which the bootloader image is used to load.
*
* The offset can point to either the PRIMARY or RECOVERY bootloader.
*
* @note The bootloader offset variable in ROM is stored in a memory that will be reclaimed by heap component.
* Setting it after the heap is initialized, may corrupt the heap memory.
*
* @param offset The offset value to set for the active bootloader.
*/
void ets_set_bootloader_offset(uint32_t offset);
typedef enum {
OK = 0,
FAIL,

View File

@@ -119,11 +119,17 @@ void esp_rom_set_cpu_ticks_per_us(uint32_t ticks_per_us)
#if SOC_RECOVERY_BOOTLOADER_SUPPORTED
uint32_t esp_rom_get_bootloader_offset(void)
{
#if CONFIG_IDF_TARGET_ESP32P4 && CONFIG_ESP32P4_REV_MIN_FULL < 300
// For early revisions of ESP32-P4 does not recovery bootloader feature.
// Return the default bootloader offset.
return CONFIG_BOOTLOADER_OFFSET_IN_FLASH;
#else
static uint32_t offset_of_active_bootloader = UINT32_MAX;
if (offset_of_active_bootloader == UINT32_MAX) {
offset_of_active_bootloader = ets_get_bootloader_offset();
}
return offset_of_active_bootloader;
#endif
}
#endif // SOC_RECOVERY_BOOTLOADER_SUPPORTED

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -44,6 +44,8 @@ typedef enum {
#define EFUSE_LL_HAS_ECDSA_KEY_P384 (1)
#define EFUSE_LL_HAS_PSRAM_ENCRYPTION_XTS_AES_128 (1)
#define EFUSE_LL_HAS_PSRAM_ENCRYPTION_XTS_AES_256 (1)
// Rev 3.00+: Recovery bootloader eFuse field is present.
#define EFUSE_LL_HAS_RECOVERY_BOOTLOADER (1)
#endif
// Always inline these functions even no gcc optimization is applied.
@@ -112,6 +114,24 @@ __attribute__((always_inline)) static inline uint32_t efuse_ll_get_chip_ver_pkg(
return EFUSE.rd_mac_sys_2.pkg_version;
}
#if EFUSE_LL_HAS_RECOVERY_BOOTLOADER
__attribute__((always_inline)) static inline uint32_t efuse_ll_get_recovery_bootloader_sector(void)
{
return ((uint32_t)EFUSE.rd_repeat_data1.recovery_bootloader_flash_sector_11_11 << 11) |
((uint32_t)EFUSE.rd_repeat_data1.recovery_bootloader_flash_sector_8_10 << 8) |
((uint32_t)EFUSE.rd_repeat_data0.recovery_bootloader_flash_sector_7_7 << 7) |
((uint32_t)EFUSE.rd_repeat_data0.recovery_bootloader_flash_sector_3_6 << 3) |
((uint32_t)EFUSE.rd_repeat_data0.recovery_bootloader_flash_sector_2_2 << 2) |
((uint32_t)EFUSE.rd_repeat_data0.recovery_bootloader_flash_sector_0_1);
}
#else
__attribute__((always_inline)) static inline uint32_t efuse_ll_get_recovery_bootloader_sector(void)
{
// Rev < 3.0 has no recovery bootloader eFuse field.
return 0;
}
#endif
/******************* eFuse control functions *************************/
__attribute__((always_inline)) static inline bool efuse_ll_get_read_cmd(void)

View File

@@ -94,6 +94,11 @@ __attribute__((always_inline)) static inline uint32_t efuse_ll_get_chip_ver_pkg(
return EFUSE.rd_mac_sys4.pkg_version;
}
__attribute__((always_inline)) static inline uint32_t efuse_ll_get_recovery_bootloader_sector(void)
{
return EFUSE.rd_repeat_data5.recovery_bootloader_flash_sector;
}
/******************* eFuse control functions *************************/
__attribute__((always_inline)) static inline bool efuse_ll_get_read_cmd(void)

View File

@@ -1627,6 +1627,10 @@ config SOC_PSRAM_ENCRYPTION_PAGE_CONFIGURABLE
bool
default y
config SOC_RECOVERY_BOOTLOADER_SUPPORTED
bool
default y
config SOC_UART_NUM
int
default 6

View File

@@ -617,6 +617,10 @@
#define SOC_PSRAM_ENCRYPTION_SEPARATE_KEY 1 /* PSRAM encryption can use independent key */
#define SOC_PSRAM_ENCRYPTION_PAGE_CONFIGURABLE 1 /* PSRAM encryption can be configured on a MMU page basis */
/*------------------------Bootloader CAPS---------------------------------*/
/* Support Recovery Bootloader */
#define SOC_RECOVERY_BOOTLOADER_SUPPORTED (1)
/*-------------------------- MEMPROT CAPS ------------------------------------*/
/*-------------------------- UART CAPS ---------------------------------------*/

View File

@@ -919,6 +919,14 @@ config SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX
int
default 64
config SOC_RECOVERY_BOOTLOADER_SUPPORTED
bool
default y
config SOC_BOOTLOADER_ANTI_ROLLBACK_SUPPORTED
bool
default y
config SOC_UART_NUM
int
default 5

View File

@@ -374,6 +374,12 @@
#define SOC_FLASH_ENCRYPTION_XTS_AES 1
#define SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX (64)
/*------------------------Bootloader CAPS---------------------------------*/
/* Support Recovery Bootloader */
#define SOC_RECOVERY_BOOTLOADER_SUPPORTED (1)
/* Support Anti-rollback */
#define SOC_BOOTLOADER_ANTI_ROLLBACK_SUPPORTED (1)
/*-------------------------- UART CAPS ---------------------------------------*/
#define SOC_UART_NUM (5)
#define SOC_UART_HP_NUM (4)

View File

@@ -1,2 +1,3 @@
CONFIG_ESP_TASK_WDT_EN=n
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
CONFIG_PARTITION_TABLE_OFFSET=0x9000

View File

@@ -0,0 +1,2 @@
# ESP32C61 supports the Recovery bootloader feature in ROM starting from v1.0 (ECO3)
CONFIG_IDF_TARGET="esp32c61"

View File

@@ -0,0 +1,3 @@
# ESP32P4 supports the Recovery bootloader feature in ROM from rev3.0
CONFIG_IDF_TARGET="esp32p4"
CONFIG_ESP32P4_REV_MIN_300=y

View File

@@ -0,0 +1,2 @@
# ESP32S31 supports the Recovery bootloader feature in ROM
CONFIG_IDF_TARGET="esp32s31"

View File

@@ -13,7 +13,7 @@ CONFIG_EXAMPLE_CONNECT_IPV6=n
CONFIG_EFUSE_VIRTUAL=y
CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=y
CONFIG_PARTITION_TABLE_OFFSET=0xE000
CONFIG_PARTITION_TABLE_OFFSET=0xF000
CONFIG_SECURE_BOOT=y
CONFIG_SECURE_BOOT_V2_ENABLED=y

View File

@@ -13,7 +13,7 @@ CONFIG_EXAMPLE_CONNECT_IPV6=n
CONFIG_EFUSE_VIRTUAL=y
CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=y
CONFIG_PARTITION_TABLE_OFFSET=0xE000
CONFIG_PARTITION_TABLE_OFFSET=0xF000
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="test/partitions_efuse_emul_2.csv"

View File

@@ -1 +1,2 @@
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
CONFIG_PARTITION_TABLE_OFFSET=0x9000