espressif: ESP32-H2 initial support
Signed-off-by: Almir Okato <almir.okato@espressif.com>
diff --git a/boot/espressif/CMakeLists.txt b/boot/espressif/CMakeLists.txt
index cbafa74..3bfb367 100644
--- a/boot/espressif/CMakeLists.txt
+++ b/boot/espressif/CMakeLists.txt
@@ -21,7 +21,8 @@
"${MCUBOOT_TARGET}" STREQUAL "esp32s3")
set(MCUBOOT_ARCH "xtensa")
elseif("${MCUBOOT_TARGET}" STREQUAL "esp32c3" OR
- "${MCUBOOT_TARGET}" STREQUAL "esp32c6")
+ "${MCUBOOT_TARGET}" STREQUAL "esp32c6" OR
+ "${MCUBOOT_TARGET}" STREQUAL "esp32h2")
set(MCUBOOT_ARCH "riscv")
endif()
@@ -36,6 +37,8 @@
set(ESP_MIN_REVISION 3)
elseif("${MCUBOOT_TARGET}" STREQUAL "esp32c6")
set(ESP_MIN_REVISION 0)
+elseif("${MCUBOOT_TARGET}" STREQUAL "esp32h2")
+ set(ESP_MIN_REVISION 0)
else()
message(FATAL_ERROR "Unsupported target ${MCUBOOT_TARGET}")
endif()
@@ -115,6 +118,8 @@
"${MCUBOOT_TARGET}" STREQUAL "esp32c3" OR
"${MCUBOOT_TARGET}" STREQUAL "esp32c6")
set(ESP_FLASH_FREQ "40m")
+ elseif("${MCUBOOT_TARGET}" STREQUAL "esp32h2")
+ set(ESP_FLASH_FREQ "24m")
endif()
endif()
diff --git a/boot/espressif/hal/include/esp32h2/esp32h2.cmake b/boot/espressif/hal/include/esp32h2/esp32h2.cmake
new file mode 100644
index 0000000..9160eab
--- /dev/null
+++ b/boot/espressif/hal/include/esp32h2/esp32h2.cmake
@@ -0,0 +1,32 @@
+# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+#
+# SPDX-License-Identifier: Apache-2.0
+
+list(APPEND include_dirs
+ ${esp_hal_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/private_include
+)
+
+list(APPEND hal_srcs
+ ${esp_hal_dir}/components/hal/cache_hal.c
+ ${esp_hal_dir}/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c
+ ${esp_hal_dir}/components/esp_rom/patches/esp_rom_regi2c_${MCUBOOT_TARGET}.c
+)
+
+if (DEFINED CONFIG_ESP_CONSOLE_UART_CUSTOM)
+ list(APPEND hal_srcs
+ ${src_dir}/${MCUBOOT_TARGET}/console_uart_custom.c
+ )
+endif()
+
+list(APPEND LINKER_SCRIPTS
+ -T${esp_hal_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.newlib.ld
+)
+
+set_source_files_properties(
+ ${esp_hal_dir}/components/bootloader_support/src/esp_image_format.c
+ ${esp_hal_dir}/components/bootloader_support/bootloader_flash/src/bootloader_flash.c
+ ${esp_hal_dir}/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_${MCUBOOT_TARGET}.c
+ ${esp_hal_dir}/components/hal/mmu_hal.c
+ ${esp_hal_dir}/components/hal/cache_hal.c
+ PROPERTIES COMPILE_FLAGS
+ "-Wno-logical-op")
diff --git a/boot/espressif/hal/include/esp32h2/sdkconfig.h b/boot/espressif/hal/include/esp32h2/sdkconfig.h
new file mode 100644
index 0000000..84cbc5b
--- /dev/null
+++ b/boot/espressif/hal/include/esp32h2/sdkconfig.h
@@ -0,0 +1,31 @@
+/*
+ * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#define BOOTLOADER_BUILD 1
+#define CONFIG_IDF_FIRMWARE_CHIP_ID 0x0010
+#define CONFIG_IDF_TARGET_ESP32H2 1
+#define CONFIG_ESP32H2_REV_MIN_0 1
+#define CONFIG_ESP32H2_REV_MIN_FULL 0
+#define CONFIG_ESP_REV_MIN_FULL CONFIG_ESP32H2_REV_MIN_FULL
+#define CONFIG_ESP32H2_REV_MIN 0
+#define CONFIG_ESP32H2_REV_MAX_FULL 99
+#define CONFIG_ESP_REV_MAX_FULL CONFIG_ESP32H2_REV_MAX_FULL
+#define CONFIG_IDF_TARGET_ARCH_RISCV 1
+#define CONFIG_MMU_PAGE_SIZE 0x10000
+#define SOC_MMU_PAGE_SIZE CONFIG_MMU_PAGE_SIZE /* from soc/CMakeLists */
+#define CONFIG_XTAL_FREQ_32 1
+#define CONFIG_XTAL_FREQ 32
+#define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1
+#define CONFIG_MCUBOOT 1
+#define NDEBUG 1
+#define CONFIG_BOOTLOADER_WDT_TIME_MS 9000
+#define CONFIG_ESP_CONSOLE_UART_BAUDRATE 115200
+#define CONFIG_BOOTLOADER_OFFSET_IN_FLASH 0x0000
+#define CONFIG_PARTITION_TABLE_OFFSET 0x10000
+#define CONFIG_EFUSE_VIRTUAL_OFFSET 0x250000
+#define CONFIG_EFUSE_VIRTUAL_SIZE 0x2000
+#define CONFIG_EFUSE_MAX_BLK_LEN 256
+#define CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT 1
diff --git a/boot/espressif/hal/include/mcuboot_config/mcuboot_logging.h b/boot/espressif/hal/include/mcuboot_config/mcuboot_logging.h
index 31b793c..680bc79 100644
--- a/boot/espressif/hal/include/mcuboot_config/mcuboot_logging.h
+++ b/boot/espressif/hal/include/mcuboot_config/mcuboot_logging.h
@@ -27,6 +27,8 @@
#define TARGET "[esp32c3]"
#elif CONFIG_IDF_TARGET_ESP32C6
#define TARGET "[esp32c6]"
+#elif CONFIG_IDF_TARGET_ESP32H2
+#define TARGET "[esp32h2]"
#else
#error "Selected target not supported."
#endif
diff --git a/boot/espressif/hal/src/esp32h2/console_uart_custom.c b/boot/espressif/hal/src/esp32h2/console_uart_custom.c
new file mode 100644
index 0000000..e006709
--- /dev/null
+++ b/boot/espressif/hal/src/esp32h2/console_uart_custom.c
@@ -0,0 +1,21 @@
+/*
+ * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <esp_rom_uart.h>
+#include <hal/uart_ll.h>
+#include <soc/uart_periph.h>
+
+#if CONFIG_ESP_CONSOLE_UART_CUSTOM
+static uart_dev_t *alt_console_uart_dev = (CONFIG_ESP_CONSOLE_UART_NUM == 0) ?
+ &UART0 :
+ &UART1;
+
+void IRAM_ATTR esp_rom_uart_putc(char c)
+{
+ while (uart_ll_get_txfifo_len(alt_console_uart_dev) == 0);
+ uart_ll_write_txfifo(alt_console_uart_dev, (const uint8_t *) &c, 1);
+}
+#endif
diff --git a/boot/espressif/port/esp32h2/bootloader.conf b/boot/espressif/port/esp32h2/bootloader.conf
new file mode 100644
index 0000000..5c5307c
--- /dev/null
+++ b/boot/espressif/port/esp32h2/bootloader.conf
@@ -0,0 +1,88 @@
+# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+#
+# SPDX-License-Identifier: Apache-2.0
+
+CONFIG_ESP_FLASH_SIZE=4MB
+CONFIG_ESP_BOOTLOADER_SIZE=0xF000
+CONFIG_ESP_BOOTLOADER_OFFSET=0x0000
+CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS=0x10000
+CONFIG_ESP_APPLICATION_SIZE=0x100000
+CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS=0x110000
+CONFIG_ESP_MCUBOOT_WDT_ENABLE=y
+CONFIG_ESP_SCRATCH_OFFSET=0x210000
+CONFIG_ESP_SCRATCH_SIZE=0x40000
+
+# When enabled, prevents updating image to an older version
+# CONFIG_ESP_DOWNGRADE_PREVENTION=y
+# This option makes downgrade prevention rely also on security
+# counter (defined using imgtool) instead of only image version
+# CONFIG_ESP_DOWNGRADE_PREVENTION_SECURITY_COUNTER=y
+
+# Enables the MCUboot Serial Recovery, that allows the use of
+# MCUMGR to upload a firmware through the serial port
+# CONFIG_ESP_MCUBOOT_SERIAL=y
+# Use Serial through USB JTAG Serial port for Serial Recovery
+# CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG=y
+# Use sector erasing (recommended) instead of entire image size
+# erasing when uploading through Serial Recovery
+# CONFIG_ESP_MCUBOOT_ERASE_PROGRESSIVELY=y
+
+# GPIO used to boot on Serial Recovery
+# CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT=5
+# GPIO input type (0 for Pull-down, 1 for Pull-up)
+# CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE=0
+# GPIO signal value
+# CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL=1
+# Delay time for identify the GPIO signal
+# CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S=5
+# UART port used for serial communication (not needed when using USB)
+# CONFIG_ESP_SERIAL_BOOT_UART_NUM=1
+# GPIO for Serial RX signal
+# CONFIG_ESP_SERIAL_BOOT_GPIO_RX=8
+# GPIO for Serial TX signal
+# CONFIG_ESP_SERIAL_BOOT_GPIO_TX=9
+
+# Use UART0 for console printing (use either UART or USB alone)
+CONFIG_ESP_CONSOLE_UART=y
+CONFIG_ESP_CONSOLE_UART_NUM=0
+# Configures alternative UART port for console printing
+# (UART_NUM=0 must not be changed)
+# CONFIG_ESP_CONSOLE_UART_CUSTOM=y
+# CONFIG_ESP_CONSOLE_UART_TX_GPIO=9
+# CONFIG_ESP_CONSOLE_UART_RX_GPIO=8
+# Use USB JTAG Serial for console printing
+# CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
+
+# CONFIG_ESP_SIGN_EC256=y
+# CONFIG_ESP_SIGN_ED25519=n
+# CONFIG_ESP_SIGN_RSA=n
+# CONFIG_ESP_SIGN_RSA_LEN=2048
+
+# Use Tinycrypt lib for EC256 or ED25519 signing
+# CONFIG_ESP_USE_TINYCRYPT=y
+# Use Mbed TLS lib for RSA image signing
+# CONFIG_ESP_USE_MBEDTLS=n
+
+# It is strongly recommended to generate a new signing key
+# using imgtool instead of use the existent sample
+# CONFIG_ESP_SIGN_KEY_FILE=root-ec-p256.pem
+
+# Hardware Secure Boot related options
+# CONFIG_SECURE_SIGNED_ON_BOOT=1
+# CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME=1
+# CONFIG_SECURE_BOOT=1
+# CONFIG_SECURE_BOOT_V2_ENABLED=1
+# CONFIG_SECURE_BOOT_SUPPORTS_RSA=1
+
+# Hardware Flash Encryption related options
+# CONFIG_SECURE_FLASH_ENC_ENABLED=1
+# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=1
+# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=1
+# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=1
+# CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=1
+# CONFIG_SECURE_BOOT_ALLOW_JTAG=1
+# CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=1
+
+# Options for enabling eFuse emulation in Flash
+# CONFIG_EFUSE_VIRTUAL=1
+# CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=1
diff --git a/boot/espressif/port/esp32h2/ld/bootloader.ld b/boot/espressif/port/esp32h2/ld/bootloader.ld
new file mode 100644
index 0000000..fa6d26f
--- /dev/null
+++ b/boot/espressif/port/esp32h2/ld/bootloader.ld
@@ -0,0 +1,212 @@
+/*
+ * SPDX-FileCopyrightText: 2023 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.
+ *
+ * ESP32-H2 ROM static data usage is as follows:
+ * - 0x4083ba78 - 0x4084d380: Shared buffers, used in UART/USB/SPI download mode only
+ * - 0x4084d380 - 0x4084f380: PRO CPU stack, can be reclaimed as heap after RTOS startup
+ * - 0x4084f380 - 0x4084fee0: ROM .bss and .data used in startup code or nonos/early boot (can be freed when IDF runs)
+ * - 0x4084fee0 - 0x40850000: ROM .bss and .data used in startup code and when IDF runs (cannot be freed)
+ *
+ * The 2nd stage bootloader can take space up to the end of ROM shared
+ * buffers area (0x4084d380).
+ */
+
+/* We consider 0x3fcdc710 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg,
+ * and work out iram_seg and iram_loader_seg addresses from there, backwards.
+ */
+
+/* These lengths can be adjusted, if necessary: */
+bootloader_usable_dram_end = 0x4084cfd0;
+bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */
+bootloader_dram_seg_len = 0x5000;
+bootloader_iram_loader_seg_len = 0x7000;
+bootloader_iram_seg_len = 0x3000;
+
+/* Start of the lower region is determined by region size and the end of the higher region */
+bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead;
+bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len;
+bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len;
+bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len;
+
+MEMORY
+{
+ iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len
+ iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len
+ dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len
+}
+
+/* The app may use RAM for static allocations up to the start of iram_loader_seg.
+ * If you have changed something above and this assert fails:
+ * 1. Check what the new value of bootloader_iram_loader_seg start is.
+ * 2. Update the value in this assert.
+ * 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32h2/memory.ld.in to the same value.
+ */
+ASSERT(bootloader_iram_loader_seg_start == 0x4083EFD0, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END");
+
+/* Default entry point: */
+ENTRY(main);
+
+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 */
+ *libhal.a:bootloader_flash.*(.literal .text .literal.* .text.*)
+ *libhal.a:bootloader_flash_config_esp32h2.*(.literal .text .literal.* .text.*)
+ *libhal.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*)
+ *libhal.a:bootloader_init.*(.literal .text .literal.* .text.*)
+ *libhal.a:bootloader_common.*(.literal .text .literal.* .text.*)
+ *libhal.a:bootloader_common_loader.*(.literal .text .literal.* .text.*)
+ *libhal.a:bootloader_random.*(.literal .text .literal.* .text.*)
+ *libhal.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable)
+ *libhal.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable)
+ *libhal.a:bootloader_efuse.*(.literal .text .literal.* .text.*)
+ *libhal.a:bootloader_utility.*(.literal .text .literal.* .text.*)
+ *libhal.a:bootloader_sha.*(.literal .text .literal.* .text.*)
+ *libhal.a:bootloader_console.*(.literal .text .literal.* .text.*)
+ *libhal.a:bootloader_console_loader.*(.literal .text .literal.* .text.*)
+ *libhal.a:bootloader_panic.*(.literal .text .literal.* .text.*)
+ *libhal.a:bootloader_soc.*(.literal .text .literal.* .text.*)
+ *libhal.a:esp_image_format.*(.literal .text .literal.* .text.*)
+ *libhal.a:flash_encrypt.*(.literal .text .literal.* .text.*)
+ *libhal.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*)
+ *libhal.a:flash_partitions.*(.literal .text .literal.* .text.*)
+ *libhal.a:secure_boot.*(.literal .text .literal.* .text.*)
+ *libhal.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*)
+ *libhal.a:secure_boot_signatures_bootloader.*(.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.*)
+ *libhal.a:esp_efuse_table.*(.literal .text .literal.* .text.*)
+ *libhal.a:esp_efuse_fields.*(.literal .text .literal.* .text.*)
+ *libhal.a:esp_efuse_api.*(.literal .text .literal.* .text.*)
+ *libhal.a:esp_efuse_utility.*(.literal .text .literal.* .text.*)
+ *libhal.a:esp_efuse_api_key.*(.literal .text .literal.* .text.*)
+ *libhal.a:rtc_clk.*(.literal .text .literal.* .text.*)
+ *libhal.a:rtc_time.*(.literal .text .literal.* .text.*)
+ *libhal.a:regi2c_ctrl.*(.literal .text .literal.* .text.*)
+ *esp_mcuboot.*(.literal .text .literal.* .text.*)
+ *esp_loader.*(.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)
+ _text_end = ABSOLUTE(.);
+ _etext = .;
+ } > iram_seg
+
+}
diff --git a/boot/espressif/port/esp32h2/serial_adapter.c b/boot/espressif/port/esp32h2/serial_adapter.c
new file mode 100644
index 0000000..09643a1
--- /dev/null
+++ b/boot/espressif/port/esp32h2/serial_adapter.c
@@ -0,0 +1,226 @@
+/*
+ * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <bootutil/bootutil_log.h>
+
+#include <esp_rom_uart.h>
+#include <esp_rom_gpio.h>
+#include <esp_rom_sys.h>
+#include <esp_rom_caps.h>
+#include <soc/uart_periph.h>
+#include <soc/gpio_struct.h>
+#include <soc/io_mux_reg.h>
+#include <soc/rtc.h>
+#include <hal/gpio_types.h>
+#include <hal/gpio_ll.h>
+#include <hal/uart_ll.h>
+#include <hal/clk_gate_ll.h>
+#include <hal/usb_serial_jtag_ll.h>
+#include <hal/gpio_hal.h>
+
+#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT
+#define SERIAL_BOOT_GPIO_DETECT CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT
+#else
+#define SERIAL_BOOT_GPIO_DETECT GPIO_NUM_5
+#endif
+
+#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL
+#define SERIAL_BOOT_GPIO_DETECT_VAL CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL
+#else
+#define SERIAL_BOOT_GPIO_DETECT_VAL 1
+#endif
+
+#ifdef CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S
+#define SERIAL_BOOT_DETECT_DELAY_S CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S
+#else
+#define SERIAL_BOOT_DETECT_DELAY_S 5
+#endif
+
+#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE
+#define SERIAL_BOOT_GPIO_INPUT_TYPE CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE
+#else
+// pull-down
+#define SERIAL_BOOT_GPIO_INPUT_TYPE 0
+#endif
+
+#ifndef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG
+
+#ifdef CONFIG_ESP_SERIAL_BOOT_UART_NUM
+#define SERIAL_BOOT_UART_NUM CONFIG_ESP_SERIAL_BOOT_UART_NUM
+#else
+#define SERIAL_BOOT_UART_NUM ESP_ROM_UART_1
+#endif
+
+#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_RX
+#define SERIAL_BOOT_GPIO_RX CONFIG_ESP_SERIAL_BOOT_GPIO_RX
+#else
+#define SERIAL_BOOT_GPIO_RX GPIO_NUM_8
+#endif
+
+#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_TX
+#define SERIAL_BOOT_GPIO_TX CONFIG_ESP_SERIAL_BOOT_GPIO_TX
+#else
+#define SERIAL_BOOT_GPIO_TX GPIO_NUM_9
+#endif
+
+static uart_dev_t *serial_boot_uart_dev = (SERIAL_BOOT_UART_NUM == 0) ?
+ &UART0 :
+ &UART1;
+
+#endif
+
+void console_write(const char *str, int cnt)
+{
+#ifdef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG
+ usb_serial_jtag_ll_txfifo_flush();
+ while (!usb_serial_jtag_ll_txfifo_writable()) {
+ MCUBOOT_WATCHDOG_FEED();
+ }
+ usb_serial_jtag_ll_write_txfifo((const uint8_t *)str, cnt);
+ usb_serial_jtag_ll_txfifo_flush();
+#else
+ uint32_t tx_len;
+ uint32_t write_len;
+
+ do {
+ tx_len = uart_ll_get_txfifo_len(serial_boot_uart_dev);
+ if (tx_len > 0) {
+ write_len = tx_len < cnt ? tx_len : cnt;
+ uart_ll_write_txfifo(serial_boot_uart_dev, (const uint8_t *)str, write_len);
+ cnt -= write_len;
+ }
+ MCUBOOT_WATCHDOG_FEED();
+ esp_rom_delay_us(1000);
+ } while (cnt > 0);
+#endif
+}
+
+int console_read(char *str, int cnt, int *newline)
+{
+#ifdef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG
+ uint32_t read_len = 0;
+
+ esp_rom_delay_us(1000);
+ do {
+ if (usb_serial_jtag_ll_rxfifo_data_available()) {
+ usb_serial_jtag_ll_read_rxfifo((uint8_t *)&str[read_len], 1);
+ read_len++;
+ }
+ MCUBOOT_WATCHDOG_FEED();
+ esp_rom_delay_us(1000);
+ } while (!(read_len == cnt || str[read_len - 1] == '\n'));
+ *newline = (str[read_len - 1] == '\n') ? 1 : 0;
+
+ return read_len;
+#else
+ uint32_t len = 0;
+ uint32_t read_len = 0;
+ bool stop = false;
+
+ do {
+ len = uart_ll_get_rxfifo_len(serial_boot_uart_dev);
+
+ if (len > 0) {
+ for (uint32_t i = 0; i < len; i++) {
+ /* Read the character from the RX FIFO */
+ uart_ll_read_rxfifo(serial_boot_uart_dev, (uint8_t *)&str[read_len], 1);
+ read_len++;
+ if (read_len == cnt - 1|| str[read_len - 1] == '\n') {
+ stop = true;
+ break;
+ }
+ }
+ }
+ MCUBOOT_WATCHDOG_FEED();
+ esp_rom_delay_us(1000);
+ } while (!stop);
+
+ *newline = (str[read_len - 1] == '\n') ? 1 : 0;
+ return read_len;
+#endif
+}
+
+int boot_console_init(void)
+{
+ BOOT_LOG_INF("Initializing serial boot pins");
+
+#ifdef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG
+ usb_serial_jtag_ll_txfifo_flush();
+ esp_rom_uart_tx_wait_idle(0);
+#else
+ /* Enable GPIO for UART RX */
+ esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_RX);
+ esp_rom_gpio_connect_in_signal(SERIAL_BOOT_GPIO_RX,
+ UART_PERIPH_SIGNAL(SERIAL_BOOT_UART_NUM, SOC_UART_RX_PIN_IDX),
+ 0);
+ gpio_ll_input_enable(&GPIO, SERIAL_BOOT_GPIO_RX);
+ esp_rom_gpio_pad_pullup_only(SERIAL_BOOT_GPIO_RX);
+
+
+ /* Enable GPIO for UART TX */
+ esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_TX);
+ esp_rom_gpio_connect_out_signal(SERIAL_BOOT_GPIO_TX,
+ UART_PERIPH_SIGNAL(SERIAL_BOOT_UART_NUM, SOC_UART_TX_PIN_IDX),
+ 0, 0);
+ gpio_ll_output_enable(&GPIO, SERIAL_BOOT_GPIO_TX);
+
+ uart_ll_set_sclk(serial_boot_uart_dev, UART_SCLK_APB);
+ uart_ll_set_mode_normal(serial_boot_uart_dev);
+ uart_ll_set_baudrate(serial_boot_uart_dev, 115200, UART_SCLK_APB);
+ uart_ll_set_stop_bits(serial_boot_uart_dev, 1u);
+ uart_ll_set_parity(serial_boot_uart_dev, UART_PARITY_DISABLE);
+ uart_ll_set_rx_tout(serial_boot_uart_dev, 16);
+ uart_ll_set_data_bit_num(serial_boot_uart_dev, UART_DATA_8_BITS);
+ uart_ll_set_tx_idle_num(serial_boot_uart_dev, 0);
+ uart_ll_set_hw_flow_ctrl(serial_boot_uart_dev, UART_HW_FLOWCTRL_DISABLE, 100);
+ periph_ll_enable_clk_clear_rst(PERIPH_UART0_MODULE + SERIAL_BOOT_UART_NUM);
+
+ uart_ll_txfifo_rst(serial_boot_uart_dev);
+ uart_ll_rxfifo_rst(serial_boot_uart_dev);
+ esp_rom_delay_us(50000);
+#endif
+
+ return 0;
+}
+
+bool boot_serial_detect_pin(void)
+{
+ bool detected = false;
+ int pin_value = 0;
+
+ esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_DETECT);
+ gpio_ll_input_enable(&GPIO, SERIAL_BOOT_GPIO_DETECT);
+ switch (SERIAL_BOOT_GPIO_INPUT_TYPE) {
+ // Pull-down
+ case 0:
+ gpio_ll_pulldown_en(&GPIO, SERIAL_BOOT_GPIO_DETECT);
+ break;
+ // Pull-up
+ case 1:
+ gpio_ll_pullup_en(&GPIO, SERIAL_BOOT_GPIO_DETECT);
+ break;
+ }
+ esp_rom_delay_us(50000);
+
+ pin_value = gpio_ll_get_level(&GPIO, SERIAL_BOOT_GPIO_DETECT);
+ detected = (pin_value == SERIAL_BOOT_GPIO_DETECT_VAL);
+ esp_rom_delay_us(50000);
+
+ if (detected) {
+ if (SERIAL_BOOT_DETECT_DELAY_S > 0) {
+ /* The delay time is an approximation */
+ for (int i = 0; i < (SERIAL_BOOT_DETECT_DELAY_S * 100); i++) {
+ esp_rom_delay_us(10000);
+ pin_value = gpio_ll_get_level(&GPIO, SERIAL_BOOT_GPIO_DETECT);
+ detected = (pin_value == SERIAL_BOOT_GPIO_DETECT_VAL);
+ if (!detected) {
+ break;
+ }
+ }
+ }
+ }
+ return detected;
+}
diff --git a/boot/espressif/tools/toolchain-esp32h2.cmake b/boot/espressif/tools/toolchain-esp32h2.cmake
new file mode 100644
index 0000000..0982a85
--- /dev/null
+++ b/boot/espressif/tools/toolchain-esp32h2.cmake
@@ -0,0 +1,13 @@
+# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+#
+# SPDX-License-Identifier: Apache-2.0
+
+set(CMAKE_SYSTEM_NAME Generic)
+
+set(CMAKE_C_COMPILER riscv32-esp-elf-gcc)
+set(CMAKE_CXX_COMPILER riscv32-esp-elf-g++)
+set(CMAKE_ASM_COMPILER riscv32-esp-elf-gcc)
+
+set(CMAKE_C_FLAGS "-march=rv32imc_zicsr_zifencei" CACHE STRING "C Compiler Base Flags")
+set(CMAKE_CXX_FLAGS "-march=rv32imc_zicsr_zifencei" CACHE STRING "C++ Compiler Base Flags")
+set(CMAKE_EXE_LINKER_FLAGS "-nostartfiles -march=rv32imc_zicsr_zifencei --specs=nosys.specs" CACHE STRING "Linker Base Flags")