From ce467787a97bce4064b53a0a48547c2adff3c287 Mon Sep 17 00:00:00 2001 From: Konstantin Kondrashov Date: Wed, 6 May 2026 17:10:51 +0300 Subject: [PATCH] feat(bootloader): Support recovery bootloader for ESP32P4/C61 --- .../test_app_update/.build-test-rules.yml | 8 +-- .../test_app_update/pytest_app_update_ut.py | 2 +- .../sdkconfig.ci.recovery_bootloader.esp32p4 | 3 + .../sdkconfig.defaults.esp32c61 | 3 + .../efuse/esp32p4/esp_efuse_table_v3.0.c | 67 +++++-------------- .../efuse/esp32p4/esp_efuse_table_v3.0.csv | 12 ++-- .../esp32p4/include/esp_efuse_table_v3.0.h | 11 +-- components/efuse/src/esp_efuse_fields.c | 6 ++ .../esp32p4/include/esp32p4/rom/ets_sys.h | 26 ++++++- components/esp_rom/patches/esp_rom_sys.c | 6 ++ components/hal/esp32p4/include/hal/efuse_ll.h | 22 +++++- .../esp32p4/include/soc/Kconfig.soc_caps.in | 4 ++ components/soc/esp32p4/include/soc/soc_caps.h | 4 ++ .../sdkconfig.ci.recovery_bootloader.esp32c61 | 2 + .../sdkconfig.ci.recovery_bootloader.esp32p4 | 3 + .../sdkconfig.ci.virt_sb_v2_and_fe | 2 +- .../sdkconfig.ci.virt_sb_v2_and_fe_2 | 2 +- 17 files changed, 109 insertions(+), 74 deletions(-) create mode 100644 components/app_update/test_apps/test_app_update/sdkconfig.ci.recovery_bootloader.esp32p4 create mode 100644 components/app_update/test_apps/test_app_update/sdkconfig.defaults.esp32c61 create mode 100644 examples/system/ota/partitions_ota/sdkconfig.ci.recovery_bootloader.esp32c61 create mode 100644 examples/system/ota/partitions_ota/sdkconfig.ci.recovery_bootloader.esp32p4 diff --git a/components/app_update/test_apps/test_app_update/.build-test-rules.yml b/components/app_update/test_apps/test_app_update/.build-test-rules.yml index b0fce925760..f04a4d77f80 100644 --- a/components/app_update/test_apps/test_app_update/.build-test-rules.yml +++ b/components/app_update/test_apps/test_app_update/.build-test-rules.yml @@ -15,7 +15,7 @@ components/app_update/test_apps: - 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 + - esp_partitions diff --git a/components/app_update/test_apps/test_app_update/pytest_app_update_ut.py b/components/app_update/test_apps/test_app_update/pytest_app_update_ut.py index d49066dea0c..76b18601c54 100644 --- a/components/app_update/test_apps/test_app_update/pytest_app_update_ut.py +++ b/components/app_update/test_apps/test_app_update/pytest_app_update_ut.py @@ -68,7 +68,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'], indirect=['target']) def test_recovery_bootloader_update(dut: Dut) -> None: try: dut.run_all_single_board_cases(group='recovery_bootloader', timeout=90) diff --git a/components/app_update/test_apps/test_app_update/sdkconfig.ci.recovery_bootloader.esp32p4 b/components/app_update/test_apps/test_app_update/sdkconfig.ci.recovery_bootloader.esp32p4 new file mode 100644 index 00000000000..2be90bacf62 --- /dev/null +++ b/components/app_update/test_apps/test_app_update/sdkconfig.ci.recovery_bootloader.esp32p4 @@ -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 diff --git a/components/app_update/test_apps/test_app_update/sdkconfig.defaults.esp32c61 b/components/app_update/test_apps/test_app_update/sdkconfig.defaults.esp32c61 new file mode 100644 index 00000000000..821bcfe5b89 --- /dev/null +++ b/components/app_update/test_apps/test_app_update/sdkconfig.defaults.esp32c61 @@ -0,0 +1,3 @@ +CONFIG_IDF_TARGET="esp32c61" +CONFIG_BOOTLOADER_NUM_PIN_APP_TEST=18 +CONFIG_BOOTLOADER_NUM_PIN_FACTORY_RESET=19 diff --git a/components/efuse/esp32p4/esp_efuse_table_v3.0.c b/components/efuse/esp32p4/esp_efuse_table_v3.0.c index 1051c0d9cf5..e03474a762e 100644 --- a/components/efuse/esp32p4/esp_efuse_table_v3.0.c +++ b/components/efuse/esp32p4/esp_efuse_table_v3.0.c @@ -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 #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 diff --git a/components/efuse/esp32p4/esp_efuse_table_v3.0.csv b/components/efuse/esp32p4/esp_efuse_table_v3.0.csv index a4bbe3a1d46..6c23ae7015d 100644 --- a/components/efuse/esp32p4/esp_efuse_table_v3.0.csv +++ b/components/efuse/esp32p4/esp_efuse_table_v3.0.csv @@ -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 diff --git a/components/efuse/esp32p4/include/esp_efuse_table_v3.0.h b/components/efuse/esp32p4/include/esp_efuse_table_v3.0.h index 3c3ea8920c0..57b4c030880 100644 --- a/components/efuse/esp32p4/include/esp_efuse_table_v3.0.h +++ b/components/efuse/esp32p4/include/esp_efuse_table_v3.0.h @@ -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[]; diff --git a/components/efuse/src/esp_efuse_fields.c b/components/efuse/src/esp_efuse_fields.c index 9bd1ef61560..ef5f5671b62 100644 --- a/components/efuse/src/esp_efuse_fields.c +++ b/components/efuse/src/esp_efuse_fields.c @@ -158,6 +158,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."); @@ -183,5 +188,6 @@ 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 diff --git a/components/esp_rom/esp32p4/include/esp32p4/rom/ets_sys.h b/components/esp_rom/esp32p4/include/esp32p4/rom/ets_sys.h index 95d8b092fcc..3aae7b0a6a7 100644 --- a/components/esp_rom/esp32p4/include/esp32p4/rom/ets_sys.h +++ b/components/esp_rom/esp32p4/include/esp32p4/rom/ets_sys.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -516,6 +516,30 @@ typedef enum { CANCEL, } STATUS; +/** + * @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); + /** * @} */ diff --git a/components/esp_rom/patches/esp_rom_sys.c b/components/esp_rom/patches/esp_rom_sys.c index 848a552419c..a8d5f161738 100644 --- a/components/esp_rom/patches/esp_rom_sys.c +++ b/components/esp_rom/patches/esp_rom_sys.c @@ -109,11 +109,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 diff --git a/components/hal/esp32p4/include/hal/efuse_ll.h b/components/hal/esp32p4/include/hal/efuse_ll.h index 3d88587d093..b2165c17c4f 100644 --- a/components/hal/esp32p4/include/hal/efuse_ll.h +++ b/components/hal/esp32p4/include/hal/efuse_ll.h @@ -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 */ @@ -46,6 +46,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. @@ -119,6 +121,24 @@ __attribute__((always_inline)) static inline void efuse_ll_set_ecdsa_key_blk(ecd ecdsa_ll_set_ecdsa_key_blk(curve, efuse_blk); } +#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) diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index 17e53307aeb..7ea9b960efe 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -1991,6 +1991,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 diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 6611f478f07..ebe884796d0 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -723,6 +723,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 ---------------------------------------*/ diff --git a/examples/system/ota/partitions_ota/sdkconfig.ci.recovery_bootloader.esp32c61 b/examples/system/ota/partitions_ota/sdkconfig.ci.recovery_bootloader.esp32c61 new file mode 100644 index 00000000000..c40bd234eb5 --- /dev/null +++ b/examples/system/ota/partitions_ota/sdkconfig.ci.recovery_bootloader.esp32c61 @@ -0,0 +1,2 @@ +# ESP32C61 supports the Recovery bootloader feature in ROM starting from v1.0 (ECO3) +CONFIG_IDF_TARGET="esp32c61" diff --git a/examples/system/ota/partitions_ota/sdkconfig.ci.recovery_bootloader.esp32p4 b/examples/system/ota/partitions_ota/sdkconfig.ci.recovery_bootloader.esp32p4 new file mode 100644 index 00000000000..2be90bacf62 --- /dev/null +++ b/examples/system/ota/partitions_ota/sdkconfig.ci.recovery_bootloader.esp32p4 @@ -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 diff --git a/examples/system/ota/partitions_ota/sdkconfig.ci.virt_sb_v2_and_fe b/examples/system/ota/partitions_ota/sdkconfig.ci.virt_sb_v2_and_fe index b46d7a4f582..285a0e7c1b6 100644 --- a/examples/system/ota/partitions_ota/sdkconfig.ci.virt_sb_v2_and_fe +++ b/examples/system/ota/partitions_ota/sdkconfig.ci.virt_sb_v2_and_fe @@ -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 diff --git a/examples/system/ota/partitions_ota/sdkconfig.ci.virt_sb_v2_and_fe_2 b/examples/system/ota/partitions_ota/sdkconfig.ci.virt_sb_v2_and_fe_2 index 40d2f72990c..59aa6d85f74 100644 --- a/examples/system/ota/partitions_ota/sdkconfig.ci.virt_sb_v2_and_fe_2 +++ b/examples/system/ota/partitions_ota/sdkconfig.ci.virt_sb_v2_and_fe_2 @@ -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"