diff --git a/components/bootloader/subproject/main/CMakeLists.txt b/components/bootloader/subproject/main/CMakeLists.txt index 651a94468d..c5db5363f6 100644 --- a/components/bootloader/subproject/main/CMakeLists.txt +++ b/components/bootloader/subproject/main/CMakeLists.txt @@ -4,7 +4,7 @@ idf_component_register(SRCS "bootloader_start.c" idf_build_get_property(target IDF_TARGET) set(scripts "ld/${target}/bootloader.ld") -if(NOT CONFIG_IDF_TARGET_ESP32C3) +if(NOT CONFIG_IDF_TARGET_ESP32C3 AND NOT CONFIG_IDF_TARGET_ESP32H2) list(APPEND scripts "ld/${target}/bootloader.rom.ld") endif() diff --git a/components/bootloader/subproject/main/ld/esp32h2/bootloader.ld b/components/bootloader/subproject/main/ld/esp32h2/bootloader.ld new file mode 100644 index 0000000000..d016cd30df --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32h2/bootloader.ld @@ -0,0 +1,190 @@ +/** Simplified memory map for the bootloader. + * Make sure the bootloader can load into main memory without overwriting itself. + * We put 2nd bootloader in the high address space (before ROM stack/data/bss). + * See memory usage for ROM bootloader at the end of this file. + */ + +MEMORY +{ + iram_seg (RWX) : org = 0x403CE000, len = 0x2000 + iram_loader_seg (RWX) : org = 0x403D0000, len = 0x6000 + dram_seg (RW) : org = 0x3FCD6000, len = 0x4000 +} + +/* Default entry point: */ +ENTRY(call_start_cpu0); + +SECTIONS +{ + + .iram_loader.text : + { + . = ALIGN (16); + _loader_text_start = ABSOLUTE(.); + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ + *liblog.a:(.literal .text .literal.* .text.*) + *libgcc.a:(.literal .text .literal.* .text.*) + *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) + *libbootloader_support.a:bootloader_efuse_esp32h2.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) + *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) + *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) + *libspi_flash.a:*.*(.literal .text .literal.* .text.*) + *libhal.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) + *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) + *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) + *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) + *libefuse.a:*.*(.literal .text .literal.* .text.*) + *(.fini.literal) + *(.fini) + *(.gnu.version) + _loader_text_end = ABSOLUTE(.); + } > iram_loader_seg + + .iram.text : + { + . = ALIGN (16); + *(.entry.text) + *(.init.literal) + *(.init) + } > iram_seg + + + /* Shared RAM */ + .dram0.bss (NOLOAD) : + { + . = ALIGN (8); + _dram_start = ABSOLUTE(.); + _bss_start = ABSOLUTE(.); + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + _bss_end = ABSOLUTE(.); + } > dram_seg + + .dram0.data : + { + _data_start = ABSOLUTE(.); + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + *(.data1) + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + *(.jcr) + _data_end = ABSOLUTE(.); + } > dram_seg + + .dram0.rodata : + { + _rodata_start = ABSOLUTE(.); + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + *(.rodata1) + __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); + *(.xt_except_table) + *(.gcc_except_table) + *(.gnu.linkonce.e.*) + *(.gnu.version_r) + *(.eh_frame) + . = (. + 3) & ~ 3; + /* C++ constructor and destructor tables, properly ordered: */ + __init_array_start = ABSOLUTE(.); + KEEP (*crtbegin.*(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __init_array_end = ABSOLUTE(.); + KEEP (*crtbegin.*(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + /* C++ exception handlers table: */ + __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); + *(.xt_except_desc) + *(.gnu.linkonce.h.*) + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); + *(.xt_except_desc_end) + *(.dynamic) + *(.gnu.version_d) + _rodata_end = ABSOLUTE(.); + /* Literals are also RO data. */ + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + . = ALIGN(4); + _dram_end = ABSOLUTE(.); + } > dram_seg + + .iram.text : + { + _stext = .; + _text_start = ABSOLUTE(.); + *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.iram .iram.*) /* catch stray IRAM_ATTR */ + *(.fini.literal) + *(.fini) + *(.gnu.version) + + /** CPU will try to prefetch up to 16 bytes of + * of instructions. This means that any configuration (e.g. MMU, PMS) must allow + * safe access to up to 16 bytes after the last real instruction, add + * dummy bytes to ensure this + */ + . += 16; + + _text_end = ABSOLUTE(.); + _etext = .; + } > iram_seg + +} + + +/** + * Appendix: Memory Usage of ROM bootloader + * + * +--------+--------------+------+ 0x3FCC_B000 + * | ^ | + * | | | + * | | data/bss | + * | | | + * | v | + * +------------------------------+ 0x3FCD_C910 + * | ^ | + * | | | + * | | stack | + * | | | + * | v | + * +------------------------------+ 0x3FCD_E910 + */ diff --git a/components/bootloader_support/include/bootloader_common.h b/components/bootloader_support/include/bootloader_common.h index 4d50649e01..3fb97c65fc 100644 --- a/components/bootloader_support/include/bootloader_common.h +++ b/components/bootloader_support/include/bootloader_common.h @@ -17,6 +17,8 @@ #include "esp32s3/rom/rtc.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rom/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/rtc.h" #endif #ifdef __cplusplus diff --git a/components/bootloader_support/include/esp_app_format.h b/components/bootloader_support/include/esp_app_format.h index 6390855b56..5ff4770d21 100644 --- a/components/bootloader_support/include/esp_app_format.h +++ b/components/bootloader_support/include/esp_app_format.h @@ -16,6 +16,7 @@ typedef enum { ESP_CHIP_ID_ESP32S2 = 0x0002, /*!< chip ID: ESP32-S2 */ ESP_CHIP_ID_ESP32C3 = 0x0005, /*!< chip ID: ESP32-C3 */ ESP_CHIP_ID_ESP32S3 = 0x0009, /*!< chip ID: ESP32-S3 */ + ESP_CHIP_ID_ESP32H2 = 0x000A, /*!< chip ID: ESP32-H2 */ ESP_CHIP_ID_INVALID = 0xFFFF /*!< Invalid chip ID (we defined it to make sure the esp_chip_id_t is 2 bytes size) */ } __attribute__((packed)) esp_chip_id_t; diff --git a/components/bootloader_support/include/esp_secure_boot.h b/components/bootloader_support/include/esp_secure_boot.h index 3e78978ff6..9bb8dfec0b 100644 --- a/components/bootloader_support/include/esp_secure_boot.h +++ b/components/bootloader_support/include/esp_secure_boot.h @@ -25,6 +25,9 @@ #elif CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/rom/efuse.h" #include "esp32s3/rom/secure_boot.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/efuse.h" +#include "esp32h2/rom/secure_boot.h" #endif #ifdef CONFIG_SECURE_BOOT_V1_ENABLED diff --git a/components/bootloader_support/src/bootloader_clock_init.c b/components/bootloader_support/src/bootloader_clock_init.c index f798ebc68b..fdeeafbd9c 100644 --- a/components/bootloader_support/src/bootloader_clock_init.c +++ b/components/bootloader_support/src/bootloader_clock_init.c @@ -22,6 +22,8 @@ #include "esp32s3/rom/rtc.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rom/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/rtc.h" #endif #include "esp_rom_uart.h" diff --git a/components/bootloader_support/src/bootloader_common.c b/components/bootloader_support/src/bootloader_common.c index 518946fdd8..f8541add5e 100644 --- a/components/bootloader_support/src/bootloader_common.c +++ b/components/bootloader_support/src/bootloader_common.c @@ -17,6 +17,8 @@ #include "esp32s3/rom/spi_flash.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/spi_flash.h" #endif #include "esp_rom_crc.h" #include "esp_rom_gpio.h" diff --git a/components/bootloader_support/src/bootloader_console.c b/components/bootloader_support/src/bootloader_console.c index 2c1e4dc103..78152b6647 100644 --- a/components/bootloader_support/src/bootloader_console.c +++ b/components/bootloader_support/src/bootloader_console.c @@ -22,6 +22,9 @@ #include "esp32c3/rom/uart.h" #elif CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/rom/uart.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/ets_sys.h" +#include "esp32h2/rom/uart.h" #endif #include "esp_rom_gpio.h" #include "esp_rom_uart.h" diff --git a/components/bootloader_support/src/bootloader_efuse_esp32h2.c b/components/bootloader_support/src/bootloader_efuse_esp32h2.c new file mode 100644 index 0000000000..aa59b5e60f --- /dev/null +++ b/components/bootloader_support/src/bootloader_efuse_esp32h2.c @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "soc/efuse_reg.h" + +uint8_t bootloader_common_get_chip_revision(void) +{ + // should return the same value as esp_efuse_get_chip_ver() + return REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_WAFER_VERSION); +} + +uint32_t bootloader_common_get_chip_ver_pkg(void) +{ + // should return the same value as esp_efuse_get_pkg_ver() + return REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_PKG_VERSION); +} diff --git a/components/bootloader_support/src/bootloader_flash.c b/components/bootloader_support/src/bootloader_flash.c index cdabafb128..8f3ac2bf91 100644 --- a/components/bootloader_support/src/bootloader_flash.c +++ b/components/bootloader_support/src/bootloader_flash.c @@ -29,6 +29,8 @@ #include "esp32s3/rom/spi_flash.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/spi_flash.h" #endif #ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH @@ -124,6 +126,10 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size) #include "esp32c3/rom/spi_flash.h" #include "esp32c3/rom/cache.h" #include "soc/cache_memory.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/spi_flash.h" +#include "esp32h2/rom/cache.h" +#include "soc/cache_memory.h" #endif static const char *TAG = "bootloader_flash"; @@ -188,6 +194,9 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size) #elif CONFIG_IDF_TARGET_ESP32C3 uint32_t autoload = Cache_Suspend_ICache(); Cache_Invalidate_ICache_All(); +#elif CONFIG_IDF_TARGET_ESP32H2 + uint32_t autoload = Cache_Suspend_ICache(); + Cache_Invalidate_ICache_All(); #endif ESP_LOGD(TAG, "mmu set paddr=%08x count=%d size=%x src_addr=%x src_addr_aligned=%x", src_addr & MMU_FLASH_MASK, count, size, src_addr, src_addr_aligned ); @@ -195,7 +204,7 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size) int e = cache_flash_mmu_set(0, 0, MMU_BLOCK0_VADDR, src_addr_aligned, 64, count); #elif CONFIG_IDF_TARGET_ESP32S2 int e = Cache_Ibus_MMU_Set(MMU_ACCESS_FLASH, MMU_BLOCK0_VADDR, src_addr_aligned, 64, count, 0); -#else // S3, C3 +#else // S3, C3, H2 int e = Cache_Dbus_MMU_Set(MMU_ACCESS_FLASH, MMU_BLOCK0_VADDR, src_addr_aligned, 64, count, 0); #endif if (e != 0) { @@ -208,6 +217,8 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size) Cache_Resume_DCache(autoload); #elif CONFIG_IDF_TARGET_ESP32C3 Cache_Resume_ICache(autoload); +#elif CONFIG_IDF_TARGET_ESP32H2 + Cache_Resume_ICache(autoload); #endif return NULL; } @@ -219,6 +230,8 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size) Cache_Resume_DCache(autoload); #elif CONFIG_IDF_TARGET_ESP32C3 Cache_Resume_ICache(autoload); +#elif CONFIG_IDF_TARGET_ESP32H2 + Cache_Resume_ICache(autoload); #endif mapped = true; @@ -248,6 +261,10 @@ void bootloader_munmap(const void *mapping) Cache_Suspend_ICache(); Cache_Invalidate_ICache_All(); Cache_MMU_Init(); +#elif CONFIG_IDF_TARGET_ESP32H2 + Cache_Suspend_ICache(); + Cache_Invalidate_ICache_All(); + Cache_MMU_Init(); #endif mapped = false; current_read_mapping = UINT32_MAX; @@ -279,6 +296,8 @@ static esp_err_t bootloader_flash_read_no_decrypt(size_t src_addr, void *dest, s uint32_t autoload = Cache_Suspend_DCache(); #elif CONFIG_IDF_TARGET_ESP32C3 uint32_t autoload = Cache_Suspend_ICache(); +#elif CONFIG_IDF_TARGET_ESP32H2 + uint32_t autoload = Cache_Suspend_ICache(); #endif esp_rom_spiflash_result_t r = esp_rom_spiflash_read(src_addr, dest, size); #if CONFIG_IDF_TARGET_ESP32 @@ -289,6 +308,8 @@ static esp_err_t bootloader_flash_read_no_decrypt(size_t src_addr, void *dest, s Cache_Resume_DCache(autoload); #elif CONFIG_IDF_TARGET_ESP32C3 Cache_Resume_ICache(autoload); +#elif CONFIG_IDF_TARGET_ESP32H2 + Cache_Resume_ICache(autoload); #endif return spi_to_esp_err(r); @@ -316,6 +337,9 @@ static esp_err_t bootloader_flash_read_allow_decrypt(size_t src_addr, void *dest #elif CONFIG_IDF_TARGET_ESP32C3 uint32_t autoload = Cache_Suspend_ICache(); Cache_Invalidate_ICache_All(); +#elif CONFIG_IDF_TARGET_ESP32H2 + uint32_t autoload = Cache_Suspend_ICache(); + Cache_Invalidate_ICache_All(); #endif ESP_LOGD(TAG, "mmu set block paddr=0x%08x (was 0x%08x)", map_at, current_read_mapping); #if CONFIG_IDF_TARGET_ESP32 @@ -326,6 +350,8 @@ static esp_err_t bootloader_flash_read_allow_decrypt(size_t src_addr, void *dest int e = Cache_Dbus_MMU_Set(MMU_ACCESS_FLASH, MMU_BLOCK63_VADDR, map_at, 64, 1, 0); #elif CONFIG_IDF_TARGET_ESP32C3 int e = Cache_Dbus_MMU_Set(MMU_ACCESS_FLASH, MMU_BLOCK63_VADDR, map_at, 64, 1, 0); +#elif CONFIG_IDF_TARGET_ESP32H2 + int e = Cache_Dbus_MMU_Set(MMU_ACCESS_FLASH, MMU_BLOCK63_VADDR, map_at, 64, 1, 0); #endif if (e != 0) { ESP_LOGE(TAG, "cache_flash_mmu_set failed: %d\n", e); @@ -337,6 +363,8 @@ static esp_err_t bootloader_flash_read_allow_decrypt(size_t src_addr, void *dest Cache_Resume_DCache(autoload); #elif CONFIG_IDF_TARGET_ESP32C3 Cache_Resume_ICache(autoload); +#elif CONFIG_IDF_TARGET_ESP32H2 + Cache_Resume_ICache(autoload); #endif return ESP_FAIL; } @@ -349,6 +377,8 @@ static esp_err_t bootloader_flash_read_allow_decrypt(size_t src_addr, void *dest Cache_Resume_DCache(autoload); #elif CONFIG_IDF_TARGET_ESP32C3 Cache_Resume_ICache(autoload); +#elif CONFIG_IDF_TARGET_ESP32H2 + Cache_Resume_ICache(autoload); #endif } map_ptr = (uint32_t *)(FLASH_READ_VADDR + (word_src - map_at)); diff --git a/components/bootloader_support/src/bootloader_flash_config_esp32h2.c b/components/bootloader_support/src/bootloader_flash_config_esp32h2.c new file mode 100644 index 0000000000..547e86767f --- /dev/null +++ b/components/bootloader_support/src/bootloader_flash_config_esp32h2.c @@ -0,0 +1,75 @@ +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "string.h" +#include "sdkconfig.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp32h2/rom/gpio.h" +#include "esp32h2/rom/spi_flash.h" +#include "esp32h2/rom/efuse.h" +#include "soc/gpio_periph.h" +#include "soc/efuse_reg.h" +#include "soc/spi_reg.h" +#include "soc/spi_mem_reg.h" +#include "soc/soc_caps.h" +#include "flash_qio_mode.h" +#include "bootloader_flash_config.h" +#include "bootloader_common.h" + +#define FLASH_IO_MATRIX_DUMMY_40M 0 +#define FLASH_IO_MATRIX_DUMMY_80M 0 + +void bootloader_flash_update_id() +{ + esp_rom_spiflash_chip_t *chip = &rom_spiflash_legacy_data->chip; + chip->device_id = bootloader_read_flash_id(); +} + +void IRAM_ATTR bootloader_flash_cs_timing_config() +{ + SET_PERI_REG_MASK(SPI_MEM_USER_REG(0), SPI_MEM_CS_HOLD_M | SPI_MEM_CS_SETUP_M); + SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_HOLD_TIME_V, 0, SPI_MEM_CS_HOLD_TIME_S); + SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(0), SPI_MEM_CS_SETUP_TIME_V, 0, SPI_MEM_CS_SETUP_TIME_S); + SET_PERI_REG_MASK(SPI_MEM_USER_REG(1), SPI_MEM_CS_HOLD_M | SPI_MEM_CS_SETUP_M); + SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(1), SPI_MEM_CS_HOLD_TIME_V, 1, SPI_MEM_CS_HOLD_TIME_S); + SET_PERI_REG_BITS(SPI_MEM_CTRL2_REG(1), SPI_MEM_CS_SETUP_TIME_V, 0, SPI_MEM_CS_SETUP_TIME_S); +} + +void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t *pfhdr) +{ + uint32_t spi_clk_div = 0; + switch (pfhdr->spi_speed) { + case ESP_IMAGE_SPI_SPEED_80M: + spi_clk_div = 1; + break; + case ESP_IMAGE_SPI_SPEED_40M: + spi_clk_div = 2; + break; + case ESP_IMAGE_SPI_SPEED_26M: + spi_clk_div = 3; + break; + case ESP_IMAGE_SPI_SPEED_20M: + spi_clk_div = 4; + break; + default: + break; + } + esp_rom_spiflash_config_clk(spi_clk_div, 0); +} + +void IRAM_ATTR bootloader_flash_set_dummy_out(void) +{ + REG_SET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FDUMMY_OUT | SPI_MEM_D_POL | SPI_MEM_Q_POL); + REG_SET_BIT(SPI_MEM_CTRL_REG(1), SPI_MEM_FDUMMY_OUT | SPI_MEM_D_POL | SPI_MEM_Q_POL); +} + +void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t *pfhdr) +{ + bootloader_configure_spi_pins(1); + bootloader_flash_set_dummy_out(); +} diff --git a/components/bootloader_support/src/bootloader_random_esp32h2.c b/components/bootloader_support/src/bootloader_random_esp32h2.c new file mode 100644 index 0000000000..3cc4e3ab2f --- /dev/null +++ b/components/bootloader_support/src/bootloader_random_esp32h2.c @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "sdkconfig.h" +#include "bootloader_random.h" +#include "esp_log.h" +#include "soc/syscon_reg.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/apb_saradc_reg.h" +#include "soc/system_reg.h" +#include "regi2c_ctrl.h" + +// ESP32H2-TODO: IDF-3381 +void bootloader_random_enable(void) +{ + +} + +void bootloader_random_disable(void) +{ + +} diff --git a/components/bootloader_support/src/bootloader_utility.c b/components/bootloader_support/src/bootloader_utility.c index edd19c75ea..747c2e3b69 100644 --- a/components/bootloader_support/src/bootloader_utility.c +++ b/components/bootloader_support/src/bootloader_utility.c @@ -45,6 +45,18 @@ #include "esp32c3/rom/secure_boot.h" #include "soc/extmem_reg.h" #include "soc/cache_memory.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/cache.h" +#include "esp32h2/rom/efuse.h" +#include "esp32h2/rom/ets_sys.h" +#include "esp32h2/rom/spi_flash.h" +#include "esp32h2/rom/crc.h" +#include "esp32h2/rom/rtc.h" +#include "esp32h2/rom/uart.h" +#include "esp32h2/rom/gpio.h" +#include "esp32h2/rom/secure_boot.h" +#include "soc/extmem_reg.h" +#include "soc/cache_memory.h" #else // CONFIG_IDF_TARGET_* #error "Unsupported IDF_TARGET" #endif @@ -700,6 +712,9 @@ static void set_cache_and_start_app( #elif CONFIG_IDF_TARGET_ESP32C3 uint32_t autoload = Cache_Suspend_ICache(); Cache_Invalidate_ICache_All(); +#elif CONFIG_IDF_TARGET_ESP32H2 + uint32_t autoload = Cache_Suspend_ICache(); + Cache_Invalidate_ICache_All(); #endif /* Clear the MMU entries that are already set up, @@ -726,6 +741,8 @@ static void set_cache_and_start_app( rc = Cache_Dbus_MMU_Set(MMU_ACCESS_FLASH, drom_load_addr & 0xffff0000, drom_addr & 0xffff0000, 64, drom_page_count, 0); #elif CONFIG_IDF_TARGET_ESP32C3 rc = Cache_Dbus_MMU_Set(MMU_ACCESS_FLASH, drom_load_addr & 0xffff0000, drom_addr & 0xffff0000, 64, drom_page_count, 0); +#elif CONFIG_IDF_TARGET_ESP32H2 + rc = Cache_Dbus_MMU_Set(MMU_ACCESS_FLASH, drom_load_addr & 0xffff0000, drom_addr & 0xffff0000, 64, drom_page_count, 0); #endif ESP_LOGV(TAG, "rc=%d", rc); #if CONFIG_IDF_TARGET_ESP32 @@ -753,6 +770,8 @@ static void set_cache_and_start_app( rc = Cache_Ibus_MMU_Set(MMU_ACCESS_FLASH, irom_load_addr & 0xffff0000, irom_addr & 0xffff0000, 64, irom_page_count, 0); #elif CONFIG_IDF_TARGET_ESP32C3 rc = Cache_Ibus_MMU_Set(MMU_ACCESS_FLASH, irom_load_addr & 0xffff0000, irom_addr & 0xffff0000, 64, irom_page_count, 0); +#elif CONFIG_IDF_TARGET_ESP32H2 + rc = Cache_Ibus_MMU_Set(MMU_ACCESS_FLASH, irom_load_addr & 0xffff0000, irom_addr & 0xffff0000, 64, irom_page_count, 0); #endif ESP_LOGV(TAG, "rc=%d", rc); #if CONFIG_IDF_TARGET_ESP32 @@ -776,6 +795,9 @@ static void set_cache_and_start_app( #elif CONFIG_IDF_TARGET_ESP32C3 REG_CLR_BIT(EXTMEM_ICACHE_CTRL1_REG, EXTMEM_ICACHE_SHUT_IBUS); REG_CLR_BIT(EXTMEM_ICACHE_CTRL1_REG, EXTMEM_ICACHE_SHUT_DBUS); +#elif CONFIG_IDF_TARGET_ESP32H2 + REG_CLR_BIT(EXTMEM_ICACHE_CTRL1_REG, EXTMEM_ICACHE_SHUT_IBUS); + REG_CLR_BIT(EXTMEM_ICACHE_CTRL1_REG, EXTMEM_ICACHE_SHUT_DBUS); #endif #if CONFIG_IDF_TARGET_ESP32 Cache_Read_Enable(0); @@ -785,6 +807,8 @@ static void set_cache_and_start_app( Cache_Resume_DCache(autoload); #elif CONFIG_IDF_TARGET_ESP32C3 Cache_Resume_ICache(autoload); +#elif CONFIG_IDF_TARGET_ESP32H2 + Cache_Resume_ICache(autoload); #endif // Application will need to do Cache_Flush(1) and Cache_Read_Enable(1) diff --git a/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c b/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c new file mode 100644 index 0000000000..c7d1e0d659 --- /dev/null +++ b/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c @@ -0,0 +1,327 @@ +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "sdkconfig.h" +#include "esp_attr.h" +#include "esp_log.h" +#include "esp_image_format.h" +#include "flash_qio_mode.h" +#include "esp_rom_gpio.h" +#include "esp_rom_efuse.h" +#include "esp_rom_uart.h" +#include "esp_rom_sys.h" +#include "soc/efuse_reg.h" +#include "soc/gpio_sig_map.h" +#include "soc/io_mux_reg.h" +#include "soc/assist_debug_reg.h" +#include "soc/cpu.h" +#include "soc/rtc.h" +#include "soc/spi_periph.h" +#include "soc/extmem_reg.h" +#include "soc/io_mux_reg.h" +#include "soc/system_reg.h" +#include "esp32h2/rom/efuse.h" +#include "esp32h2/rom/spi_flash.h" +#include "esp32h2/rom/cache.h" +#include "esp32h2/rom/ets_sys.h" +#include "esp32h2/rom/spi_flash.h" +#include "esp32h2/rom/rtc.h" +#include "bootloader_common.h" +#include "bootloader_init.h" +#include "bootloader_clock.h" +#include "bootloader_flash_config.h" +#include "bootloader_mem.h" +#include "regi2c_ctrl.h" +#include "bootloader_console.h" +#include "bootloader_flash_priv.h" + +static const char *TAG = "boot.esp32h2"; + +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 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); +} + +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); // TODO: set mode + Cache_Resume_ICache(autoload); +} + +static void print_flash_info(const esp_image_header_t *bootloader_hdr) +{ + ESP_LOGD(TAG, "magic %02x", bootloader_hdr->magic); + ESP_LOGD(TAG, "segments %02x", bootloader_hdr->segment_count); + ESP_LOGD(TAG, "spi_mode %02x", bootloader_hdr->spi_mode); + ESP_LOGD(TAG, "spi_speed %02x", bootloader_hdr->spi_speed); + ESP_LOGD(TAG, "spi_size %02x", bootloader_hdr->spi_size); + + const char *str; + switch (bootloader_hdr->spi_speed) { + case ESP_IMAGE_SPI_SPEED_40M: + str = "40MHz"; + break; + case ESP_IMAGE_SPI_SPEED_26M: + str = "26.7MHz"; + break; + case ESP_IMAGE_SPI_SPEED_20M: + str = "20MHz"; + break; + case ESP_IMAGE_SPI_SPEED_80M: + str = "80MHz"; + break; + default: + str = "20MHz"; + break; + } + ESP_LOGI(TAG, "SPI Speed : %s", str); + + /* SPI mode could have been set to QIO during boot already, + so test the SPI registers not the flash header */ + uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0)); + if (spi_ctrl & SPI_MEM_FREAD_QIO) { + str = "QIO"; + } else if (spi_ctrl & SPI_MEM_FREAD_QUAD) { + str = "QOUT"; + } else if (spi_ctrl & SPI_MEM_FREAD_DIO) { + str = "DIO"; + } else if (spi_ctrl & SPI_MEM_FREAD_DUAL) { + str = "DOUT"; + } else if (spi_ctrl & SPI_MEM_FASTRD_MODE) { + str = "FAST READ"; + } else { + str = "SLOW READ"; + } + ESP_LOGI(TAG, "SPI Mode : %s", str); + + switch (bootloader_hdr->spi_size) { + case ESP_IMAGE_FLASH_SIZE_1MB: + str = "1MB"; + break; + case ESP_IMAGE_FLASH_SIZE_2MB: + str = "2MB"; + break; + case ESP_IMAGE_FLASH_SIZE_4MB: + str = "4MB"; + break; + case ESP_IMAGE_FLASH_SIZE_8MB: + str = "8MB"; + break; + case ESP_IMAGE_FLASH_SIZE_16MB: + str = "16MB"; + break; + default: + str = "2MB"; + break; + } + ESP_LOGI(TAG, "SPI Flash Size : %s", str); +} + +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(); +#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_spi_flash_resume(); + esp_rom_spiflash_unlock(); + +#if CONFIG_ESPTOOLPY_FLASHMODE_QIO || CONFIG_ESPTOOLPY_FLASHMODE_QOUT + bootloader_enable_qio_mode(); +#endif + + print_flash_info(&bootloader_image_hdr); + update_flash_config(&bootloader_image_hdr); + //ensure the flash is write-protected + bootloader_enable_wp(); + return ESP_OK; +} + +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_EN_REG, ASSIST_DEBUG_CORE_0_RCD_PDEBUGEN | ASSIST_DEBUG_CORE_0_RCD_RECORDEN); +} + +static void wdt_reset_info_dump(int cpu) +{ + (void) cpu; + // saved PC was already printed by the ROM bootloader. + // nothing to do here. +} + +static void bootloader_check_wdt_reset(void) +{ + int wdt_rst = 0; + RESET_REASON rst_reas[2]; + + rst_reas[0] = rtc_get_reset_reason(0); + if (rst_reas[0] == RTCWDT_SYS_RESET || rst_reas[0] == TG0WDT_SYS_RESET || rst_reas[0] == TG1WDT_SYS_RESET || + rst_reas[0] == TG0WDT_CPU_RESET || rst_reas[0] == TG1WDT_CPU_RESET || rst_reas[0] == RTCWDT_CPU_RESET) { + ESP_LOGW(TAG, "PRO CPU has been reset by WDT."); + wdt_rst = 1; + } + if (wdt_rst) { + // if reset by WDT dump info from trace port + wdt_reset_info_dump(0); + } + 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_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); + } +} + +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 console, from now on, we can use esp_log + bootloader_console_init(); + /* print 2nd bootloader banner */ + bootloader_print_banner(); + // update flash ID + bootloader_flash_update_id(); + // read bootloader header + if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { + goto err; + } + // read chip revision and check if it's compatible to bootloader + if ((ret = bootloader_check_bootloader_validity()) != 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(); + // enable RNG early entropy source + bootloader_enable_random(); +err: + return ret; +} diff --git a/components/bootloader_support/src/esp32h2/bootloader_sha.c b/components/bootloader_support/src/esp32h2/bootloader_sha.c new file mode 100644 index 0000000000..4054751df7 --- /dev/null +++ b/components/bootloader_support/src/esp32h2/bootloader_sha.c @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "bootloader_sha.h" +#include +#include +#include +#include + +#include "esp32h2/rom/sha.h" + +static SHA_CTX ctx; + +bootloader_sha256_handle_t bootloader_sha256_start() +{ + // Enable SHA hardware + ets_sha_enable(); + ets_sha_init(&ctx, SHA2_256); + return &ctx; // Meaningless non-NULL value +} + +void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data, size_t data_len) +{ + assert(handle != NULL); + assert(data_len % 4 == 0); + ets_sha_update(&ctx, data, data_len, false); +} + +void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest) +{ + assert(handle != NULL); + + if (digest == NULL) { + bzero(&ctx, sizeof(ctx)); + return; + } + ets_sha_finish(&ctx, digest); +} diff --git a/components/bootloader_support/src/esp32h2/flash_encrypt.c b/components/bootloader_support/src/esp32h2/flash_encrypt.c new file mode 100644 index 0000000000..b0a6190f2d --- /dev/null +++ b/components/bootloader_support/src/esp32h2/flash_encrypt.c @@ -0,0 +1,346 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "bootloader_flash_priv.h" +#include "bootloader_random.h" +#include "bootloader_utility.h" +#include "esp_image_format.h" +#include "esp_flash_encrypt.h" +#include "esp_flash_partitions.h" +#include "esp_secure_boot.h" +#include "esp_log.h" +#include "esp32h2/rom/secure_boot.h" +#include "esp_efuse.h" +#include "esp_efuse_table.h" +#include "hal/wdt_hal.h" + +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_and_load_partition_table(esp_partition_info_t *partition_table, int *num_partitions); +static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partition); + +esp_err_t esp_flash_encrypt_check_and_update(void) +{ + uint8_t flash_crypt_wr_dis = 0; + uint32_t flash_crypt_cnt = 0; + + esp_efuse_read_field_blob(ESP_EFUSE_SPI_BOOT_CRYPT_CNT, &flash_crypt_cnt, 3); + esp_efuse_read_field_blob(ESP_EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT, &flash_crypt_wr_dis, 1); + + ESP_LOGV(TAG, "SPI_BOOT_CRYPT_CNT 0x%x", flash_crypt_cnt); + ESP_LOGV(TAG, "EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT 0x%x", flash_crypt_wr_dis); + + if (__builtin_parity(flash_crypt_cnt) == 1) { + /* Flash is already encrypted */ + int left = (flash_crypt_cnt == 1) ? 1 : 0; + 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) +{ + esp_efuse_block_t aes_128_key_block; + + bool has_key = esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY, &aes_128_key_block); + bool dis_write = false; + bool dis_read = false; + + // If there are keys set, they must be write and read protected! + if(has_key) { + dis_write = esp_efuse_get_key_dis_write(aes_128_key_block); + dis_read = esp_efuse_get_key_dis_read(aes_128_key_block); + } + + + if(has_key && (!dis_read || !dis_write)) { + ESP_LOGE(TAG, "Invalid key state, a key was set but not read and write protected."); + return ESP_ERR_INVALID_STATE; + } + + if(!has_key && !dis_write && !dis_read) { + ESP_LOGI(TAG, "Generating new flash encryption key..."); + + enum { BLOCKS_NEEDED = 1 }; + esp_efuse_purpose_t purposes[BLOCKS_NEEDED] = { + ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY, + }; + + uint8_t keys[BLOCKS_NEEDED][32] = { 0 }; + for (int i = 0; i < BLOCKS_NEEDED; ++i) { + bootloader_fill_random(keys[i], 32); + } + + 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; + } + ESP_LOGD(TAG, "Key generation complete"); + return ESP_OK; + + } else { + ESP_LOGI(TAG, "Using pre-existing 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 */ + + esp_err_t key_state = check_and_generate_encryption_keys(); + if(key_state != ESP_OK) { + esp_efuse_batch_write_cancel(); + return key_state; + } + +#ifndef CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC + ESP_LOGI(TAG, "Disable UART bootloader encryption..."); + esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT); +#else + ESP_LOGW(TAG, "Not disabling UART bootloader encryption"); +#endif + +#ifndef CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE + ESP_LOGI(TAG, "Disable UART bootloader cache..."); + esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_ICACHE); +#else + ESP_LOGW(TAG, "Not disabling UART bootloader cache - SECURITY COMPROMISED"); +#endif + +#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG + ESP_LOGI(TAG, "Disable JTAG..."); + esp_efuse_write_field_bit(ESP_EFUSE_DIS_PAD_JTAG); + esp_efuse_write_field_bit(ESP_EFUSE_DIS_USB_JTAG); +#else + ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED"); +#endif + + esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT); + + esp_err_t err = esp_efuse_batch_write_commit(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Error programming security eFuses (err=0x%x).", err); + } + + return err; +} + +/* Encrypt all flash data that should be encrypted */ +static esp_err_t encrypt_flash_contents(uint32_t spi_boot_crypt_cnt, bool flash_crypt_wr_dis) +{ + esp_err_t err; + esp_partition_info_t partition_table[ESP_PARTITION_TABLE_MAX_ENTRIES]; + int num_partitions; + + /* If the last spi_boot_crypt_cnt bit is burned or write-disabled, the + device can't re-encrypt itself. */ + if (flash_crypt_wr_dis || spi_boot_crypt_cnt == EFUSE_SPI_BOOT_CRYPT_CNT) { + ESP_LOGE(TAG, "Cannot re-encrypt data SPI_BOOT_CRYPT_CNT 0x%02x write disabled %d", spi_boot_crypt_cnt, flash_crypt_wr_dis); + return ESP_FAIL; + } + + if (spi_boot_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; + } + + err = encrypt_and_load_partition_table(partition_table, &num_partitions); + if (err != ESP_OK) { + return err; + } + + /* Now iterate the just-loaded partition table, looking for entries to encrypt + */ + + /* Go through each partition and encrypt if necessary */ + for (int i = 0; i < num_partitions; i++) { + err = encrypt_partition(i, &partition_table[i]); + if (err != ESP_OK) { + return err; + } + } + + ESP_LOGD(TAG, "All flash regions checked for encryption pass"); + + /* Set least significant 0-bit in spi_boot_crypt_cnt */ + int ffs_inv = __builtin_ffs((~spi_boot_crypt_cnt) & 0x7); + /* ffs_inv shouldn't be zero, as zero implies spi_boot_crypt_cnt == 0xFF */ + uint32_t new_spi_boot_crypt_cnt = (1 << (ffs_inv - 1)); + ESP_LOGD(TAG, "SPI_BOOT_CRYPT_CNT 0x%x -> 0x%x", spi_boot_crypt_cnt, new_spi_boot_crypt_cnt + spi_boot_crypt_cnt); + + esp_efuse_write_field_blob(ESP_EFUSE_SPI_BOOT_CRYPT_CNT, &new_spi_boot_crypt_cnt, 3); + +#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE + //Secure SPI boot cnt after its update if needed. + const uint32_t spi_boot_cnt_wr_dis = 1; + ESP_LOGI(TAG, "Write protecting SPI_CRYPT_CNT eFuse"); + esp_efuse_write_field_blob(ESP_EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT, &spi_boot_cnt_wr_dis, 1); +#endif + 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_LOGD(TAG, "bootloader is plaintext. Encrypting..."); + +#if CONFIG_SECURE_BOOT_V2_ENABLED + /* The image length obtained from esp_image_verify_bootloader includes the sector boundary padding and the signature block lengths */ + if (ESP_BOOTLOADER_OFFSET + image_length > ESP_PARTITION_TABLE_OFFSET) { + ESP_LOGE(TAG, "Bootloader is too large to fit Secure Boot V2 signature sector and partition table (configured offset 0x%x)", ESP_PARTITION_TABLE_OFFSET); + return ESP_ERR_INVALID_SIZE; + } +#endif // CONFIG_SECURE_BOOT_V2_ENABLED + + err = esp_flash_encrypt_region(ESP_BOOTLOADER_OFFSET, image_length); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to encrypt bootloader in place: 0x%x", err); + return err; + } + + ESP_LOGI(TAG, "bootloader encrypted successfully"); + return err; + } + else { + ESP_LOGW(TAG, "no valid bootloader was found"); + return ESP_ERR_NOT_FOUND; + } +} + +static esp_err_t encrypt_and_load_partition_table(esp_partition_info_t *partition_table, int *num_partitions) +{ + esp_err_t err; + /* Check for plaintext partition table */ + err = bootloader_flash_read(ESP_PARTITION_TABLE_OFFSET, partition_table, ESP_PARTITION_TABLE_MAX_LEN, false); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to read partition table data"); + return err; + } + if (esp_partition_table_verify(partition_table, false, num_partitions) == ESP_OK) { + ESP_LOGD(TAG, "partition table is plaintext. Encrypting..."); + esp_err_t err = esp_flash_encrypt_region(ESP_PARTITION_TABLE_OFFSET, + FLASH_SECTOR_SIZE); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to encrypt partition table in place. %x", err); + return err; + } + } else { + ESP_LOGE(TAG, "Failed to read partition table data - not plaintext?"); + return ESP_ERR_INVALID_STATE; + } + + /* Valid partition table loaded */ + ESP_LOGI(TAG, "partition table encrypted and loaded successfully"); + return ESP_OK; +} + + +static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partition) +{ + esp_err_t err; + bool should_encrypt = (partition->flags & PART_FLAG_ENCRYPTED); + + if (partition->type == PART_TYPE_APP) { + /* check if the partition holds a valid unencrypted app */ + esp_image_metadata_t data_ignored; + err = esp_image_verify(ESP_IMAGE_VERIFY, + &partition->pos, + &data_ignored); + should_encrypt = (err == ESP_OK); + } else if (partition->type == PART_TYPE_DATA && partition->subtype == PART_SUBTYPE_DATA_OTA) { + /* check if we have ota data partition and the partition should be encrypted unconditionally */ + should_encrypt = true; + } + + if (!should_encrypt) { + return ESP_OK; + } else { + /* should_encrypt */ + ESP_LOGI(TAG, "Encrypting partition %d at offset 0x%x (length 0x%x)...", index, partition->pos.offset, partition->pos.size); + + err = esp_flash_encrypt_region(partition->pos.offset, partition->pos.size); + ESP_LOGI(TAG, "Done encrypting"); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to encrypt partition %d", index); + } + return err; + } +} + + +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, false); + 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/components/bootloader_support/src/esp32h2/secure_boot.c b/components/bootloader_support/src/esp32h2/secure_boot.c new file mode 100644 index 0000000000..3fd6e04792 --- /dev/null +++ b/components/bootloader_support/src/esp32h2/secure_boot.c @@ -0,0 +1,289 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +#include "esp_log.h" +#include "esp_secure_boot.h" +#include "soc/efuse_reg.h" + +#include "bootloader_flash_priv.h" +#include "bootloader_sha.h" +#include "bootloader_utility.h" + +#include "esp_rom_crc.h" +#include "esp_efuse.h" +#include "esp_efuse_table.h" + +#include "esp32h2/rom/efuse.h" +#include "esp32h2/rom/secure_boot.h" + +static const char *TAG = "secure_boot_v2"; +#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) + +/* 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) +{ + uint32_t crc = esp_rom_crc32_le(0, (uint8_t *)block, CRC_SIGN_BLOCK_LEN); + 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 != crc) { + 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 signatures"); + 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; + } + + for (int 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; +} + +static esp_err_t check_and_generate_secure_boot_keys(const esp_image_metadata_t *image_data) +{ + esp_err_t ret; + /* 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; + } + + /* Check if secure boot digests are present */ + bool has_secure_boot_digest = esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0, NULL); + has_secure_boot_digest |= esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1, NULL); + has_secure_boot_digest |= esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2, NULL); + ESP_LOGI(TAG, "Secure boot digests %s", has_secure_boot_digest ? "already present":"absent, generating.."); + + if (!has_secure_boot_digest) { + esp_image_sig_public_key_digests_t boot_key_digests = {0}; + esp_image_sig_public_key_digests_t app_key_digests = {0}; + + /* 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_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, + }; + + ret = esp_efuse_write_keys(secure_boot_key_purpose, boot_key_digests.key_digests, boot_key_digests.num_digests); + if (ret) { + 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; + } + + /* Generate the application public key digests */ + ret = s_calculate_image_public_key_digests(image_data->start_addr, image_data->image_len - SIG_BLOCK_PADDING, &app_key_digests); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "App signature block is invalid."); + return ret; + } + + if (app_key_digests.num_digests == 0) { + ESP_LOGE(TAG, "No valid applications signature blocks found."); + return ESP_FAIL; + } + + ESP_LOGI(TAG, "%d signature block(s) found appended to the app.", app_key_digests.num_digests); + if (app_key_digests.num_digests > boot_key_digests.num_digests) { + ESP_LOGW(TAG, "App has %d signature blocks but bootloader only has %d. Some keys missing from bootloader?"); + } + + /* Confirm if at least one public key from the application matches a public key in the bootloader + (Also, ensure if that public revoke bit is not set for the matched key) */ + bool match = false; + + for (int i = 0; i < boot_key_digests.num_digests; i++) { + + if (esp_efuse_get_digest_revoke(i)) { + ESP_LOGI(TAG, "Key block(%d) has been revoked.", i); + continue; // skip if the key block is revoked + } + + for (int j = 0; j < app_key_digests.num_digests; j++) { + if (!memcmp(boot_key_digests.key_digests[i], app_key_digests.key_digests[j], ESP_SECURE_BOOT_DIGEST_LEN)) { + ESP_LOGI(TAG, "Application key(%d) matches with bootloader key(%d).", j, i); + match = true; + } + } + } + + if (match == false) { + ESP_LOGE(TAG, "No application key digest matches the bootloader key digest."); + return ESP_FAIL; + } + + /* 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 (uint8_t 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); + } + } + } + return ESP_OK; +} + +esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *image_data) +{ + ESP_LOGI(TAG, "enabling secure boot v2..."); + + if (esp_secure_boot_enabled()) { + ESP_LOGI(TAG, "secure boot v2 is already enabled, continuing.."); + return ESP_OK; + } + + esp_efuse_batch_write_begin(); /* Batch all efuse writes at the end of this function */ + + esp_err_t key_state = check_and_generate_secure_boot_keys(image_data); + if (key_state != ESP_OK) { + esp_efuse_batch_write_cancel(); + return key_state; + } + + esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT); + +#ifdef CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE + ESP_LOGI(TAG, "Enabling Security download mode..."); + esp_efuse_write_field_bit(ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD); +#else + ESP_LOGW(TAG, "Not enabling Security download mode - SECURITY COMPROMISED"); +#endif + +#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG + ESP_LOGI(TAG, "Disable hardware & software JTAG..."); + esp_efuse_write_field_bit(ESP_EFUSE_DIS_PAD_JTAG); + esp_efuse_write_field_bit(ESP_EFUSE_DIS_USB_JTAG); + esp_efuse_write_field_bit(ESP_EFUSE_SOFT_DIS_JTAG); +#else + ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED"); +#endif + +#ifdef CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE + esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE); +#endif + + esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_EN); + + esp_err_t err = esp_efuse_batch_write_commit(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Error programming security eFuses (err=0x%x).", err); + return err; + } + +#ifdef CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE + assert(ets_efuse_secure_boot_aggressive_revoke_enabled()); +#endif + + assert(esp_rom_efuse_is_secure_boot_enabled()); + ESP_LOGI(TAG, "Secure boot permanently enabled"); + + return ESP_OK; +} diff --git a/components/bootloader_support/src/esp_image_format.c b/components/bootloader_support/src/esp_image_format.c index 10c93207d6..52fa5c19dd 100644 --- a/components/bootloader_support/src/esp_image_format.c +++ b/components/bootloader_support/src/esp_image_format.c @@ -30,6 +30,9 @@ #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rom/rtc.h" #include "esp32c3/rom/secure_boot.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/rtc.h" +#include "esp32h2/rom/secure_boot.h" #endif /* Checking signatures as part of verifying images is necessary: diff --git a/components/bootloader_support/src/flash_encrypt.c b/components/bootloader_support/src/flash_encrypt.c index 4ed7397486..c6a9815c2f 100644 --- a/components/bootloader_support/src/flash_encrypt.c +++ b/components/bootloader_support/src/flash_encrypt.c @@ -89,6 +89,9 @@ esp_flash_enc_mode_t esp_get_flash_encryption_mode(void) #elif CONFIG_IDF_TARGET_ESP32C3 uint8_t dis_dl_enc = 0; uint8_t dis_dl_icache = 0; +#elif CONFIG_IDF_TARGET_ESP32H2 + uint8_t dis_dl_enc = 0; + uint8_t dis_dl_icache = 0; #endif esp_flash_enc_mode_t mode = ESP_FLASH_ENC_MODE_DEVELOPMENT; @@ -127,6 +130,13 @@ esp_flash_enc_mode_t esp_get_flash_encryption_mode(void) dis_dl_enc = esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT); dis_dl_icache = esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_ICACHE); + if (dis_dl_enc && dis_dl_icache) { + mode = ESP_FLASH_ENC_MODE_RELEASE; + } +#elif CONFIG_IDF_TARGET_ESP32H2 + dis_dl_enc = esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT); + dis_dl_icache = esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_ICACHE); + if (dis_dl_enc && dis_dl_icache) { mode = ESP_FLASH_ENC_MODE_RELEASE; } diff --git a/components/bootloader_support/src/flash_partitions.c b/components/bootloader_support/src/flash_partitions.c index 2729d3df12..9731244cfb 100644 --- a/components/bootloader_support/src/flash_partitions.c +++ b/components/bootloader_support/src/flash_partitions.c @@ -13,6 +13,8 @@ #include "esp32s2/rom/spi_flash.h" #elif CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/spi_flash.h" #else #include "esp32/rom/spi_flash.h" #endif diff --git a/components/bootloader_support/src/flash_qio_mode.c b/components/bootloader_support/src/flash_qio_mode.c index ce14f0a3fd..83b9377f52 100644 --- a/components/bootloader_support/src/flash_qio_mode.c +++ b/components/bootloader_support/src/flash_qio_mode.c @@ -21,6 +21,8 @@ #include "esp32s3/rom/spi_flash.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32H2 +#include "esp32h2/rom/spi_flash.h" #endif #include "soc/efuse_periph.h" #include "soc/io_mux_reg.h"