From 1c820b0a6d1eccedbfd5e671fd0d5a0162269549 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Fri, 8 Jul 2022 16:46:11 +0800 Subject: [PATCH] esp32c6: add bootloader support --- .../subproject/main/ld/esp32c6/bootloader.ld | 200 ++++++++++ .../main/ld/esp32c6/bootloader.rom.ld | 6 + .../bootloader_flash/src/bootloader_flash.c | 20 +- .../src/bootloader_flash_config_esp32c6.c | 69 ++++ .../bootloader_flash/src/flash_qio_mode.c | 4 +- .../include/esp_app_format.h | 1 + .../private_include/bootloader_signature.h | 2 + .../src/bootloader_clock_init.c | 27 ++ .../src/bootloader_console.c | 3 + .../bootloader_support/src/bootloader_efuse.c | 3 + .../bootloader_support/src/bootloader_init.c | 30 +- .../bootloader_support/src/bootloader_mem.c | 13 + .../src/bootloader_random_esp32c6.c | 22 ++ .../src/bootloader_utility.c | 7 + .../src/esp32c6/bootloader_esp32c6.c | 344 ++++++++++++++++++ .../src/esp32c6/bootloader_sha.c | 40 ++ .../src/esp32c6/bootloader_soc.c | 28 ++ .../flash_encryption_secure_features.c | 50 +++ .../src/esp32c6/secure_boot_secure_features.c | 70 ++++ .../bootloader_support/src/esp_image_format.c | 3 + .../bootloader_support/src/flash_encrypt.c | 4 +- .../src/flash_encryption/flash_encrypt.c | 4 + 22 files changed, 922 insertions(+), 28 deletions(-) create mode 100644 components/bootloader/subproject/main/ld/esp32c6/bootloader.ld create mode 100644 components/bootloader/subproject/main/ld/esp32c6/bootloader.rom.ld create mode 100644 components/bootloader_support/src/esp32c6/bootloader_esp32c6.c create mode 100644 components/bootloader_support/src/esp32c6/bootloader_sha.c create mode 100644 components/bootloader_support/src/esp32c6/bootloader_soc.c create mode 100644 components/bootloader_support/src/esp32c6/flash_encryption_secure_features.c create mode 100644 components/bootloader_support/src/esp32c6/secure_boot_secure_features.c diff --git a/components/bootloader/subproject/main/ld/esp32c6/bootloader.ld b/components/bootloader/subproject/main/ld/esp32c6/bootloader.ld new file mode 100644 index 0000000000..05a420d03f --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32c6/bootloader.ld @@ -0,0 +1,200 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/** 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 = 0x4086E000, len = 0x2000 + iram_loader_seg (RWX) : org = 0x40870000, len = 0x6000 + dram_seg (RW) : org = 0x40876000, 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.*(.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:bootloader_soc.*(.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_encryption_secure_features.*(.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_secure_features.*(.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.*) + *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) + *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) + *libhal.a:efuse_hal.*(.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.*) + *(.gnu.linkonce.s2.*) + *(.jcr) + _data_end = ABSOLUTE(.); + } > dram_seg + + .dram0.rodata : + { + _rodata_start = ABSOLUTE(.); + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + *(.rodata1) + *(.sdata2 .sdata2.* .srodata .srodata.*) + __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_AE00 + * | ^ | + * | | | + * | | data/bss | + * | | | + * | v | + * +------------------------------+ 0x3FCD_C710 + * | ^ | + * | | | + * | | stack | + * | | | + * | v | + * +------------------------------+ 0x3FCD_E710 + */ diff --git a/components/bootloader/subproject/main/ld/esp32c6/bootloader.rom.ld b/components/bootloader/subproject/main/ld/esp32c6/bootloader.rom.ld new file mode 100644 index 0000000000..239eb438b4 --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32c6/bootloader.rom.ld @@ -0,0 +1,6 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* No definition for ESP32-C6 target */ diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c index da282577a8..321010fba7 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c @@ -128,9 +128,9 @@ static const char *TAG = "bootloader_flash"; 50th block for bootloader_flash_read */ #define MMU_BLOCK0_VADDR SOC_DROM_LOW -#define MMU_SIZE (0x320000) -#define MMU_BLOCK50_VADDR (MMU_BLOCK0_VADDR + MMU_SIZE) -#define FLASH_READ_VADDR MMU_BLOCK50_VADDR +#define MMAP_MMU_SIZE (0x320000) +#define MMU_BLOCK50_VADDR (MMU_BLOCK0_VADDR + MMAP_MMU_SIZE) +#define FLASH_READ_VADDR MMU_BLOCK50_VADDR #else // !CONFIG_IDF_TARGET_ESP32 @@ -139,15 +139,15 @@ static const char *TAG = "bootloader_flash"; */ #define MMU_BLOCK0_VADDR SOC_DROM_LOW #ifdef SOC_MMU_PAGE_SIZE_CONFIGURABLE -#define MMU_SIZE (DRAM0_CACHE_ADDRESS_HIGH(SPI_FLASH_MMU_PAGE_SIZE) - DRAM0_CACHE_ADDRESS_LOW - SPI_FLASH_MMU_PAGE_SIZE) // This mmu size means that the mmu size to be mapped +#define MMAP_MMU_SIZE (DRAM0_CACHE_ADDRESS_HIGH(SPI_FLASH_MMU_PAGE_SIZE) - DRAM0_CACHE_ADDRESS_LOW - SPI_FLASH_MMU_PAGE_SIZE) // This mmu size means that the mmu size to be mapped #else -#define MMU_SIZE (DRAM0_CACHE_ADDRESS_HIGH - DRAM0_CACHE_ADDRESS_LOW - SPI_FLASH_MMU_PAGE_SIZE) // This mmu size means that the mmu size to be mapped +#define MMAP_MMU_SIZE (DRAM0_CACHE_ADDRESS_HIGH - DRAM0_CACHE_ADDRESS_LOW - SPI_FLASH_MMU_PAGE_SIZE) // This mmu size means that the mmu size to be mapped #endif -#define MMU_BLOCK63_VADDR (MMU_BLOCK0_VADDR + MMU_SIZE) +#define MMU_BLOCK63_VADDR (MMU_BLOCK0_VADDR + MMAP_MMU_SIZE) #define FLASH_READ_VADDR MMU_BLOCK63_VADDR #endif -#define MMU_FREE_PAGES (MMU_SIZE / FLASH_BLOCK_SIZE) +#define MMU_FREE_PAGES (MMAP_MMU_SIZE / CONFIG_MMU_PAGE_SIZE) static bool mapped; @@ -169,7 +169,7 @@ const void *bootloader_mmap(uint32_t src_paddr, uint32_t size) ESP_EARLY_LOGE(TAG, "tried to bootloader_mmap twice"); return NULL; /* can't map twice */ } - if (size > MMU_SIZE) { + if (size > MMAP_MMU_SIZE) { ESP_EARLY_LOGE(TAG, "bootloader_mmap excess size %x", size); return NULL; } @@ -769,10 +769,8 @@ esp_err_t IRAM_ATTR bootloader_flash_reset_chip(void) bootloader_execute_flash_command(0x05, 0, 0, 0); #if CONFIG_IDF_TARGET_ESP32 if (SPI1.ext2.st != 0) -#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 - if (SPIMEM1.fsm.st != 0) #else - if (SPIMEM1.fsm.spi0_mst_st != 0) + if (!spimem_flash_ll_host_idle(&SPIMEM1)) #endif { return ESP_FAIL; diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c index e69de29bb2..7220370f7b 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c @@ -0,0 +1,69 @@ +/* + * SPDX-FileCopyrightText: 2022 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 "esp32c6/rom/gpio.h" +#include "esp32c6/rom/spi_flash.h" +#include "esp32c6/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" + +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); +} + +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_DIV_1: + spi_clk_div = 1; + break; + case ESP_IMAGE_SPI_SPEED_DIV_2: + spi_clk_div = 2; + break; + case ESP_IMAGE_SPI_SPEED_DIV_3: + spi_clk_div = 3; + break; + case ESP_IMAGE_SPI_SPEED_DIV_4: + 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); // TODO: IDF-5631 ESP32C6 not have SPI_MEM_FDUMMY_OUT + REG_SET_BIT(SPI_MEM_CTRL_REG(1), /*SPI_MEM_FDUMMY_OUT |*/ SPI_MEM_D_POL | SPI_MEM_Q_POL); // TODO: idf-5631 ESP32C6 not have SPI_MEM_FDUMMY_OUT +} + +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/bootloader_flash/src/flash_qio_mode.c b/components/bootloader_support/bootloader_flash/src/flash_qio_mode.c index 59dfcfc0ef..a448a0fb6b 100644 --- a/components/bootloader_support/bootloader_flash/src/flash_qio_mode.c +++ b/components/bootloader_support/bootloader_flash/src/flash_qio_mode.c @@ -106,8 +106,8 @@ static void s_flash_set_qio_pins(void) const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); int wp_pin = bootloader_flash_get_wp_pin(); esp_rom_spiflash_select_qio_pins(wp_pin, spiconfig); -#elif CONFIG_IDF_TARGET_ESP32C2 - // ESP32C2 doesn't support configure mspi pins. So the second +#elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5649 Add a soc_caps + // ESP32C2/ESP32C6 doesn't support configure mspi pins. So the second // parameter is set to 0, means that chip uses default SPI pins // and wp_gpio_num parameter(the first parameter) is ignored. esp_rom_spiflash_select_qio_pins(0, 0); diff --git a/components/bootloader_support/include/esp_app_format.h b/components/bootloader_support/include/esp_app_format.h index 5fa0975ee1..7bed35186c 100644 --- a/components/bootloader_support/include/esp_app_format.h +++ b/components/bootloader_support/include/esp_app_format.h @@ -22,6 +22,7 @@ typedef enum { #elif CONFIG_IDF_TARGET_ESP32H2_BETA_VERSION_1 ESP_CHIP_ID_ESP32H2 = 0x000A, /*!< chip ID: ESP32-H2 Beta1 */ #endif + ESP_CHIP_ID_ESP32C6 = 0x000D, /*!< chip ID: ESP32-C6 */ 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/private_include/bootloader_signature.h b/components/bootloader_support/private_include/bootloader_signature.h index fceb9eb49a..9bea96ff7c 100644 --- a/components/bootloader_support/private_include/bootloader_signature.h +++ b/components/bootloader_support/private_include/bootloader_signature.h @@ -21,6 +21,8 @@ #include "esp32h2/rom/secure_boot.h" #elif CONFIG_IDF_TARGET_ESP32C2 #include "esp32c2/rom/secure_boot.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rom/secure_boot.h" #endif #if !CONFIG_IDF_TARGET_ESP32 || CONFIG_ESP32_REV_MIN_3 diff --git a/components/bootloader_support/src/bootloader_clock_init.c b/components/bootloader_support/src/bootloader_clock_init.c index 35b1e08952..943b597e74 100644 --- a/components/bootloader_support/src/bootloader_clock_init.c +++ b/components/bootloader_support/src/bootloader_clock_init.c @@ -7,7 +7,16 @@ #include "soc/soc.h" #include "soc/rtc.h" #include "hal/efuse_hal.h" + +#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5645 #include "soc/rtc_cntl_reg.h" +#else +#include "soc/lp_wdt_reg.h" +#include "soc/lp_timer_reg.h" +#include "soc/lp_analog_peri_reg.h" +#include "soc/pmu_reg.h" +#endif + #if CONFIG_IDF_TARGET_ESP32 #include "hal/clk_tree_ll.h" #endif @@ -65,6 +74,24 @@ __attribute__((weak)) void bootloader_clock_configure(void) } #endif // CONFIG_ESP_SYSTEM_RTC_EXT_XTAL +// TODO: IDF-5645 +#if CONFIG_IDF_TARGET_ESP32C6 + // CLR ENA + CLEAR_PERI_REG_MASK(LP_WDT_INT_ENA_REG, LP_WDT_SUPER_WDT_INT_ENA); /* SWD */ + CLEAR_PERI_REG_MASK(LP_TIMER_LP_INT_ENA_REG, LP_TIMER_MAIN_TIMER_LP_INT_ENA); /* MAIN_TIMER */ + CLEAR_PERI_REG_MASK(LP_ANALOG_PERI_LP_ANA_LP_INT_ENA_REG, LP_ANALOG_PERI_LP_ANA_BOD_MODE0_LP_INT_ENA); /* BROWN_OUT */ + CLEAR_PERI_REG_MASK(LP_WDT_INT_ENA_REG, LP_WDT_LP_WDT_INT_ENA); /* WDT */ + CLEAR_PERI_REG_MASK(PMU_HP_INT_ENA_REG, PMU_SOC_WAKEUP_INT_ENA); /* SLP_REJECT */ + CLEAR_PERI_REG_MASK(PMU_SOC_SLEEP_REJECT_INT_ENA, PMU_SOC_SLEEP_REJECT_INT_ENA); /* SLP_WAKEUP */ + // SET CLR + SET_PERI_REG_MASK(LP_WDT_INT_CLR_REG, LP_WDT_SUPER_WDT_INT_CLR); /* SWD */ + SET_PERI_REG_MASK(LP_TIMER_LP_INT_CLR_REG, LP_TIMER_MAIN_TIMER_LP_INT_CLR); /* MAIN_TIMER */ + SET_PERI_REG_MASK(LP_ANALOG_PERI_LP_ANA_LP_INT_CLR_REG, LP_ANALOG_PERI_LP_ANA_BOD_MODE0_LP_INT_CLR); /* BROWN_OUT */ + SET_PERI_REG_MASK(LP_WDT_INT_CLR_REG, LP_WDT_LP_WDT_INT_CLR); /* WDT */ + SET_PERI_REG_MASK(PMU_HP_INT_CLR_REG, PMU_SOC_WAKEUP_INT_CLR); /* SLP_REJECT */ + SET_PERI_REG_MASK(PMU_SOC_SLEEP_REJECT_INT_CLR, PMU_SOC_SLEEP_REJECT_INT_CLR); /* SLP_WAKEUP */ +#else REG_WRITE(RTC_CNTL_INT_ENA_REG, 0); REG_WRITE(RTC_CNTL_INT_CLR_REG, UINT32_MAX); +#endif } diff --git a/components/bootloader_support/src/bootloader_console.c b/components/bootloader_support/src/bootloader_console.c index 85e4aa8027..d63e63a638 100644 --- a/components/bootloader_support/src/bootloader_console.c +++ b/components/bootloader_support/src/bootloader_console.c @@ -28,6 +28,9 @@ #elif CONFIG_IDF_TARGET_ESP32C2 #include "esp32c2/rom/ets_sys.h" #include "esp32c2/rom/uart.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rom/ets_sys.h" +#include "esp32c6/rom/uart.h" #endif #include "esp_rom_gpio.h" #include "esp_rom_uart.h" diff --git a/components/bootloader_support/src/bootloader_efuse.c b/components/bootloader_support/src/bootloader_efuse.c index ea22a524a6..cf3e49ed76 100644 --- a/components/bootloader_support/src/bootloader_efuse.c +++ b/components/bootloader_support/src/bootloader_efuse.c @@ -30,6 +30,9 @@ int bootloader_clock_get_rated_freq_mhz(void) #elif CONFIG_IDF_TARGET_ESP32H2 return 96; +#elif CONFIG_IDF_TARGET_ESP32C6 + return 160; + #elif CONFIG_IDF_TARGET_ESP32S2 return 240; diff --git a/components/bootloader_support/src/bootloader_init.c b/components/bootloader_support/src/bootloader_init.c index 7567511180..511de79b40 100644 --- a/components/bootloader_support/src/bootloader_init.c +++ b/components/bootloader_support/src/bootloader_init.c @@ -58,27 +58,31 @@ void bootloader_config_wdt(void) * protect the remainder of the bootloader process. */ //Disable RWDT flashboot protection. - 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); +#if CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5653 + wdt_hal_context_t rwdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &LP_WDT}; +#else + wdt_hal_context_t rwdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL}; +#endif + wdt_hal_write_protect_disable(&rwdt_ctx); + wdt_hal_set_flashboot_en(&rwdt_ctx, false); + wdt_hal_write_protect_enable(&rwdt_ctx); #ifdef CONFIG_BOOTLOADER_WDT_ENABLE //Initialize and start RWDT to protect the for bootloader if configured to do so ESP_LOGD(TAG, "Enabling RTCWDT(%d ms)", CONFIG_BOOTLOADER_WDT_TIME_MS); - wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false); + wdt_hal_init(&rwdt_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); + wdt_hal_write_protect_disable(&rwdt_ctx); + wdt_hal_config_stage(&rwdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC); + wdt_hal_enable(&rwdt_ctx); + wdt_hal_write_protect_enable(&rwdt_ctx); #endif //Disable MWDT0 flashboot protection. But only after we've enabled the RWDT first so that there's not gap in WDT protection. - 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); + wdt_hal_context_t mwdt_ctx = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0}; + wdt_hal_write_protect_disable(&mwdt_ctx); + wdt_hal_set_flashboot_en(&mwdt_ctx, false); + wdt_hal_write_protect_enable(&mwdt_ctx); } void bootloader_enable_random(void) diff --git a/components/bootloader_support/src/bootloader_mem.c b/components/bootloader_support/src/bootloader_mem.c index 1b45c2b5c7..397d1b47d7 100644 --- a/components/bootloader_support/src/bootloader_mem.c +++ b/components/bootloader_support/src/bootloader_mem.c @@ -12,8 +12,21 @@ #include "bootloader_mem.h" #include "esp_cpu.h" +#if CONFIG_IDF_TARGET_ESP32C6 +#include "soc/hp_apm_reg.h" +#include "soc/lp_apm_reg.h" +#include "soc/lp_apm0_reg.h" +#endif + void bootloader_init_mem(void) { +#if CONFIG_IDF_TARGET_ESP32C6 + // disable apm filter // TODO: IDF-5909 + REG_WRITE(LP_APM_FUNC_CTRL_REG, 0); + REG_WRITE(LP_APM0_FUNC_CTRL_REG, 0); + REG_WRITE(HP_APM_FUNC_CTRL_REG, 0); +#endif + #ifdef CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE // protect memory region esp_cpu_configure_region_protection(); diff --git a/components/bootloader_support/src/bootloader_random_esp32c6.c b/components/bootloader_support/src/bootloader_random_esp32c6.c index e69de29bb2..378e84744e 100644 --- a/components/bootloader_support/src/bootloader_random_esp32c6.c +++ b/components/bootloader_support/src/bootloader_random_esp32c6.c @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "sdkconfig.h" +#include "bootloader_random.h" +#include "esp_log.h" + +static const char *TAG = "bootloader_random"; + +void bootloader_random_enable(void) +{ + // TODO: IDF-5352 + ESP_EARLY_LOGW(TAG, "bootloader_random_enable() has not been implemented yet"); +} + +void bootloader_random_disable(void) +{ + // TODO: IDF-5352 + ESP_EARLY_LOGW(TAG, "bootloader_random_enable() has not been implemented yet"); +} diff --git a/components/bootloader_support/src/bootloader_utility.c b/components/bootloader_support/src/bootloader_utility.c index ba059f54b4..7e094426bd 100644 --- a/components/bootloader_support/src/bootloader_utility.c +++ b/components/bootloader_support/src/bootloader_utility.c @@ -41,6 +41,13 @@ #include "esp32c2/rom/uart.h" #include "esp32c2/rom/gpio.h" #include "esp32c2/rom/secure_boot.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rom/efuse.h" +#include "esp32c6/rom/crc.h" +#include "esp32c6/rom/rtc.h" +#include "esp32c6/rom/uart.h" +#include "esp32c6/rom/gpio.h" +#include "esp32c6/rom/secure_boot.h" #else // CONFIG_IDF_TARGET_* #error "Unsupported IDF_TARGET" diff --git a/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c b/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c new file mode 100644 index 0000000000..8c104aa34a --- /dev/null +++ b/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c @@ -0,0 +1,344 @@ +/* + * SPDX-FileCopyrightText: 2022 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 "esp_rom_spiflash.h" +#include "soc/gpio_sig_map.h" +#include "soc/io_mux_reg.h" +#include "soc/assist_debug_reg.h" +#include "esp_cpu.h" +#include "soc/rtc.h" +#include "soc/spi_periph.h" +#include "soc/extmem_reg.h" +#include "soc/io_mux_reg.h" +#include "soc/pcr_reg.h" +#include "esp32c6/rom/efuse.h" +#include "esp32c6/rom/ets_sys.h" +#include "bootloader_common.h" +#include "bootloader_init.h" +#include "bootloader_clock.h" +#include "bootloader_flash_config.h" +#include "bootloader_mem.h" +#include "esp_private/regi2c_ctrl.h" +#include "soc/regi2c_lp_bias.h" +#include "soc/regi2c_bias.h" +#include "bootloader_console.h" +#include "bootloader_flash_priv.h" +#include "bootloader_soc.h" +#include "esp_efuse.h" +#include "hal/mmu_hal.h" +#include "hal/cache_hal.h" +#include "soc/lp_wdt_reg.h" +#include "hal/efuse_hal.h" + +static const char *TAG = "boot.esp32c6"; + +void IRAM_ATTR bootloader_configure_spi_pins(int drv) +{ + // TODO: IDF-5649 + const uint32_t spiconfig = 0; + 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) { + + } + 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 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_hal_disable(CACHE_TYPE_ALL); + // 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_hal_enable(CACHE_TYPE_ALL); +} + +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_DIV_2: + str = "40MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_3: + str = "26.7MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_4: + str = "20MHz"; + break; + case ESP_IMAGE_SPI_SPEED_DIV_1: + 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(); +// TODO: IDF-5649 +// #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(); + bootloader_flash_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(PCR_ASSIST_CONF_REG, PCR_ASSIST_CLK_EN); + REG_CLR_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_RST_EN); + 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; + soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0); + if (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 || rst_reason == RESET_REASON_CORE_MWDT1 || + rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_MWDT1 || rst_reason == RESET_REASON_CPU0_RTC_WDT) { + 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(LP_WDT_WPROTECT_REG, RTC_CNTL_SWD_WKEY_VALUE); + REG_SET_BIT(LP_WDT_SWD_CONFIG_REG, LP_WDT_SWD_AUTO_FEED_EN); + REG_WRITE(LP_WDT_WPROTECT_REG, 0); +} + +static inline void bootloader_hardware_init(void) +{ + // TODO: IDF-5990 copied from C3, need update + // This check is always included in the bootloader so it can + // print the minimum revision error message later in the boot + if (efuse_hal_get_minor_chip_version() < 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_ana_reset_config(void) +{ + // TODO: IDF-5990 copied from C3, need update + /* + esp32c6 has removed super wdt! + 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 = efuse_hal_get_minor_chip_version(); + switch (chip_version) { + case 0: + case 1: + //Disable BOR and GLITCH reset + bootloader_ana_bod_reset_config(false); + bootloader_ana_clock_glitch_reset_config(false); + break; + case 2: + //Enable BOR reset. Disable GLITCH reset + bootloader_ana_bod_reset_config(true); + bootloader_ana_clock_glitch_reset_config(false); + break; + case 3: + default: + //Enable BOR, and GLITCH reset + bootloader_ana_bod_reset_config(true); + bootloader_ana_clock_glitch_reset_config(true); + break; + } +} + +esp_err_t bootloader_init(void) +{ + esp_err_t ret = ESP_OK; + + bootloader_hardware_init(); + bootloader_ana_reset_config(); + 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(); + // init eFuse virtual mode (read eFuses to RAM) +#ifdef CONFIG_EFUSE_VIRTUAL + ESP_LOGW(TAG, "eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!"); +#ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH + esp_efuse_init_virtual_mode_in_ram(); +#endif +#endif + //init cache hal + cache_hal_init(); + //reset mmu + mmu_hal_init(); + // 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(); + // Check and run XMC startup flow + if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) { + ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); + goto err; + } + // 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/esp32c6/bootloader_sha.c b/components/bootloader_support/src/esp32c6/bootloader_sha.c new file mode 100644 index 0000000000..716f143cb0 --- /dev/null +++ b/components/bootloader_support/src/esp32c6/bootloader_sha.c @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "bootloader_sha.h" +#include +#include +#include +#include + +#include "esp32c6/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/esp32c6/bootloader_soc.c b/components/bootloader_support/src/esp32c6/bootloader_soc.c new file mode 100644 index 0000000000..77a8d2176a --- /dev/null +++ b/components/bootloader_support/src/esp32c6/bootloader_soc.c @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "soc/soc.h" +#include "soc/lp_analog_peri_reg.h" + +void bootloader_ana_bod_reset_config(bool enable) +{ + REG_CLR_BIT(LP_ANALOG_PERI_LP_ANA_FIB_ENABLE_REG, LP_ANALOG_PERI_LP_ANA_FIB_BOR_RST); + if (enable) { + REG_SET_BIT(LP_ANALOG_PERI_LP_ANA_BOD_MODE1_CNTL_REG, LP_ANALOG_PERI_LP_ANA_BOD_MODE1_RESET_ENA); + } else { + REG_CLR_BIT(LP_ANALOG_PERI_LP_ANA_BOD_MODE1_CNTL_REG, LP_ANALOG_PERI_LP_ANA_BOD_MODE1_RESET_ENA); + } +} + +void bootloader_ana_clock_glitch_reset_config(bool enable) +{ + REG_CLR_BIT(LP_ANALOG_PERI_LP_ANA_FIB_ENABLE_REG, LP_ANALOG_PERI_LP_ANA_FIB_GLITCH_RST); + if (enable) { + REG_SET_BIT(LP_ANALOG_PERI_LP_ANA_CK_GLITCH_CNTL_REG, LP_ANALOG_PERI_LP_ANA_CK_GLITCH_RESET_ENA); + } else { + REG_CLR_BIT(LP_ANALOG_PERI_LP_ANA_CK_GLITCH_CNTL_REG, LP_ANALOG_PERI_LP_ANA_CK_GLITCH_RESET_ENA); + } +} diff --git a/components/bootloader_support/src/esp32c6/flash_encryption_secure_features.c b/components/bootloader_support/src/esp32c6/flash_encryption_secure_features.c new file mode 100644 index 0000000000..3f64dbfd3d --- /dev/null +++ b/components/bootloader_support/src/esp32c6/flash_encryption_secure_features.c @@ -0,0 +1,50 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_flash_encrypt.h" +#include "esp_secure_boot.h" +#include "esp_efuse.h" +#include "esp_efuse_table.h" +#include "esp_log.h" +#include "sdkconfig.h" + +static __attribute__((unused)) const char *TAG = "flash_encrypt"; + +esp_err_t esp_flash_encryption_enable_secure_features(void) +{ +#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_DIRECT_BOOT); + +#if defined(CONFIG_SECURE_BOOT_V2_ENABLED) && !defined(CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS) + // This bit is set when enabling Secure Boot V2, but we can't enable it until this later point in the first boot + // otherwise the Flash Encryption key cannot be read protected + esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS); +#endif + + return ESP_OK; +} diff --git a/components/bootloader_support/src/esp32c6/secure_boot_secure_features.c b/components/bootloader_support/src/esp32c6/secure_boot_secure_features.c new file mode 100644 index 0000000000..9ea0f69e4b --- /dev/null +++ b/components/bootloader_support/src/esp32c6/secure_boot_secure_features.c @@ -0,0 +1,70 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_flash_encrypt.h" +#include "esp_secure_boot.h" +#include "esp_efuse.h" +#include "esp_efuse_table.h" +#include "esp_log.h" +#include "sdkconfig.h" + +static __attribute__((unused)) const char *TAG = "secure_boot"; + +esp_err_t esp_secure_boot_enable_secure_features(void) +{ + esp_efuse_write_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT); + +#ifdef CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE + ESP_LOGI(TAG, "Enabling Security download mode..."); + esp_err_t err = esp_efuse_enable_rom_secure_download_mode(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Could not enable Security download mode..."); + return err; + } +#elif CONFIG_SECURE_DISABLE_ROM_DL_MODE + ESP_LOGI(TAG, "Disable ROM Download mode..."); + esp_err_t err = esp_efuse_disable_rom_download_mode(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Could not disable ROM Download mode..."); + return err; + } +#else + ESP_LOGW(TAG, "UART ROM Download mode kept enabled - 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_cnt(ESP_EFUSE_SOFT_DIS_JTAG, ESP_EFUSE_SOFT_DIS_JTAG[0]->bit_count); +#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); + +#ifndef CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS + bool rd_dis_now = true; +#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED + /* If flash encryption is not enabled yet then don't read-disable efuses yet, do it later in the boot + when Flash Encryption is being enabled */ + rd_dis_now = esp_flash_encryption_enabled(); +#endif + if (rd_dis_now) { + ESP_LOGI(TAG, "Prevent read disabling of additional efuses..."); + esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS); + } +#else + ESP_LOGW(TAG, "Allowing read disabling of additional efuses - SECURITY COMPROMISED"); +#endif + + return ESP_OK; +} diff --git a/components/bootloader_support/src/esp_image_format.c b/components/bootloader_support/src/esp_image_format.c index 67105299ff..c46e698eed 100644 --- a/components/bootloader_support/src/esp_image_format.c +++ b/components/bootloader_support/src/esp_image_format.c @@ -34,6 +34,9 @@ #elif CONFIG_IDF_TARGET_ESP32C2 #include "esp32c2/rom/rtc.h" #include "esp32c2/rom/secure_boot.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rom/rtc.h" +#include "esp32c6/rom/secure_boot.h" #endif #define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) diff --git a/components/bootloader_support/src/flash_encrypt.c b/components/bootloader_support/src/flash_encrypt.c index 9405e5ac68..e6f789f1ef 100644 --- a/components/bootloader_support/src/flash_encrypt.c +++ b/components/bootloader_support/src/flash_encrypt.c @@ -142,7 +142,7 @@ esp_flash_enc_mode_t esp_get_flash_encryption_mode(void) if (dis_dl_enc && dis_dl_icache && dis_dl_dcache) { mode = ESP_FLASH_ENC_MODE_RELEASE; } -#elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 +#elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C6 bool dis_dl_enc = esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT); bool dis_dl_icache = esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_ICACHE); if (dis_dl_enc && dis_dl_icache) { @@ -191,7 +191,7 @@ void esp_flash_encryption_set_release_mode(void) esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT); esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_ICACHE); esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_DCACHE); -#elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 +#elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C6 esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT); esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_ICACHE); #ifdef CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_128_DERIVED diff --git a/components/bootloader_support/src/flash_encryption/flash_encrypt.c b/components/bootloader_support/src/flash_encryption/flash_encrypt.c index 0256a6ebdd..8ff0e27a3d 100644 --- a/components/bootloader_support/src/flash_encryption/flash_encrypt.c +++ b/components/bootloader_support/src/flash_encryption/flash_encrypt.c @@ -429,7 +429,11 @@ esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length) return ESP_FAIL; } +#if CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5653 + wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &LP_WDT}; +#else wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL}; +#endif 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);