Infineon: Switch to 1.9.0 code base, add xmc7000 family support, refactor memory layer
diff --git a/boot/espressif/hal/src/esp32/bootloader_init.c b/boot/espressif/hal/src/esp32/bootloader_init.c
new file mode 100644
index 0000000..e7b1528
--- /dev/null
+++ b/boot/espressif/hal/src/esp32/bootloader_init.c
@@ -0,0 +1,218 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "sdkconfig.h"
+#include "esp_attr.h"
+#include "esp_image_format.h"
+
+#include "bootloader_init.h"
+#include "bootloader_mem.h"
+#include "bootloader_clock.h"
+#include "bootloader_flash_config.h"
+#include "bootloader_flash.h"
+#include "bootloader_flash_priv.h"
+
+#include "soc/dport_reg.h"
+#include "soc/efuse_reg.h"
+#include "soc/rtc.h"
+
+#include "hal/wdt_hal.h"
+
+#include "esp32/rom/cache.h"
+#include "esp32/rom/spi_flash.h"
+#include "esp32/rom/uart.h"
+
+esp_image_header_t WORD_ALIGNED_ATTR bootloader_image_hdr;
+
+void bootloader_clear_bss_section(void)
+{
+ memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start));
+}
+
+static void bootloader_common_vddsdio_configure(void)
+{
+ rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config();
+ if (cfg.enable == 1 && cfg.tieh == RTC_VDDSDIO_TIEH_1_8V) { /* VDDSDIO regulator is enabled @ 1.8V */
+ cfg.drefh = 3;
+ cfg.drefm = 3;
+ cfg.drefl = 3;
+ cfg.force = 1;
+ rtc_vddsdio_set_config(cfg);
+ ets_delay_us(10); /* wait for regulator to become stable */
+ }
+}
+
+static void bootloader_reset_mmu(void)
+{
+ /* completely reset MMU in case serial bootloader was running */
+ Cache_Read_Disable(0);
+#if !CONFIG_FREERTOS_UNICORE
+ Cache_Read_Disable(1);
+#endif
+ Cache_Flush(0);
+#if !CONFIG_FREERTOS_UNICORE
+ Cache_Flush(1);
+#endif
+ mmu_init(0);
+#if !CONFIG_FREERTOS_UNICORE
+ /* The lines which manipulate DPORT_APP_CACHE_MMU_IA_CLR bit are
+ necessary to work around a hardware bug. */
+ DPORT_REG_SET_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
+ mmu_init(1);
+ DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
+#endif
+
+ /* normal ROM boot exits with DROM0 cache unmasked,
+ but serial bootloader exits with it masked. */
+ DPORT_REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MASK_DROM0);
+#if !CONFIG_FREERTOS_UNICORE
+ DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MASK_DROM0);
+#endif
+}
+
+static esp_err_t bootloader_check_rated_cpu_clock(void)
+{
+ int rated_freq = bootloader_clock_get_rated_freq_mhz();
+ if (rated_freq < 80) {
+ return ESP_FAIL;
+ }
+ return ESP_OK;
+}
+
+esp_err_t bootloader_read_bootloader_header(void)
+{
+ if (bootloader_flash_read(ESP_BOOTLOADER_OFFSET, &bootloader_image_hdr, sizeof(esp_image_header_t), true) != ESP_OK) {
+ return ESP_FAIL;
+ }
+ return ESP_OK;
+}
+
+static void update_flash_config(const esp_image_header_t *bootloader_hdr)
+{
+ uint32_t size;
+ switch (bootloader_hdr->spi_size) {
+ case ESP_IMAGE_FLASH_SIZE_1MB:
+ size = 1;
+ break;
+ case ESP_IMAGE_FLASH_SIZE_2MB:
+ size = 2;
+ break;
+ case ESP_IMAGE_FLASH_SIZE_4MB:
+ size = 4;
+ break;
+ case ESP_IMAGE_FLASH_SIZE_8MB:
+ size = 8;
+ break;
+ case ESP_IMAGE_FLASH_SIZE_16MB:
+ size = 16;
+ break;
+ default:
+ size = 2;
+ }
+ Cache_Read_Disable(0);
+ /* Set flash chip size */
+ esp_rom_spiflash_config_param(g_rom_flashchip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff);
+ /* TODO: set mode */
+ /* TODO: set frequency */
+ Cache_Flush(0);
+ Cache_Read_Enable(0);
+}
+
+static void IRAM_ATTR bootloader_init_flash_configure(void)
+{
+ bootloader_flash_gpio_config(&bootloader_image_hdr);
+ bootloader_flash_dummy_config(&bootloader_image_hdr);
+ bootloader_flash_cs_timing_config();
+}
+
+static esp_err_t bootloader_init_spi_flash(void)
+{
+ bootloader_init_flash_configure();
+ esp_rom_spiflash_unlock();
+
+ update_flash_config(&bootloader_image_hdr);
+ return ESP_OK;
+}
+
+void bootloader_config_wdt(void)
+{
+ wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL};
+ wdt_hal_write_protect_disable(&rtc_wdt_ctx);
+ wdt_hal_set_flashboot_en(&rtc_wdt_ctx, false);
+ wdt_hal_write_protect_enable(&rtc_wdt_ctx);
+
+#ifdef CONFIG_ESP_MCUBOOT_WDT_ENABLE
+ wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false);
+ uint32_t stage_timeout_ticks = (uint32_t)((uint64_t)CONFIG_BOOTLOADER_WDT_TIME_MS * rtc_clk_slow_freq_get_hz() / 1000);
+ wdt_hal_write_protect_disable(&rtc_wdt_ctx);
+ wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC);
+ wdt_hal_enable(&rtc_wdt_ctx);
+ wdt_hal_write_protect_enable(&rtc_wdt_ctx);
+#endif
+
+ wdt_hal_context_t wdt_ctx = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0};
+ wdt_hal_write_protect_disable(&wdt_ctx);
+ wdt_hal_set_flashboot_en(&wdt_ctx, false);
+ wdt_hal_write_protect_enable(&wdt_ctx);
+}
+
+static void bootloader_init_uart_console(void)
+{
+ const int uart_num = 0;
+
+ uartAttach();
+ ets_install_uart_printf();
+ uart_tx_wait_idle(0);
+
+ const int uart_baud = CONFIG_ESP_CONSOLE_UART_BAUDRATE;
+ uart_div_modify(uart_num, (rtc_clk_apb_freq_get() << 4) / uart_baud);
+}
+
+
+esp_err_t bootloader_init(void)
+{
+ esp_err_t ret = ESP_OK;
+
+ bootloader_init_mem();
+
+ /* check that static RAM is after the stack */
+#ifndef NDEBUG
+ {
+ assert(&_bss_start <= &_bss_end);
+ assert(&_data_start <= &_data_end);
+ assert(sp < &_bss_start);
+ assert(sp < &_data_start);
+ }
+#endif
+ /* clear bss section */
+ bootloader_clear_bss_section();
+ /* bootst up vddsdio */
+ bootloader_common_vddsdio_configure();
+ /* reset MMU */
+ bootloader_reset_mmu();
+ /* check rated CPU clock */
+ if ((ret = bootloader_check_rated_cpu_clock()) != ESP_OK) {
+ goto err;
+ }
+ /* config clock */
+ bootloader_clock_configure();
+ /* initialize uart console, from now on, we can use ets_printf */
+ bootloader_init_uart_console();
+ /* read bootloader header */
+ if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
+ goto err;
+ }
+ /* initialize spi flash */
+ if ((ret = bootloader_init_spi_flash()) != ESP_OK) {
+ goto err;
+ }
+ /* config WDT */
+ bootloader_config_wdt();
+err:
+ return ret;
+}
diff --git a/boot/espressif/hal/src/esp32c3/bootloader_init.c b/boot/espressif/hal/src/esp32c3/bootloader_init.c
new file mode 100644
index 0000000..ec74349
--- /dev/null
+++ b/boot/espressif/hal/src/esp32c3/bootloader_init.c
@@ -0,0 +1,243 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+
+#include "sdkconfig.h"
+#include "esp_attr.h"
+#include "esp_image_format.h"
+
+#include "esp_rom_efuse.h"
+#include "esp_rom_gpio.h"
+#include "esp_rom_uart.h"
+#include "esp_rom_sys.h"
+
+#include "bootloader_init.h"
+#include "bootloader_clock.h"
+#include "bootloader_flash_config.h"
+#include "bootloader_mem.h"
+#include "bootloader_flash.h"
+#include "bootloader_flash_priv.h"
+#include "regi2c_ctrl.h"
+
+#include "soc/extmem_reg.h"
+#include "soc/io_mux_reg.h"
+#include "soc/efuse_reg.h"
+#include "soc/rtc.h"
+
+#include "esp32c3/rom/cache.h"
+#include "esp32c3/rom/spi_flash.h"
+
+#include "hal/wdt_hal.h"
+
+extern uint8_t bootloader_common_get_chip_revision(void);
+
+esp_image_header_t WORD_ALIGNED_ATTR bootloader_image_hdr;
+
+void bootloader_clear_bss_section(void)
+{
+ memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start));
+}
+
+void IRAM_ATTR bootloader_configure_spi_pins(int drv)
+{
+ const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
+ uint8_t wp_pin = esp_rom_efuse_get_flash_wp_gpio();
+ uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM;
+ uint8_t q_gpio_num = SPI_Q_GPIO_NUM;
+ uint8_t d_gpio_num = SPI_D_GPIO_NUM;
+ uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM;
+ uint8_t hd_gpio_num = SPI_HD_GPIO_NUM;
+ uint8_t wp_gpio_num = SPI_WP_GPIO_NUM;
+ if (spiconfig != 0) {
+ clk_gpio_num = spiconfig & 0x3f;
+ q_gpio_num = (spiconfig >> 6) & 0x3f;
+ d_gpio_num = (spiconfig >> 12) & 0x3f;
+ cs0_gpio_num = (spiconfig >> 18) & 0x3f;
+ hd_gpio_num = (spiconfig >> 24) & 0x3f;
+ wp_gpio_num = wp_pin;
+ }
+ esp_rom_gpio_pad_set_drv(clk_gpio_num, drv);
+ esp_rom_gpio_pad_set_drv(q_gpio_num, drv);
+ esp_rom_gpio_pad_set_drv(d_gpio_num, drv);
+ esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv);
+ if (hd_gpio_num <= MAX_PAD_GPIO_NUM) {
+ esp_rom_gpio_pad_set_drv(hd_gpio_num, drv);
+ }
+ if (wp_gpio_num <= MAX_PAD_GPIO_NUM) {
+ esp_rom_gpio_pad_set_drv(wp_gpio_num, drv);
+ }
+}
+
+static void bootloader_reset_mmu(void)
+{
+ Cache_Suspend_ICache();
+ Cache_Invalidate_ICache_All();
+ Cache_MMU_Init();
+
+ REG_CLR_BIT(EXTMEM_ICACHE_CTRL1_REG, EXTMEM_ICACHE_SHUT_IBUS);
+ REG_CLR_BIT(EXTMEM_ICACHE_CTRL1_REG, EXTMEM_ICACHE_SHUT_DBUS);
+}
+
+esp_err_t bootloader_read_bootloader_header(void)
+{
+ if (bootloader_flash_read(ESP_BOOTLOADER_OFFSET, &bootloader_image_hdr, sizeof(esp_image_header_t), true) != ESP_OK) {
+ return ESP_FAIL;
+ }
+ return ESP_OK;
+}
+
+static void update_flash_config(const esp_image_header_t *bootloader_hdr)
+{
+ uint32_t size;
+ switch (bootloader_hdr->spi_size) {
+ case ESP_IMAGE_FLASH_SIZE_1MB:
+ size = 1;
+ break;
+ case ESP_IMAGE_FLASH_SIZE_2MB:
+ size = 2;
+ break;
+ case ESP_IMAGE_FLASH_SIZE_4MB:
+ size = 4;
+ break;
+ case ESP_IMAGE_FLASH_SIZE_8MB:
+ size = 8;
+ break;
+ case ESP_IMAGE_FLASH_SIZE_16MB:
+ size = 16;
+ break;
+ default:
+ size = 2;
+ }
+ uint32_t autoload = Cache_Suspend_ICache();
+ // Set flash chip size
+ esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff);
+ Cache_Resume_ICache(autoload);
+}
+
+static void IRAM_ATTR bootloader_init_flash_configure(void)
+{
+ bootloader_flash_dummy_config(&bootloader_image_hdr);
+ bootloader_flash_cs_timing_config();
+}
+
+static void bootloader_spi_flash_resume(void)
+{
+ bootloader_execute_flash_command(CMD_RESUME, 0, 0, 0);
+ esp_rom_spiflash_wait_idle(&g_rom_flashchip);
+}
+
+static esp_err_t bootloader_init_spi_flash(void)
+{
+ bootloader_init_flash_configure();
+ bootloader_spi_flash_resume();
+ esp_rom_spiflash_unlock();
+ update_flash_config(&bootloader_image_hdr);
+
+ return ESP_OK;
+}
+
+static inline void bootloader_hardware_init(void)
+{
+ // This check is always included in the bootloader so it can
+ // print the minimum revision error message later in the boot
+ if (bootloader_common_get_chip_revision() < 3) {
+ REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_XPD_IPH, 1);
+ REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_DREG_1P1_PVT, 12);
+ }
+}
+
+static inline void bootloader_glitch_reset_disable(void)
+{
+ /*
+ For origin chip & ECO1: only support swt reset;
+ For ECO2: fix brownout reset bug, support swt & brownout reset;
+ For ECO3: fix clock glitch reset bug, support all reset, include: swt & brownout & clock glitch reset.
+ */
+ uint8_t chip_version = bootloader_common_get_chip_revision();
+ if (chip_version < 2) {
+ REG_SET_FIELD(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SEL, RTC_CNTL_FIB_SUPER_WDT_RST);
+ } else if (chip_version == 2) {
+ REG_SET_FIELD(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SEL, RTC_CNTL_FIB_SUPER_WDT_RST | RTC_CNTL_FIB_BOR_RST);
+ }
+}
+
+static void bootloader_super_wdt_auto_feed(void)
+{
+ REG_WRITE(RTC_CNTL_SWD_WPROTECT_REG, RTC_CNTL_SWD_WKEY_VALUE);
+ REG_SET_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_AUTO_FEED_EN);
+ REG_WRITE(RTC_CNTL_SWD_WPROTECT_REG, 0);
+}
+
+void bootloader_config_wdt(void)
+{
+ wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL};
+ wdt_hal_write_protect_disable(&rtc_wdt_ctx);
+ wdt_hal_set_flashboot_en(&rtc_wdt_ctx, false);
+ wdt_hal_write_protect_enable(&rtc_wdt_ctx);
+
+#ifdef CONFIG_ESP_MCUBOOT_WDT_ENABLE
+ wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false);
+ uint32_t stage_timeout_ticks = (uint32_t)((uint64_t)CONFIG_BOOTLOADER_WDT_TIME_MS * rtc_clk_slow_freq_get_hz() / 1000);
+ wdt_hal_write_protect_disable(&rtc_wdt_ctx);
+ wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC);
+ wdt_hal_enable(&rtc_wdt_ctx);
+ wdt_hal_write_protect_enable(&rtc_wdt_ctx);
+#endif
+
+ wdt_hal_context_t wdt_ctx = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0};
+ wdt_hal_write_protect_disable(&wdt_ctx);
+ wdt_hal_set_flashboot_en(&wdt_ctx, false);
+ wdt_hal_write_protect_enable(&wdt_ctx);
+}
+
+static void bootloader_init_uart_console(void)
+{
+ const int uart_num = 0;
+
+ esp_rom_install_uart_printf();
+ esp_rom_uart_tx_wait_idle(0);
+ uint32_t clock_hz = UART_CLK_FREQ_ROM;
+ esp_rom_uart_set_clock_baudrate(uart_num, clock_hz, CONFIG_ESP_CONSOLE_UART_BAUDRATE);
+}
+
+esp_err_t bootloader_init(void)
+{
+ esp_err_t ret = ESP_OK;
+
+ bootloader_hardware_init();
+ bootloader_glitch_reset_disable();
+ bootloader_super_wdt_auto_feed();
+ // protect memory region
+ bootloader_init_mem();
+ /* check that static RAM is after the stack */
+ assert(&_bss_start <= &_bss_end);
+ assert(&_data_start <= &_data_end);
+ // clear bss section
+ bootloader_clear_bss_section();
+ // reset MMU
+ bootloader_reset_mmu();
+ // config clock
+ bootloader_clock_configure();
+ /* initialize uart console, from now on, we can use ets_printf */
+ bootloader_init_uart_console();
+ // update flash ID
+ bootloader_flash_update_id();
+ // read bootloader header
+ if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
+ goto err;
+ }
+ // initialize spi flash
+ if ((ret = bootloader_init_spi_flash()) != ESP_OK) {
+ goto err;
+ }
+ // config WDT
+ bootloader_config_wdt();
+err:
+ return ret;
+}
diff --git a/boot/espressif/hal/src/esp32s2/bootloader_init.c b/boot/espressif/hal/src/esp32s2/bootloader_init.c
new file mode 100644
index 0000000..5e36530
--- /dev/null
+++ b/boot/espressif/hal/src/esp32s2/bootloader_init.c
@@ -0,0 +1,208 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "sdkconfig.h"
+#include "esp_attr.h"
+#include "esp_image_format.h"
+
+#include "esp_rom_efuse.h"
+#include "esp_rom_gpio.h"
+
+#include "bootloader_init.h"
+#include "bootloader_mem.h"
+#include "bootloader_clock.h"
+#include "bootloader_flash_config.h"
+#include "bootloader_flash.h"
+#include "bootloader_flash_priv.h"
+
+#include "soc/dport_reg.h"
+#include "soc/efuse_reg.h"
+#include "soc/rtc.h"
+#include "soc/extmem_reg.h"
+#include "soc/io_mux_reg.h"
+
+#include "hal/wdt_hal.h"
+
+#include "esp32s2/rom/cache.h"
+#include "esp32s2/rom/ets_sys.h"
+#include "esp32s2/rom/spi_flash.h"
+#include "esp32s2/rom/uart.h"
+
+esp_image_header_t WORD_ALIGNED_ATTR bootloader_image_hdr;
+
+void bootloader_clear_bss_section(void)
+{
+ memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start));
+}
+
+static void bootloader_reset_mmu(void)
+{
+ Cache_Suspend_ICache();
+ Cache_Invalidate_ICache_All();
+ Cache_MMU_Init();
+
+ /* normal ROM boot exits with DROM0 cache unmasked,
+ but serial bootloader exits with it masked. */
+ REG_CLR_BIT(EXTMEM_PRO_ICACHE_CTRL1_REG, EXTMEM_PRO_ICACHE_MASK_DROM0);
+}
+
+esp_err_t bootloader_read_bootloader_header(void)
+{
+ if (bootloader_flash_read(ESP_BOOTLOADER_OFFSET, &bootloader_image_hdr, sizeof(esp_image_header_t), true) != ESP_OK) {
+ return ESP_FAIL;
+ }
+ return ESP_OK;
+}
+
+static void update_flash_config(const esp_image_header_t *bootloader_hdr)
+{
+ uint32_t size;
+ switch (bootloader_hdr->spi_size) {
+ case ESP_IMAGE_FLASH_SIZE_1MB:
+ size = 1;
+ break;
+ case ESP_IMAGE_FLASH_SIZE_2MB:
+ size = 2;
+ break;
+ case ESP_IMAGE_FLASH_SIZE_4MB:
+ size = 4;
+ break;
+ case ESP_IMAGE_FLASH_SIZE_8MB:
+ size = 8;
+ break;
+ case ESP_IMAGE_FLASH_SIZE_16MB:
+ size = 16;
+ break;
+ default:
+ size = 2;
+ }
+ uint32_t autoload = Cache_Suspend_ICache();
+ // Set flash chip size
+ esp_rom_spiflash_config_param(g_rom_flashchip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff);
+ Cache_Resume_ICache(autoload);
+}
+
+void IRAM_ATTR bootloader_configure_spi_pins(int drv)
+{
+ const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
+ uint8_t wp_pin = esp_rom_efuse_get_flash_wp_gpio();
+ uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM;
+ uint8_t q_gpio_num = SPI_Q_GPIO_NUM;
+ uint8_t d_gpio_num = SPI_D_GPIO_NUM;
+ uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM;
+ uint8_t hd_gpio_num = SPI_HD_GPIO_NUM;
+ uint8_t wp_gpio_num = SPI_WP_GPIO_NUM;
+ if (spiconfig != 0) {
+ clk_gpio_num = spiconfig & 0x3f;
+ q_gpio_num = (spiconfig >> 6) & 0x3f;
+ d_gpio_num = (spiconfig >> 12) & 0x3f;
+ cs0_gpio_num = (spiconfig >> 18) & 0x3f;
+ hd_gpio_num = (spiconfig >> 24) & 0x3f;
+ wp_gpio_num = wp_pin;
+ }
+ esp_rom_gpio_pad_set_drv(clk_gpio_num, drv);
+ esp_rom_gpio_pad_set_drv(q_gpio_num, drv);
+ esp_rom_gpio_pad_set_drv(d_gpio_num, drv);
+ esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv);
+ if (hd_gpio_num <= MAX_PAD_GPIO_NUM) {
+ esp_rom_gpio_pad_set_drv(hd_gpio_num, drv);
+ }
+ if (wp_gpio_num <= MAX_PAD_GPIO_NUM) {
+ esp_rom_gpio_pad_set_drv(wp_gpio_num, drv);
+ }
+}
+
+static void IRAM_ATTR bootloader_init_flash_configure(void)
+{
+ bootloader_flash_dummy_config(&bootloader_image_hdr);
+ bootloader_flash_cs_timing_config();
+}
+
+static esp_err_t bootloader_init_spi_flash(void)
+{
+ bootloader_init_flash_configure();
+ esp_rom_spiflash_unlock();
+
+ update_flash_config(&bootloader_image_hdr);
+ return ESP_OK;
+}
+
+void bootloader_config_wdt(void)
+{
+ wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL};
+ wdt_hal_write_protect_disable(&rtc_wdt_ctx);
+ wdt_hal_set_flashboot_en(&rtc_wdt_ctx, false);
+ wdt_hal_write_protect_enable(&rtc_wdt_ctx);
+
+#ifdef CONFIG_ESP_MCUBOOT_WDT_ENABLE
+ wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false);
+ uint32_t stage_timeout_ticks = (uint32_t)((uint64_t)CONFIG_BOOTLOADER_WDT_TIME_MS * rtc_clk_slow_freq_get_hz() / 1000);
+ wdt_hal_write_protect_disable(&rtc_wdt_ctx);
+ wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC);
+ wdt_hal_enable(&rtc_wdt_ctx);
+ wdt_hal_write_protect_enable(&rtc_wdt_ctx);
+#endif
+
+ wdt_hal_context_t wdt_ctx = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0};
+ wdt_hal_write_protect_disable(&wdt_ctx);
+ wdt_hal_set_flashboot_en(&wdt_ctx, false);
+ wdt_hal_write_protect_enable(&wdt_ctx);
+}
+
+static void bootloader_init_uart_console(void)
+{
+ const int uart_num = 0;
+
+ uartAttach(NULL);
+ ets_install_uart_printf();
+ uart_tx_wait_idle(0);
+
+ const int uart_baud = CONFIG_ESP_CONSOLE_UART_BAUDRATE;
+ uart_div_modify(uart_num, (rtc_clk_apb_freq_get() << 4) / uart_baud);
+}
+
+static void bootloader_super_wdt_auto_feed(void)
+{
+ REG_SET_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_AUTO_FEED_EN);
+}
+
+esp_err_t bootloader_init(void)
+{
+ esp_err_t ret = ESP_OK;
+ bootloader_super_wdt_auto_feed();
+
+ bootloader_init_mem();
+
+ /* check that static RAM is after the stack */
+#ifndef NDEBUG
+ {
+ assert(&_bss_start <= &_bss_end);
+ assert(&_data_start <= &_data_end);
+ }
+#endif
+ /* clear bss section */
+ bootloader_clear_bss_section();
+ /* reset MMU */
+ bootloader_reset_mmu();
+ /* config clock */
+ bootloader_clock_configure();
+ /* initialize uart console, from now on, we can use ets_printf */
+ bootloader_init_uart_console();
+ /* read bootloader header */
+ if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
+ goto err;
+ }
+ /* initialize spi flash */
+ if ((ret = bootloader_init_spi_flash()) != ESP_OK) {
+ goto err;
+ }
+ /* config WDT */
+ bootloader_config_wdt();
+err:
+ return ret;
+}
diff --git a/boot/espressif/hal/src/esp32s3/bootloader_init.c b/boot/espressif/hal/src/esp32s3/bootloader_init.c
new file mode 100644
index 0000000..c9d627a
--- /dev/null
+++ b/boot/espressif/hal/src/esp32s3/bootloader_init.c
@@ -0,0 +1,318 @@
+/*
+ * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "sdkconfig.h"
+#include "esp_attr.h"
+#include "esp_image_format.h"
+#include "flash_qio_mode.h"
+#include "esp_rom_efuse.h"
+#include "esp_rom_gpio.h"
+#include "esp_rom_sys.h"
+#include "esp_rom_uart.h"
+#include "esp_efuse.h"
+
+#include "bootloader_init.h"
+#include "bootloader_mem.h"
+#include "bootloader_clock.h"
+#include "bootloader_flash_config.h"
+#include "bootloader_flash.h"
+#include "bootloader_flash_priv.h"
+#include "bootloader_soc.h"
+
+#include "soc/cpu.h"
+#include "soc/dport_reg.h"
+#include "soc/efuse_reg.h"
+#include "soc/rtc.h"
+#include "soc/rtc_cntl_reg.h"
+#include "soc/extmem_reg.h"
+#include "soc/io_mux_reg.h"
+#include "soc/assist_debug_reg.h"
+
+#include "hal/wdt_hal.h"
+
+#include "esp32s3/rom/cache.h"
+#include "esp32s3/rom/ets_sys.h"
+#include "esp32s3/rom/spi_flash.h"
+#include "esp32s3/rom/uart.h"
+
+#include "esp_log.h"
+#include "mcuboot_config/mcuboot_config.h"
+
+static const char *TAG = "boot.esp32s3";
+
+esp_image_header_t WORD_ALIGNED_ATTR bootloader_image_hdr;
+
+void bootloader_clear_bss_section(void)
+{
+ memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start));
+}
+
+static void bootloader_reset_mmu(void)
+{
+ Cache_Suspend_DCache();
+ Cache_Invalidate_DCache_All();
+ Cache_MMU_Init();
+
+ REG_CLR_BIT(EXTMEM_ICACHE_CTRL1_REG, EXTMEM_ICACHE_SHUT_CORE0_BUS);
+ REG_CLR_BIT(EXTMEM_ICACHE_CTRL1_REG, EXTMEM_ICACHE_SHUT_CORE1_BUS);
+}
+
+esp_err_t bootloader_read_bootloader_header(void)
+{
+ if (bootloader_flash_read(ESP_BOOTLOADER_OFFSET, &bootloader_image_hdr, sizeof(esp_image_header_t), true) != ESP_OK) {
+ return ESP_FAIL;
+ }
+ return ESP_OK;
+}
+
+static void update_flash_config(const esp_image_header_t *bootloader_hdr)
+{
+ uint32_t size;
+ switch (bootloader_hdr->spi_size) {
+ case ESP_IMAGE_FLASH_SIZE_1MB:
+ size = 1;
+ break;
+ case ESP_IMAGE_FLASH_SIZE_2MB:
+ size = 2;
+ break;
+ case ESP_IMAGE_FLASH_SIZE_4MB:
+ size = 4;
+ break;
+ case ESP_IMAGE_FLASH_SIZE_8MB:
+ size = 8;
+ break;
+ case ESP_IMAGE_FLASH_SIZE_16MB:
+ size = 16;
+ break;
+ default:
+ size = 2;
+ }
+ uint32_t autoload = Cache_Suspend_DCache();
+ // Set flash chip size
+ esp_rom_spiflash_config_param(g_rom_flashchip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff);
+ Cache_Resume_DCache(autoload);
+}
+
+void IRAM_ATTR bootloader_configure_spi_pins(int drv)
+{
+ const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
+ uint8_t wp_pin = esp_rom_efuse_get_flash_wp_gpio();
+ uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM;
+ uint8_t q_gpio_num = SPI_Q_GPIO_NUM;
+ uint8_t d_gpio_num = SPI_D_GPIO_NUM;
+ uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM;
+ uint8_t hd_gpio_num = SPI_HD_GPIO_NUM;
+ uint8_t wp_gpio_num = SPI_WP_GPIO_NUM;
+ if (spiconfig == 0) {
+
+ } else {
+ clk_gpio_num = spiconfig & 0x3f;
+ q_gpio_num = (spiconfig >> 6) & 0x3f;
+ d_gpio_num = (spiconfig >> 12) & 0x3f;
+ cs0_gpio_num = (spiconfig >> 18) & 0x3f;
+ hd_gpio_num = (spiconfig >> 24) & 0x3f;
+ wp_gpio_num = wp_pin;
+ }
+ esp_rom_gpio_pad_set_drv(clk_gpio_num, drv);
+ esp_rom_gpio_pad_set_drv(q_gpio_num, drv);
+ esp_rom_gpio_pad_set_drv(d_gpio_num, drv);
+ esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv);
+ if (hd_gpio_num <= MAX_PAD_GPIO_NUM) {
+ esp_rom_gpio_pad_set_drv(hd_gpio_num, drv);
+ }
+ if (wp_gpio_num <= MAX_PAD_GPIO_NUM) {
+ esp_rom_gpio_pad_set_drv(wp_gpio_num, drv);
+ }
+}
+
+static void IRAM_ATTR bootloader_init_flash_configure(void)
+{
+ bootloader_flash_dummy_config(&bootloader_image_hdr);
+ bootloader_flash_cs_timing_config();
+}
+
+static esp_err_t bootloader_init_spi_flash(void)
+{
+ bootloader_init_flash_configure();
+#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
+ const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
+ if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) {
+ ESP_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig");
+ return ESP_FAIL;
+ }
+#endif
+
+ bootloader_flash_unlock();
+ update_flash_config(&bootloader_image_hdr);
+ //ensure the flash is write-protected
+ bootloader_enable_wp();
+ return ESP_OK;
+}
+
+void bootloader_config_wdt(void)
+{
+ wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL};
+ wdt_hal_write_protect_disable(&rtc_wdt_ctx);
+ wdt_hal_set_flashboot_en(&rtc_wdt_ctx, false);
+ wdt_hal_write_protect_enable(&rtc_wdt_ctx);
+
+#ifdef CONFIG_ESP_MCUBOOT_WDT_ENABLE
+ wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false);
+ uint32_t stage_timeout_ticks = (uint32_t)((uint64_t)CONFIG_BOOTLOADER_WDT_TIME_MS * rtc_clk_slow_freq_get_hz() / 1000);
+ wdt_hal_write_protect_disable(&rtc_wdt_ctx);
+ wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC);
+ wdt_hal_enable(&rtc_wdt_ctx);
+ wdt_hal_write_protect_enable(&rtc_wdt_ctx);
+#endif
+
+ wdt_hal_context_t wdt_ctx = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0};
+ wdt_hal_write_protect_disable(&wdt_ctx);
+ wdt_hal_set_flashboot_en(&wdt_ctx, false);
+ wdt_hal_write_protect_enable(&wdt_ctx);
+}
+
+static void bootloader_init_uart_console(void)
+{
+ const int uart_num = 0;
+
+ esp_rom_install_uart_printf();
+ esp_rom_uart_tx_wait_idle(0);
+ uint32_t clock_hz = UART_CLK_FREQ_ROM;
+ esp_rom_uart_set_clock_baudrate(uart_num, clock_hz, CONFIG_ESP_CONSOLE_UART_BAUDRATE);
+}
+
+static void wdt_reset_cpu0_info_enable(void)
+{
+ REG_SET_BIT(SYSTEM_CPU_PERI_CLK_EN_REG, SYSTEM_CLK_EN_ASSIST_DEBUG);
+ REG_CLR_BIT(SYSTEM_CPU_PERI_RST_EN_REG, SYSTEM_RST_EN_ASSIST_DEBUG);
+ REG_WRITE(ASSIST_DEBUG_CORE_0_RCD_PDEBUGENABLE_REG, 1);
+ REG_WRITE(ASSIST_DEBUG_CORE_0_RCD_RECORDING_REG, 1);
+}
+
+#if MCUBOOT_LOG_LEVEL >= MCUBOOT_LOG_LEVEL_DEBUG
+static void wdt_reset_info_dump(int cpu)
+{
+ uint32_t inst = 0, pid = 0, stat = 0, data = 0, pc = 0,
+ lsstat = 0, lsaddr = 0, lsdata = 0, dstat = 0;
+ const char *cpu_name = cpu ? "APP" : "PRO";
+
+ stat = 0xdeadbeef;
+ pid = 0;
+ if (cpu == 0) {
+ inst = REG_READ(ASSIST_DEBUG_CORE_0_RCD_PDEBUGINST_REG);
+ dstat = REG_READ(ASSIST_DEBUG_CORE_0_RCD_PDEBUGSTATUS_REG);
+ data = REG_READ(ASSIST_DEBUG_CORE_0_RCD_PDEBUGDATA_REG);
+ pc = REG_READ(ASSIST_DEBUG_CORE_0_RCD_PDEBUGPC_REG);
+ lsstat = REG_READ(ASSIST_DEBUG_CORE_0_RCD_PDEBUGLS0STAT_REG);
+ lsaddr = REG_READ(ASSIST_DEBUG_CORE_0_RCD_PDEBUGLS0ADDR_REG);
+ lsdata = REG_READ(ASSIST_DEBUG_CORE_0_RCD_PDEBUGLS0DATA_REG);
+ } else {
+ inst = REG_READ(ASSIST_DEBUG_CORE_1_RCD_PDEBUGINST_REG);
+ dstat = REG_READ(ASSIST_DEBUG_CORE_1_RCD_PDEBUGSTATUS_REG);
+ data = REG_READ(ASSIST_DEBUG_CORE_1_RCD_PDEBUGDATA_REG);
+ pc = REG_READ(ASSIST_DEBUG_CORE_1_RCD_PDEBUGPC_REG);
+ lsstat = REG_READ(ASSIST_DEBUG_CORE_1_RCD_PDEBUGLS0STAT_REG);
+ lsaddr = REG_READ(ASSIST_DEBUG_CORE_1_RCD_PDEBUGLS0ADDR_REG);
+ lsdata = REG_READ(ASSIST_DEBUG_CORE_1_RCD_PDEBUGLS0DATA_REG);
+ }
+
+ ESP_LOGD(TAG, "WDT reset info: %s CPU STATUS 0x%08x", cpu_name, stat);
+ ESP_LOGD(TAG, "WDT reset info: %s CPU PID 0x%08x", cpu_name, pid);
+ ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGINST 0x%08x", cpu_name, inst);
+ ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGSTATUS 0x%08x", cpu_name, dstat);
+ ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGDATA 0x%08x", cpu_name, data);
+ ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGPC 0x%08x", cpu_name, pc);
+ ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0STAT 0x%08x", cpu_name, lsstat);
+ ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0ADDR 0x%08x", cpu_name, lsaddr);
+ ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0DATA 0x%08x", cpu_name, lsdata);
+}
+#endif
+
+static void bootloader_check_wdt_reset(void)
+{
+ int wdt_rst = 0;
+ soc_reset_reason_t rst_reas[2];
+
+ rst_reas[0] = esp_rom_get_reset_reason(0);
+ rst_reas[1] = esp_rom_get_reset_reason(1);
+ if (rst_reas[0] == RESET_REASON_CORE_RTC_WDT || rst_reas[0] == RESET_REASON_CORE_MWDT0 || rst_reas[0] == RESET_REASON_CORE_MWDT1 ||
+ rst_reas[0] == RESET_REASON_CPU0_MWDT0 || rst_reas[0] == RESET_REASON_CPU0_RTC_WDT) {
+ ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
+ wdt_rst = 1;
+ }
+ if (rst_reas[1] == RESET_REASON_CORE_RTC_WDT || rst_reas[1] == RESET_REASON_CORE_MWDT0 || rst_reas[1] == RESET_REASON_CORE_MWDT1 ||
+ rst_reas[1] == RESET_REASON_CPU1_MWDT1 || rst_reas[1] == RESET_REASON_CPU1_RTC_WDT) {
+ ESP_LOGW(TAG, "APP CPU has been reset by WDT.");
+ wdt_rst = 1;
+ }
+ if (wdt_rst) {
+#if MCUBOOT_LOG_LEVEL >= MCUBOOT_LOG_LEVEL_DEBUG
+ // if reset by WDT dump info from trace port
+ wdt_reset_info_dump(0);
+ wdt_reset_info_dump(1);
+#endif
+ }
+ wdt_reset_cpu0_info_enable();
+}
+
+static void bootloader_super_wdt_auto_feed(void)
+{
+ REG_WRITE(RTC_CNTL_SWD_WPROTECT_REG, RTC_CNTL_SWD_WKEY_VALUE);
+ REG_SET_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_AUTO_FEED_EN);
+ REG_WRITE(RTC_CNTL_SWD_WPROTECT_REG, 0);}
+
+static inline void bootloader_ana_reset_config(void)
+{
+ //Enable WDT, BOR, and GLITCH reset
+ bootloader_ana_super_wdt_reset_config(true);
+ bootloader_ana_bod_reset_config(true);
+ bootloader_ana_clock_glitch_reset_config(true);
+}
+
+esp_err_t bootloader_init(void)
+{
+ esp_err_t ret = ESP_OK;
+ bootloader_ana_reset_config();
+ bootloader_super_wdt_auto_feed();
+ // protect memory region
+ bootloader_init_mem();
+ /* check that static RAM is after the stack */
+#ifndef NDEBUG
+ {
+ assert(&_bss_start <= &_bss_end);
+ assert(&_data_start <= &_data_end);
+ }
+#endif
+ // clear bss section
+ bootloader_clear_bss_section();
+ // reset MMU
+ bootloader_reset_mmu();
+ // config clock
+ bootloader_clock_configure();
+ /* initialize uart console, from now on, we can use ets_printf */
+ bootloader_init_uart_console();
+ // Check and run XMC startup flow
+ if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) {
+ goto err;
+ }
+ // read bootloader header
+ if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
+ goto err;
+ }
+ // initialize spi flash
+ if ((ret = bootloader_init_spi_flash()) != ESP_OK) {
+ goto err;
+ }
+ // check whether a WDT reset happend
+ bootloader_check_wdt_reset();
+ // config WDT
+ bootloader_config_wdt();
+
+err:
+ return ret;
+}
diff --git a/boot/espressif/hal/src/flash_encrypt.c b/boot/espressif/hal/src/flash_encrypt.c
new file mode 100644
index 0000000..143571b
--- /dev/null
+++ b/boot/espressif/hal/src/flash_encrypt.c
@@ -0,0 +1,351 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <strings.h>
+#include "bootloader_flash_priv.h"
+#include "bootloader_random.h"
+#include "esp_image_format.h"
+#include "esp_flash_encrypt.h"
+#include "esp_flash_partitions.h"
+#include "esp_secure_boot.h"
+#include "esp_efuse.h"
+#include "esp_efuse_table.h"
+#include "esp_log.h"
+#include "hal/wdt_hal.h"
+
+#include "esp_mcuboot_image.h"
+
+#if CONFIG_IDF_TARGET_ESP32
+#define CRYPT_CNT ESP_EFUSE_FLASH_CRYPT_CNT
+#define WR_DIS_CRYPT_CNT ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT
+#else
+#define CRYPT_CNT ESP_EFUSE_SPI_BOOT_CRYPT_CNT
+#define WR_DIS_CRYPT_CNT ESP_EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT
+#endif
+
+/* This file implements FLASH ENCRYPTION related APIs to perform
+ * various operations such as programming necessary flash encryption
+ * eFuses, detect whether flash encryption is enabled (by reading eFuse)
+ * and if required encrypt the partitions in flash memory
+ */
+
+static const char *TAG = "flash_encrypt";
+
+/* Static functions for stages of flash encryption */
+static esp_err_t initialise_flash_encryption(void);
+static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_crypt_wr_dis) __attribute__((unused));
+static esp_err_t encrypt_bootloader(void);
+static esp_err_t encrypt_primary_slot(void);
+
+esp_err_t esp_flash_encrypt_check_and_update(void)
+{
+ size_t flash_crypt_cnt = 0;
+ esp_efuse_read_field_cnt(CRYPT_CNT, &flash_crypt_cnt);
+ bool flash_crypt_wr_dis = esp_efuse_read_field_bit(WR_DIS_CRYPT_CNT);
+
+ ESP_LOGV(TAG, "CRYPT_CNT %d, write protection %d", flash_crypt_cnt, flash_crypt_wr_dis);
+
+ if (flash_crypt_cnt % 2 == 1) {
+ /* Flash is already encrypted */
+ int left = (CRYPT_CNT[0]->bit_count - flash_crypt_cnt) / 2;
+ if (flash_crypt_wr_dis) {
+ left = 0; /* can't update FLASH_CRYPT_CNT, no more flashes */
+ }
+ ESP_LOGI(TAG, "flash encryption is enabled (%d plaintext flashes left)", left);
+ return ESP_OK;
+ } else {
+#ifndef CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED
+ /* Flash is not encrypted, so encrypt it! */
+ return encrypt_flash_contents(flash_crypt_cnt, flash_crypt_wr_dis);
+#else
+ ESP_LOGE(TAG, "flash encryption is not enabled, and SECURE_FLASH_REQUIRE_ALREADY_ENABLED "
+ "is set, refusing to boot.");
+ return ESP_ERR_INVALID_STATE;
+#endif // CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED
+ }
+}
+
+static esp_err_t check_and_generate_encryption_keys(void)
+{
+ size_t key_size = 32;
+#ifdef CONFIG_IDF_TARGET_ESP32
+ enum { BLOCKS_NEEDED = 1 };
+ esp_efuse_purpose_t purposes[BLOCKS_NEEDED] = {
+ ESP_EFUSE_KEY_PURPOSE_FLASH_ENCRYPTION,
+ };
+ esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK_ENCRYPT_FLASH);
+ if (coding_scheme != EFUSE_CODING_SCHEME_NONE && coding_scheme != EFUSE_CODING_SCHEME_3_4) {
+ ESP_LOGE(TAG, "Unknown/unsupported CODING_SCHEME value 0x%x", coding_scheme);
+ return ESP_ERR_NOT_SUPPORTED;
+ }
+ if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
+ key_size = 24;
+ }
+#else
+#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_AES256
+ enum { BLOCKS_NEEDED = 2 };
+ esp_efuse_purpose_t purposes[BLOCKS_NEEDED] = {
+ ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1,
+ ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2,
+ };
+ if (esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY, NULL)) {
+ ESP_LOGE(TAG, "XTS_AES_128_KEY is already in use, XTS_AES_256_KEY_1/2 can not be used");
+ return ESP_ERR_INVALID_STATE;
+ }
+#else
+ enum { BLOCKS_NEEDED = 1 };
+ esp_efuse_purpose_t purposes[BLOCKS_NEEDED] = {
+ ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY,
+ };
+#endif // CONFIG_SECURE_FLASH_ENCRYPTION_AES256
+#endif // CONFIG_IDF_TARGET_ESP32
+
+ /* Initialize all efuse block entries to invalid (max) value */
+ esp_efuse_block_t blocks[BLOCKS_NEEDED] = {[0 ... BLOCKS_NEEDED-1] = EFUSE_BLK_KEY_MAX};
+ bool has_key = true;
+ for (unsigned i = 0; i < BLOCKS_NEEDED; i++) {
+ bool tmp_has_key = esp_efuse_find_purpose(purposes[i], &blocks[i]);
+ if (tmp_has_key) { // For ESP32: esp_efuse_find_purpose() always returns True, need to check whether the key block is used or not.
+ tmp_has_key &= !esp_efuse_key_block_unused(blocks[i]);
+ }
+ if (i == 1 && tmp_has_key != has_key) {
+ ESP_LOGE(TAG, "Invalid efuse key blocks: Both AES-256 key blocks must be set.");
+ return ESP_ERR_INVALID_STATE;
+ }
+ has_key &= tmp_has_key;
+ }
+
+ if (!has_key) {
+ /* Generate key */
+ uint8_t keys[BLOCKS_NEEDED][32] = { 0 };
+ ESP_LOGI(TAG, "Generating new flash encryption key...");
+ for (unsigned i = 0; i < BLOCKS_NEEDED; ++i) {
+ bootloader_fill_random(keys[i], key_size);
+ }
+ ESP_LOGD(TAG, "Key generation complete");
+
+ esp_err_t err = esp_efuse_write_keys(purposes, keys, BLOCKS_NEEDED);
+ if (err != ESP_OK) {
+ if (err == ESP_ERR_NOT_ENOUGH_UNUSED_KEY_BLOCKS) {
+ ESP_LOGE(TAG, "Not enough free efuse key blocks (need %d) to continue", BLOCKS_NEEDED);
+ } else {
+ ESP_LOGE(TAG, "Failed to write efuse block with purpose (err=0x%x). Can't continue.", err);
+ }
+ return err;
+ }
+ } else {
+ for (unsigned i = 0; i < BLOCKS_NEEDED; i++) {
+ if (!esp_efuse_get_key_dis_write(blocks[i])
+ || !esp_efuse_get_key_dis_read(blocks[i])
+ || !esp_efuse_get_keypurpose_dis_write(blocks[i])) { // For ESP32: no keypurpose, it returns always True.
+ ESP_LOGE(TAG, "Invalid key state, check read&write protection for key and keypurpose(if exists)");
+ return ESP_ERR_INVALID_STATE;
+ }
+ }
+ ESP_LOGI(TAG, "Using pre-loaded flash encryption key in efuse");
+ }
+ return ESP_OK;
+}
+
+static esp_err_t initialise_flash_encryption(void)
+{
+ esp_efuse_batch_write_begin(); /* Batch all efuse writes at the end of this function */
+
+ /* Before first flash encryption pass, need to initialise key & crypto config */
+ esp_err_t err = check_and_generate_encryption_keys();
+ if (err != ESP_OK) {
+ esp_efuse_batch_write_cancel();
+ return err;
+ }
+
+ err = esp_flash_encryption_enable_secure_features();
+ if (err != ESP_OK) {
+ esp_efuse_batch_write_cancel();
+ return err;
+ }
+
+ err = esp_efuse_batch_write_commit();
+ if (err != ESP_OK) {
+ ESP_LOGE(TAG, "Error programming security eFuses (err=0x%x).", err);
+ return err;
+ }
+
+ return ESP_OK;
+}
+
+/* Encrypt all flash data that should be encrypted */
+static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_crypt_wr_dis)
+{
+ esp_err_t err;
+
+ /* If all flash_crypt_cnt bits are burned or write-disabled, the
+ device can't re-encrypt itself. */
+ if (flash_crypt_wr_dis || flash_crypt_cnt == CRYPT_CNT[0]->bit_count) {
+ ESP_LOGE(TAG, "Cannot re-encrypt data CRYPT_CNT %d write disabled %d", flash_crypt_cnt, flash_crypt_wr_dis);
+ return ESP_FAIL;
+ }
+
+ if (flash_crypt_cnt == 0) {
+ /* Very first flash of encrypted data: generate keys, etc. */
+ err = initialise_flash_encryption();
+ if (err != ESP_OK) {
+ return err;
+ }
+ }
+
+ err = encrypt_bootloader();
+ if (err != ESP_OK) {
+ return err;
+ }
+
+ /* If the primary slot executable application is not encrypted,
+ * then encrypt it
+ */
+ err = encrypt_primary_slot();
+ if (err != ESP_OK) {
+ return err;
+ }
+
+ /* Unconditionally encrypts remaining regions
+ * This will need changes when implementing multi-slot support
+ */
+ ESP_LOGI(TAG, "Encrypting remaining flash...");
+ uint32_t region_addr = CONFIG_ESP_APPLICATION_SECONDARY_START_ADDRESS;
+ size_t region_size = CONFIG_ESP_APPLICATION_SIZE;
+ err = esp_flash_encrypt_region(region_addr, region_size);
+ if (err != ESP_OK) {
+ return err;
+ }
+ region_addr = CONFIG_ESP_SCRATCH_OFFSET;
+ region_size = CONFIG_ESP_SCRATCH_SIZE;
+ err = esp_flash_encrypt_region(region_addr, region_size);
+ if (err != ESP_OK) {
+ return err;
+ }
+
+#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE
+ // Go straight to max, permanently enabled
+ ESP_LOGI(TAG, "Setting CRYPT_CNT for permanent encryption");
+ size_t new_flash_crypt_cnt = CRYPT_CNT[0]->bit_count - flash_crypt_cnt;
+#else
+ /* Set least significant 0-bit in flash_crypt_cnt */
+ size_t new_flash_crypt_cnt = 1;
+#endif
+ ESP_LOGD(TAG, "CRYPT_CNT %d -> %d", flash_crypt_cnt, new_flash_crypt_cnt);
+ err = esp_efuse_write_field_cnt(CRYPT_CNT, new_flash_crypt_cnt);
+
+ ESP_LOGI(TAG, "Flash encryption completed");
+
+ return ESP_OK;
+}
+
+static esp_err_t encrypt_bootloader(void)
+{
+ esp_err_t err;
+ uint32_t image_length;
+ /* Check for plaintext bootloader (verification will fail if it's already encrypted) */
+ if (esp_image_verify_bootloader(&image_length) == ESP_OK) {
+ ESP_LOGI(TAG, "Encrypting bootloader...");
+
+ err = esp_flash_encrypt_region(ESP_BOOTLOADER_OFFSET, CONFIG_ESP_BOOTLOADER_SIZE);
+ if (err != ESP_OK) {
+ ESP_LOGE(TAG, "Failed to encrypt bootloader in place: 0x%x", err);
+ return err;
+ }
+ ESP_LOGI(TAG, "Bootloader encrypted successfully");
+ } else {
+ ESP_LOGW(TAG, "No valid bootloader was found");
+ return ESP_ERR_NOT_FOUND;
+ }
+
+ return ESP_OK;
+}
+
+static esp_err_t verify_img_header(uint32_t addr, const esp_image_load_header_t *image, bool silent)
+{
+ esp_err_t err = ESP_OK;
+
+ if (image->header_magic != ESP_LOAD_HEADER_MAGIC) {
+ if (!silent) {
+ ESP_LOGE(TAG, "image at 0x%x has invalid magic byte",
+ addr);
+ }
+ err = ESP_ERR_IMAGE_INVALID;
+ }
+
+ return err;
+}
+
+static esp_err_t encrypt_primary_slot(void)
+{
+ esp_err_t err;
+
+ esp_image_load_header_t img_header;
+
+ /* Check if the slot is plaintext or encrypted, 0x20 offset is for skipping
+ * MCUboot header
+ */
+ err = bootloader_flash_read(CONFIG_ESP_APPLICATION_PRIMARY_START_ADDRESS + 0x20,
+ &img_header, sizeof(esp_image_load_header_t), true);
+ if (err != ESP_OK) {
+ ESP_LOGE(TAG, "Failed to read slot img header");
+ return err;
+ } else {
+ err = verify_img_header(CONFIG_ESP_APPLICATION_PRIMARY_START_ADDRESS,
+ &img_header, true);
+ }
+
+ if (err == ESP_OK) {
+ ESP_LOGI(TAG, "Encrypting primary slot...");
+
+ err = esp_flash_encrypt_region(CONFIG_ESP_APPLICATION_PRIMARY_START_ADDRESS,
+ CONFIG_ESP_APPLICATION_SIZE);
+ if (err != ESP_OK) {
+ ESP_LOGE(TAG, "Failed to encrypt slot in place: 0x%x", err);
+ return err;
+ }
+ } else {
+ ESP_LOGW(TAG, "Slot already encrypted or no valid image was found");
+ }
+
+ return ESP_OK;
+}
+
+esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length)
+{
+ esp_err_t err;
+ uint32_t buf[FLASH_SECTOR_SIZE / sizeof(uint32_t)];
+
+ if (src_addr % FLASH_SECTOR_SIZE != 0) {
+ ESP_LOGE(TAG, "esp_flash_encrypt_region bad src_addr 0x%x", src_addr);
+ return ESP_FAIL;
+ }
+
+ wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL};
+ for (size_t i = 0; i < data_length; i += FLASH_SECTOR_SIZE) {
+ wdt_hal_write_protect_disable(&rtc_wdt_ctx);
+ wdt_hal_feed(&rtc_wdt_ctx);
+ wdt_hal_write_protect_enable(&rtc_wdt_ctx);
+ uint32_t sec_start = i + src_addr;
+ err = bootloader_flash_read(sec_start, buf, FLASH_SECTOR_SIZE, true);
+ if (err != ESP_OK) {
+ goto flash_failed;
+ }
+ err = bootloader_flash_erase_sector(sec_start / FLASH_SECTOR_SIZE);
+ if (err != ESP_OK) {
+ goto flash_failed;
+ }
+ err = bootloader_flash_write(sec_start, buf, FLASH_SECTOR_SIZE, true);
+ if (err != ESP_OK) {
+ goto flash_failed;
+ }
+ }
+ return ESP_OK;
+
+flash_failed:
+ ESP_LOGE(TAG, "flash operation failed: 0x%x", err);
+ return err;
+}
diff --git a/boot/espressif/hal/src/secure_boot.c b/boot/espressif/hal/src/secure_boot.c
new file mode 100644
index 0000000..9cb24be
--- /dev/null
+++ b/boot/espressif/hal/src/secure_boot.c
@@ -0,0 +1,248 @@
+/*
+ * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <string.h>
+#include "sdkconfig.h"
+#include "esp_log.h"
+#include "esp_secure_boot.h"
+#include "bootloader_flash_priv.h"
+#include "bootloader_sha.h"
+#include "bootloader_utility.h"
+#include "esp_image_format.h"
+#include "esp_efuse.h"
+#include "esp_efuse_table.h"
+
+/* The following API implementations are used only when called
+ * from the bootloader code.
+ */
+
+#ifdef CONFIG_SECURE_BOOT_V2_ENABLED
+
+#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
+static const char *TAG = "secure_boot_v2";
+
+/* A signature block is valid when it has correct magic byte, crc and image digest. */
+static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *block, int block_num, const uint8_t *image_digest)
+{
+ if (block->magic_byte != ETS_SECURE_BOOT_V2_SIGNATURE_MAGIC) {
+ // All signature blocks have been parsed, no new signature block present.
+ ESP_LOGD(TAG, "Signature block(%d) invalid/absent.", block_num);
+ return ESP_FAIL;
+ }
+ if (block->block_crc != esp_rom_crc32_le(0, (uint8_t *)block, CRC_SIGN_BLOCK_LEN)) {
+ ESP_LOGE(TAG, "Magic byte correct but incorrect crc.");
+ return ESP_FAIL;
+ }
+ if (memcmp(image_digest, block->image_digest, ESP_SECURE_BOOT_DIGEST_LEN)) {
+ ESP_LOGE(TAG, "Magic byte & CRC correct but incorrect image digest.");
+ return ESP_FAIL;
+ } else {
+ ESP_LOGD(TAG, "valid signature block(%d) found", block_num);
+ return ESP_OK;
+ }
+ return ESP_FAIL;
+}
+
+/* Generates the public key digests of the valid public keys in an image's
+ signature block, verifies each signature, and stores the key digests in the
+ public_key_digests structure.
+
+ @param flash_offset Image offset in flash
+ @param flash_size Image size in flash (not including signature block)
+ @param[out] public_key_digests Pointer to structure to hold the key digests for valid sig blocks
+
+
+ Note that this function doesn't read any eFuses, so it doesn't know if the
+ keys are ultimately trusted by the hardware or not
+
+ @return - ESP_OK if no signatures failed to verify, or if no valid signature blocks are found at all.
+ - ESP_FAIL if there's a valid signature block that doesn't verify using the included public key (unexpected!)
+*/
+static esp_err_t s_calculate_image_public_key_digests(uint32_t flash_offset, uint32_t flash_size, esp_image_sig_public_key_digests_t *public_key_digests)
+{
+ esp_err_t ret;
+ uint8_t image_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
+ uint8_t __attribute__((aligned(4))) key_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
+ size_t sig_block_addr = flash_offset + ALIGN_UP(flash_size, FLASH_SECTOR_SIZE);
+
+ ESP_LOGD(TAG, "calculating public key digests for sig blocks of image offset 0x%x (sig block offset 0x%x)", flash_offset, sig_block_addr);
+
+ bzero(public_key_digests, sizeof(esp_image_sig_public_key_digests_t));
+
+ ret = bootloader_sha256_flash_contents(flash_offset, sig_block_addr - flash_offset, image_digest);
+ if (ret != ESP_OK) {
+ ESP_LOGE(TAG, "error generating image digest, %d", ret);
+ return ret;
+ }
+
+ ESP_LOGD(TAG, "reading signature(s)");
+ const ets_secure_boot_signature_t *signatures = bootloader_mmap(sig_block_addr, sizeof(ets_secure_boot_signature_t));
+ if (signatures == NULL) {
+ ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", sig_block_addr, sizeof(ets_secure_boot_signature_t));
+ return ESP_FAIL;
+ }
+
+ /* Validating Signature block */
+ for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
+ const ets_secure_boot_sig_block_t *block = &signatures->block[i];
+
+ ret = validate_signature_block(block, i, image_digest);
+ if (ret != ESP_OK) {
+ ret = ESP_OK; // past the last valid signature block
+ break;
+ }
+
+ /* Generating the SHA of the public key components in the signature block */
+ bootloader_sha256_handle_t sig_block_sha;
+ sig_block_sha = bootloader_sha256_start();
+ bootloader_sha256_data(sig_block_sha, &block->key, sizeof(block->key));
+ bootloader_sha256_finish(sig_block_sha, key_digest);
+
+ // Check we can verify the image using this signature and this key
+ uint8_t temp_verified_digest[ESP_SECURE_BOOT_DIGEST_LEN];
+ bool verified = ets_rsa_pss_verify(&block->key, block->signature, image_digest, temp_verified_digest);
+
+ if (!verified) {
+ /* We don't expect this: the signature blocks before we enable secure boot should all be verifiable or invalid,
+ so this is a fatal error
+ */
+ ret = ESP_FAIL;
+ ESP_LOGE(TAG, "Secure boot key (%d) verification failed.", i);
+ break;
+ }
+ ESP_LOGD(TAG, "Signature block (%d) is verified", i);
+ /* Copy the key digest to the buffer provided by the caller */
+ memcpy((void *)public_key_digests->key_digests[i], key_digest, ESP_SECURE_BOOT_DIGEST_LEN);
+ public_key_digests->num_digests++;
+ }
+
+ if (ret == ESP_OK && public_key_digests->num_digests > 0) {
+ ESP_LOGI(TAG, "Digests successfully calculated, %d valid signatures (image offset 0x%x)",
+ public_key_digests->num_digests, flash_offset);
+ }
+
+ bootloader_munmap(signatures);
+ return ret;
+}
+
+esp_err_t check_and_generate_secure_boot_keys(void)
+{
+ esp_err_t ret;
+#ifdef CONFIG_IDF_TARGET_ESP32
+ esp_efuse_purpose_t secure_boot_key_purpose[SECURE_BOOT_NUM_BLOCKS] = {
+ ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2,
+ };
+ esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK_SECURE_BOOT);
+ if (coding_scheme != EFUSE_CODING_SCHEME_NONE) {
+ ESP_LOGE(TAG, "No coding schemes are supported in secure boot v2.(Detected scheme: 0x%x)", coding_scheme);
+ return ESP_ERR_NOT_SUPPORTED;
+ }
+#else
+ esp_efuse_purpose_t secure_boot_key_purpose[SECURE_BOOT_NUM_BLOCKS] = {
+ ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0,
+ ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1,
+ ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2,
+ };
+#endif // CONFIG_IDF_TARGET_ESP32
+
+ /* Verify the bootloader */
+ esp_image_metadata_t bootloader_data = { 0 };
+ ret = esp_image_verify_bootloader_data(&bootloader_data);
+ if (ret != ESP_OK) {
+ ESP_LOGE(TAG, "bootloader image appears invalid! error %d", ret);
+ return ret;
+ }
+
+ /* Initialize all efuse block entries to invalid (max) value */
+ esp_efuse_block_t blocks[SECURE_BOOT_NUM_BLOCKS] = {[0 ... SECURE_BOOT_NUM_BLOCKS-1] = EFUSE_BLK_KEY_MAX};
+ /* Check if secure boot digests are present */
+ bool has_secure_boot_digest = false;
+ for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
+ bool tmp_has_key = esp_efuse_find_purpose(secure_boot_key_purpose[i], &blocks[i]);
+ if (tmp_has_key) { // For ESP32: esp_efuse_find_purpose() always returns True, need to check whether the key block is used or not.
+ tmp_has_key &= !esp_efuse_key_block_unused(blocks[i]);
+ }
+ has_secure_boot_digest |= tmp_has_key;
+ }
+
+ esp_image_sig_public_key_digests_t boot_key_digests = {0};
+ ESP_LOGI(TAG, "Secure boot digests %s", has_secure_boot_digest ? "already present":"absent, generating..");
+
+ if (!has_secure_boot_digest) {
+ /* Generate the bootloader public key digests */
+ ret = s_calculate_image_public_key_digests(bootloader_data.start_addr, bootloader_data.image_len - SIG_BLOCK_PADDING, &boot_key_digests);
+ if (ret != ESP_OK) {
+ ESP_LOGE(TAG, "Bootloader signature block is invalid");
+ return ret;
+ }
+
+ if (boot_key_digests.num_digests == 0) {
+ ESP_LOGE(TAG, "No valid bootloader signature blocks found.");
+ return ESP_FAIL;
+ }
+ ESP_LOGI(TAG, "%d signature block(s) found appended to the bootloader.", boot_key_digests.num_digests);
+
+ ESP_LOGI(TAG, "Burning public key hash to eFuse");
+ ret = esp_efuse_write_keys(secure_boot_key_purpose, boot_key_digests.key_digests, boot_key_digests.num_digests);
+ if (ret != ESP_OK) {
+ if (ret == ESP_ERR_NOT_ENOUGH_UNUSED_KEY_BLOCKS) {
+ ESP_LOGE(TAG, "Bootloader signatures(%d) more than available key slots.", boot_key_digests.num_digests);
+ } else {
+ ESP_LOGE(TAG, "Failed to write efuse block with purpose (err=0x%x). Can't continue.", ret);
+ }
+ return ret;
+ }
+ } else {
+ for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
+ /* Check if corresponding digest slot is used or not */
+ if (blocks[i] == EFUSE_BLK_KEY_MAX) {
+ ESP_LOGD(TAG, "SECURE_BOOT_DIGEST%d slot is not used", i);
+ continue;
+ }
+
+#if SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
+ if (esp_efuse_get_digest_revoke(i)) {
+ continue;
+ }
+#endif
+ if (esp_efuse_get_key_dis_read(blocks[i])) {
+ ESP_LOGE(TAG, "Key digest (BLK%d) read protected, aborting...", blocks[i]);
+ return ESP_FAIL;
+ }
+ if (esp_efuse_block_is_empty(blocks[i])) {
+ ESP_LOGE(TAG, "%d eFuse block is empty, aborting...", blocks[i]);
+ return ESP_FAIL;
+ }
+ esp_efuse_set_key_dis_write(blocks[i]);
+ ret = esp_efuse_read_block(blocks[i], boot_key_digests.key_digests[boot_key_digests.num_digests], 0,
+ sizeof(boot_key_digests.key_digests[0]) * 8);
+ if (ret) {
+ ESP_LOGE(TAG, "Error during reading %d eFuse block (err=0x%x)", blocks[i], ret);
+ return ret;
+ }
+ boot_key_digests.num_digests++;
+ }
+ if (boot_key_digests.num_digests == 0) {
+ ESP_LOGE(TAG, "No valid pre-loaded public key digest in eFuse");
+ return ESP_FAIL;
+ }
+ ESP_LOGW(TAG, "Using pre-loaded public key digest in eFuse");
+ }
+
+#if SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
+ /* Revoke the empty signature blocks */
+ if (boot_key_digests.num_digests < SECURE_BOOT_NUM_BLOCKS) {
+ /* The revocation index can be 0, 1, 2. Bootloader count can be 1,2,3. */
+ for (unsigned i = boot_key_digests.num_digests; i < SECURE_BOOT_NUM_BLOCKS; i++) {
+ ESP_LOGI(TAG, "Revoking empty key digest slot (%d)...", i);
+ esp_efuse_set_digest_revoke(i);
+ }
+ }
+#endif // SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
+ return ESP_OK;
+}
+
+#endif // CONFIG_SECURE_BOOT_V2_ENABLED