Infineon: Switch to 1.9.0 code base, add xmc7000 family support, refactor memory layer
diff --git a/boot/espressif/CMakeLists.txt b/boot/espressif/CMakeLists.txt
new file mode 100644
index 0000000..0aa9dc2
--- /dev/null
+++ b/boot/espressif/CMakeLists.txt
@@ -0,0 +1,237 @@
+# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+#
+# SPDX-License-Identifier: Apache-2.0
+
+cmake_minimum_required(VERSION 3.13)
+
+if (NOT DEFINED MCUBOOT_TARGET)
+    message(FATAL_ERROR "MCUBOOT_TARGET not defined. Please pass -DMCUBOOT_TARGET flag.")
+endif()
+
+project(mcuboot_${MCUBOOT_TARGET})
+
+add_definitions(-DMCUBOOT_TARGET=${MCUBOOT_TARGET})
+
+if ("${MCUBOOT_TARGET}" STREQUAL "esp32" OR
+    "${MCUBOOT_TARGET}" STREQUAL "esp32s2" OR
+    "${MCUBOOT_TARGET}" STREQUAL "esp32s3")
+    set(MCUBOOT_ARCH "xtensa")
+elseif("${MCUBOOT_TARGET}" STREQUAL "esp32c3")
+    set(MCUBOOT_ARCH "riscv")
+endif()
+
+if (NOT DEFINED IDF_PATH)
+    if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/hal/esp-idf")
+        set(IDF_PATH "${CMAKE_CURRENT_LIST_DIR}/hal/esp-idf")
+    elseif (DEFINED ENV{IDF_PATH})
+        set(IDF_PATH $ENV{IDF_PATH})
+    else()
+        message(FATAL_ERROR "IDF_PATH not found. Please update submodules or set IDF_PATH environment variable or pass -DIDF_PATH flag.")
+    endif()
+endif()
+
+execute_process(
+    COMMAND git describe --tags
+    WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
+    OUTPUT_VARIABLE MCUBOOT_VER
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+    )
+add_definitions(-DMCUBOOT_VER=\"${MCUBOOT_VER}\")
+
+if (DEFINED MCUBOOT_CONFIG_FILE)
+    set(mcuboot_config_file ${MCUBOOT_CONFIG_FILE})
+else()
+    set(mcuboot_config_file "${CMAKE_CURRENT_LIST_DIR}/bootloader.conf")
+endif()
+
+if (NOT EXISTS "${mcuboot_config_file}")
+    message(FATAL_ERROR "MCUboot configuration file does not exist at ${mcuboot_config_file}")
+endif()
+
+configure_file(${mcuboot_config_file} dummy.conf)
+file(STRINGS ${mcuboot_config_file} BOOTLOADER_CONF)
+foreach(config ${BOOTLOADER_CONF})
+    if (NOT (${config} MATCHES "#"))
+        string(REGEX REPLACE "^[ ]+" "" config ${config})
+        string(REGEX MATCH "^[^=]+" CONFIG_NAME ${config})
+        string(REPLACE "${CONFIG_NAME}=" "" CONFIG_VALUE ${config})
+        if (NOT ("${CONFIG_VALUE}" STREQUAL "n"
+            OR "${CONFIG_VALUE}" STREQUAL "N"))
+            add_definitions(-D${CONFIG_NAME}=${CONFIG_VALUE})
+            set(${CONFIG_NAME} ${CONFIG_VALUE})
+        endif()
+    endif()
+endforeach()
+
+set(APP_NAME mcuboot_${MCUBOOT_TARGET})
+set(APP_EXECUTABLE ${APP_NAME}.elf)
+
+set(MCUBOOT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
+set(BOOTUTIL_DIR ${MCUBOOT_ROOT_DIR}/boot/bootutil)
+set(ESPRESSIF_PORT_DIR ${CMAKE_CURRENT_LIST_DIR})
+
+# Find imgtool.
+# Go with an explicitly installed imgtool first, falling
+# back to mcuboot/scripts/imgtool.py.
+find_program(IMGTOOL_COMMAND
+    NAMES imgtool imgtool.py
+    )
+if ("${IMGTOOL_COMMAND}" MATCHES "IMGTOOL_COMMAND-NOTFOUND")
+    set(imgtool_path "${MCUBOOT_ROOT_DIR}/scripts/imgtool.py")
+else()
+    set(imgtool_path "${IMGTOOL_COMMAND}")
+endif()
+
+if (DEFINED CONFIG_ESP_SIGN_RSA)
+    include(${CMAKE_CURRENT_LIST_DIR}/include/crypto_config/rsa.cmake)
+elseif (DEFINED CONFIG_ESP_SIGN_EC256)
+    include(${CMAKE_CURRENT_LIST_DIR}/include/crypto_config/ec256.cmake)
+elseif (DEFINED CONFIG_ESP_SIGN_ED25519)
+    include(${CMAKE_CURRENT_LIST_DIR}/include/crypto_config/ed25519.cmake)
+else()
+    # No signature verification
+    set(TINYCRYPT_DIR ${MCUBOOT_ROOT_DIR}/ext/tinycrypt/lib)
+    set(CRYPTO_INC
+        ${TINYCRYPT_DIR}/include
+        )
+    set(crypto_srcs
+        ${TINYCRYPT_DIR}/source/sha256.c
+        ${TINYCRYPT_DIR}/source/utils.c
+        )
+endif()
+
+if(DEFINED CONFIG_ESP_SIGN_KEY_FILE)
+    if(IS_ABSOLUTE ${CONFIG_ESP_SIGN_KEY_FILE})
+        set(KEY_FILE ${CONFIG_ESP_SIGN_KEY_FILE})
+    else()
+        set(KEY_FILE ${MCUBOOT_ROOT_DIR}/${CONFIG_ESP_SIGN_KEY_FILE})
+    endif()
+    message("MCUBoot bootloader key file: ${KEY_FILE}")
+
+    set(GENERATED_PUBKEY ${CMAKE_CURRENT_BINARY_DIR}/autogen-pubkey.c)
+        add_custom_command(
+            OUTPUT ${GENERATED_PUBKEY}
+            COMMAND
+            ${imgtool_path}
+            getpub
+            -k
+            ${KEY_FILE}
+            > ${GENERATED_PUBKEY}
+            DEPENDS ${KEY_FILE}
+        )
+    list(APPEND crypto_srcs ${GENERATED_PUBKEY})
+endif()
+
+set(bootutil_srcs
+    ${BOOTUTIL_DIR}/src/boot_record.c
+    ${BOOTUTIL_DIR}/src/bootutil_misc.c
+    ${BOOTUTIL_DIR}/src/bootutil_public.c
+    ${BOOTUTIL_DIR}/src/caps.c
+    ${BOOTUTIL_DIR}/src/encrypted.c
+    ${BOOTUTIL_DIR}/src/fault_injection_hardening.c
+    ${BOOTUTIL_DIR}/src/fault_injection_hardening_delay_rng_mbedtls.c
+    ${BOOTUTIL_DIR}/src/image_ec.c
+    ${BOOTUTIL_DIR}/src/image_ec256.c
+    ${BOOTUTIL_DIR}/src/image_ed25519.c
+    ${BOOTUTIL_DIR}/src/image_rsa.c
+    ${BOOTUTIL_DIR}/src/image_validate.c
+    ${BOOTUTIL_DIR}/src/loader.c
+    ${BOOTUTIL_DIR}/src/swap_misc.c
+    ${BOOTUTIL_DIR}/src/swap_move.c
+    ${BOOTUTIL_DIR}/src/swap_scratch.c
+    ${BOOTUTIL_DIR}/src/tlv.c
+    )
+
+set(CFLAGS
+    "-Wno-frame-address"
+    "-Wall"
+    "-Wextra"
+    "-W"
+    "-Wdeclaration-after-statement"
+    "-Wwrite-strings"
+    "-Wlogical-op"
+    "-Wshadow"
+    "-ffunction-sections"
+    "-fdata-sections"
+    "-fstrict-volatile-bitfields"
+    "-Werror=all"
+    "-Wno-error=unused-function"
+    "-Wno-error=unused-but-set-variable"
+    "-Wno-error=unused-variable"
+    "-Wno-error=deprecated-declarations"
+    "-Wno-unused-parameter"
+    "-Wno-sign-compare"
+    "-ggdb"
+    "-Os"
+    "-D_GNU_SOURCE"
+    "-std=gnu99"
+    "-Wno-old-style-declaration"
+    "-Wno-implicit-int"
+    "-Wno-declaration-after-statement"
+    )
+
+set(LDFLAGS
+    "-nostdlib"
+    "-Wno-frame-address"
+    "-Wl,--cref"
+    "-Wl,--Map=${APP_NAME}.map"
+    "-fno-rtti"
+    "-fno-lto"
+    "-Wl,--gc-sections"
+    "-Wl,--undefined=uxTopUsedPriority"
+    "-lm"
+    "-lgcc"
+    "-lgcov"
+    )
+
+if ("${MCUBOOT_ARCH}" STREQUAL "xtensa")
+    list(APPEND CFLAGS
+        "-mlongcalls"
+        )
+    list(APPEND LDFLAGS
+        "-mlongcalls"
+        )
+endif()
+
+add_subdirectory(hal)
+add_executable(
+    ${APP_EXECUTABLE}
+    ${CMAKE_CURRENT_LIST_DIR}/main.c
+    )
+
+target_compile_options(
+    ${APP_EXECUTABLE}
+    PUBLIC
+    ${CFLAGS}
+    )
+
+target_sources(
+    ${APP_EXECUTABLE}
+    PUBLIC
+    ${bootutil_srcs}
+    ${crypto_srcs}
+    ${CMAKE_CURRENT_LIST_DIR}/port/esp_mcuboot.c
+    ${CMAKE_CURRENT_LIST_DIR}/port/esp_loader.c
+    ${CMAKE_CURRENT_LIST_DIR}/os.c
+    )
+
+target_include_directories(
+    ${APP_EXECUTABLE}
+    PUBLIC
+    ${BOOTUTIL_DIR}/include
+    ${CRYPTO_INC}
+    ${CMAKE_CURRENT_LIST_DIR}/include
+    )
+
+target_link_libraries(
+    ${APP_EXECUTABLE}
+    PUBLIC
+    -T${CMAKE_CURRENT_LIST_DIR}/port/${MCUBOOT_TARGET}/ld/bootloader.ld
+    ${LDFLAGS}
+    )
+
+target_link_libraries(
+    ${APP_EXECUTABLE}
+    PUBLIC
+    hal
+    )
diff --git a/boot/espressif/bootloader.conf b/boot/espressif/bootloader.conf
new file mode 100644
index 0000000..f350262
--- /dev/null
+++ b/boot/espressif/bootloader.conf
@@ -0,0 +1,45 @@
+# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+#
+# SPDX-License-Identifier: Apache-2.0
+
+CONFIG_ESP_BOOTLOADER_SIZE=0xF000
+CONFIG_ESP_APPLICATION_PRIMARY_START_ADDRESS=0x10000
+CONFIG_ESP_APPLICATION_SIZE=0x100000
+CONFIG_ESP_APPLICATION_SECONDARY_START_ADDRESS=0x110000
+CONFIG_ESP_MCUBOOT_WDT_ENABLE=y
+CONFIG_ESP_SCRATCH_OFFSET=0x210000
+CONFIG_ESP_SCRATCH_SIZE=0x40000
+
+# 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/hal/CMakeLists.txt b/boot/espressif/hal/CMakeLists.txt
new file mode 100644
index 0000000..3b767a9
--- /dev/null
+++ b/boot/espressif/hal/CMakeLists.txt
@@ -0,0 +1,177 @@
+# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+#
+# SPDX-License-Identifier: Apache-2.0
+
+cmake_minimum_required(VERSION 3.13)
+
+project(hal)
+
+set(esp_idf_dir ${IDF_PATH})
+
+set(src_dir ${CMAKE_CURRENT_LIST_DIR}/src)
+set(include_dirs
+    ${CMAKE_CURRENT_LIST_DIR}/include
+    ${CMAKE_CURRENT_LIST_DIR}/include/${MCUBOOT_TARGET}
+    )
+
+list(APPEND include_dirs
+    ${esp_idf_dir}/components/${MCUBOOT_ARCH}/include
+    ${esp_idf_dir}/components/esp_common/include
+    ${esp_idf_dir}/components/esp_rom/include
+    ${esp_idf_dir}/components/esp_rom/include/${MCUBOOT_TARGET}
+    ${esp_idf_dir}/components/esp_rom/${MCUBOOT_TARGET}
+    ${esp_idf_dir}/components/spi_flash/include
+    ${esp_idf_dir}/components/spi_flash/include/spi_flash
+    ${esp_idf_dir}/components/esp_hw_support/include
+    ${esp_idf_dir}/components/esp_hw_support/include/soc
+    ${esp_idf_dir}/components/esp_hw_support/include/soc/${MCUBOOT_TARGET}
+    ${esp_idf_dir}/components/esp_hw_support/port/include
+    ${esp_idf_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}
+    ${esp_idf_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/private_include
+    ${esp_idf_dir}/components/soc/include
+    ${esp_idf_dir}/components/soc/${MCUBOOT_TARGET}/include
+    ${esp_idf_dir}/components/bootloader_support/include
+    ${esp_idf_dir}/components/bootloader_support/include_bootloader
+    ${esp_idf_dir}/components/hal/include
+    ${esp_idf_dir}/components/hal/platform_port/include
+    ${esp_idf_dir}/components/hal/${MCUBOOT_TARGET}/include
+    ${esp_idf_dir}/components/hal/${MCUBOOT_TARGET}/include/hal
+    ${esp_idf_dir}/components/heap/include
+    ${esp_idf_dir}/components/efuse/include
+    ${esp_idf_dir}/components/efuse/${MCUBOOT_TARGET}/include
+    ${esp_idf_dir}/components/efuse/private_include
+    ${esp_idf_dir}/components/efuse/${MCUBOOT_TARGET}/private_include
+    ${esp_idf_dir}/components/newlib/platform_include
+    )
+
+if("${MCUBOOT_ARCH}" STREQUAL "xtensa")
+    list(APPEND include_dirs
+        ${esp_idf_dir}/components/${MCUBOOT_ARCH}/${MCUBOOT_TARGET}/include
+        )
+endif()
+
+set(hal_srcs
+    ${src_dir}/bootloader_wdt.c
+    ${src_dir}/secure_boot.c
+    ${src_dir}/flash_encrypt.c
+    ${src_dir}/${MCUBOOT_TARGET}/bootloader_init.c
+    ${esp_idf_dir}/components/hal/mpu_hal.c
+    ${esp_idf_dir}/components/bootloader_support/src/bootloader_common_loader.c
+    ${esp_idf_dir}/components/bootloader_support/src/bootloader_console_loader.c
+    ${esp_idf_dir}/components/bootloader_support/src/bootloader_flash.c
+    ${esp_idf_dir}/components/bootloader_support/src/bootloader_flash_config_${MCUBOOT_TARGET}.c
+    ${esp_idf_dir}/components/bootloader_support/src/bootloader_clock_init.c
+    ${esp_idf_dir}/components/bootloader_support/src/bootloader_efuse_${MCUBOOT_TARGET}.c
+    ${esp_idf_dir}/components/bootloader_support/src/bootloader_panic.c
+    ${esp_idf_dir}/components/bootloader_support/src/bootloader_mem.c
+    ${esp_idf_dir}/components/bootloader_support/src/bootloader_random.c
+    ${esp_idf_dir}/components/bootloader_support/src/bootloader_random_${MCUBOOT_TARGET}.c
+    ${esp_idf_dir}/components/bootloader_support/src/bootloader_utility.c
+    ${esp_idf_dir}/components/bootloader_support/src/esp_image_format.c
+    ${esp_idf_dir}/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_bootloader.c
+    ${esp_idf_dir}/components/bootloader_support/src/${MCUBOOT_TARGET}/bootloader_soc.c
+    ${esp_idf_dir}/components/bootloader_support/src/${MCUBOOT_TARGET}/bootloader_sha.c
+    ${esp_idf_dir}/components/bootloader_support/src/${MCUBOOT_TARGET}/secure_boot_secure_features.c
+    ${esp_idf_dir}/components/bootloader_support/src/${MCUBOOT_TARGET}/flash_encryption_secure_features.c
+    ${esp_idf_dir}/components/spi_flash/${MCUBOOT_TARGET}/spi_flash_rom_patch.c
+    ${esp_idf_dir}/components/esp_hw_support/esp_clk.c
+    ${esp_idf_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/rtc_init.c
+    ${esp_idf_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/rtc_time.c
+    ${esp_idf_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/rtc_clk.c
+    ${esp_idf_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/rtc_clk_init.c
+    ${esp_idf_dir}/components/hal/wdt_hal_iram.c
+    ${esp_idf_dir}/components/esp_hw_support/cpu_util.c
+    ${esp_idf_dir}/components/esp_rom/patches/esp_rom_uart.c
+    ${esp_idf_dir}/components/esp_rom/patches/esp_rom_sys.c
+    ${esp_idf_dir}/components/efuse/${MCUBOOT_TARGET}/esp_efuse_table.c
+    ${esp_idf_dir}/components/efuse/src/esp_efuse_fields.c
+    ${esp_idf_dir}/components/efuse/${MCUBOOT_TARGET}/esp_efuse_fields.c
+    ${esp_idf_dir}/components/efuse/src/esp_efuse_api.c
+    ${esp_idf_dir}/components/efuse/src/esp_efuse_utility.c
+    ${esp_idf_dir}/components/efuse/${MCUBOOT_TARGET}/esp_efuse_utility.c
+    )
+
+if("${MCUBOOT_ARCH}" STREQUAL "xtensa")
+    list(APPEND hal_srcs
+        ${esp_idf_dir}/components/esp_rom/patches/esp_rom_longjmp.S
+        )
+endif()
+
+set(CFLAGS
+    "-nostdlib"
+    "-Wno-frame-address"
+    "-Wall"
+    "-Wextra"
+    "-W"
+    "-Wwrite-strings"
+    "-Wlogical-op"
+    "-Wshadow"
+    "-ffunction-sections"
+    "-fdata-sections"
+    "-fstrict-volatile-bitfields"
+    "-Werror=all"
+    "-Wno-error=unused-function"
+    "-Wno-error=unused-but-set-variable"
+    "-Wno-error=unused-variable"
+    "-Wno-error=deprecated-declarations"
+    "-Wno-unused-parameter"
+    "-Wno-sign-compare"
+    "-ggdb"
+    "-Os"
+    "-D_GNU_SOURCE"
+    "-std=gnu99"
+    "-Wno-old-style-declaration"
+    "-Wno-implicit-int"
+    )
+
+set(LDFLAGS
+    "-Wno-frame-address"
+    "-Wl,--cref"
+    "-Wl,--Map=${APP_NAME}.map"
+    "-fno-rtti"
+    "-fno-lto"
+    "-Wl,--gc-sections"
+    "-Wl,--undefined=uxTopUsedPriority"
+    "-lm"
+    "-lgcc"
+    "-lgcov"
+    )
+
+if("${MCUBOOT_ARCH}" STREQUAL "xtensa")
+    list(APPEND CFLAGS
+        "-mlongcalls"
+        )
+    list(APPEND LDFLAGS
+        "-mlongcalls"
+        )
+endif()
+
+set(LINKER_SCRIPTS
+    -T${esp_idf_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.ld
+    -T${esp_idf_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.libgcc.ld
+    -T${esp_idf_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.api.ld
+    -T${esp_idf_dir}/components/soc/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.peripherals.ld
+    )
+
+include(${CMAKE_CURRENT_LIST_DIR}/include/${MCUBOOT_TARGET}/${MCUBOOT_TARGET}.cmake)
+
+add_library(hal STATIC ${hal_srcs} ${include_dirs})
+
+target_include_directories(
+    hal
+    PUBLIC
+    ${include_dirs}
+    )
+
+target_compile_options(
+    hal
+    PUBLIC
+    ${CFLAGS}
+    )
+
+target_link_libraries(
+    hal
+    PUBLIC
+    ${LDFLAGS}
+    ${LINKER_SCRIPTS}
+    )
diff --git a/boot/espressif/hal/include/esp32/esp32.cmake b/boot/espressif/hal/include/esp32/esp32.cmake
new file mode 100644
index 0000000..e26b6c3
--- /dev/null
+++ b/boot/espressif/hal/include/esp32/esp32.cmake
@@ -0,0 +1,16 @@
+# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+#
+# SPDX-License-Identifier: Apache-2.0
+
+list(APPEND include_dirs
+    ${esp_idf_dir}/components/${MCUBOOT_TARGET}/include
+    )
+
+list(APPEND hal_srcs
+    ${esp_idf_dir}/components/efuse/src/esp_efuse_api_key_esp32.c
+    )
+
+list(APPEND LINKER_SCRIPTS
+    -T${esp_idf_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.newlib-funcs.ld
+    -T${esp_idf_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.eco3.ld
+    )
diff --git a/boot/espressif/hal/include/esp32/sdkconfig.h b/boot/espressif/hal/include/esp32/sdkconfig.h
new file mode 100644
index 0000000..6e76b63
--- /dev/null
+++ b/boot/espressif/hal/include/esp32/sdkconfig.h
@@ -0,0 +1,22 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#define BOOTLOADER_BUILD 1
+#define CONFIG_IDF_FIRMWARE_CHIP_ID 0x0000
+#define CONFIG_IDF_TARGET_ESP32 1
+#define CONFIG_ESP32_REV_MIN_3 1
+#define CONFIG_ESP32_REV_MIN 3
+#define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1
+#define CONFIG_ESP32_XTAL_FREQ 40
+#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 0x1000
+#define CONFIG_PARTITION_TABLE_OFFSET 0x10000
+#define CONFIG_EFUSE_VIRTUAL_OFFSET 0x250000
+#define CONFIG_EFUSE_VIRTUAL_SIZE 0x2000
+#define CONFIG_EFUSE_MAX_BLK_LEN 192
diff --git a/boot/espressif/hal/include/esp32c3/esp32c3.cmake b/boot/espressif/hal/include/esp32c3/esp32c3.cmake
new file mode 100644
index 0000000..5d37192
--- /dev/null
+++ b/boot/espressif/hal/include/esp32c3/esp32c3.cmake
@@ -0,0 +1,19 @@
+# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+#
+# SPDX-License-Identifier: Apache-2.0
+
+list(APPEND hal_srcs
+    ${esp_idf_dir}/components/bootloader_support/src/flash_qio_mode.c
+    ${esp_idf_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/cpu_util_esp32c3.c
+    ${esp_idf_dir}/components/efuse/src/esp_efuse_api_key_esp32xx.c
+)
+
+list(APPEND LINKER_SCRIPTS
+    -T${esp_idf_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.newlib.ld
+    -T${esp_idf_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.eco3.ld
+)
+
+set_source_files_properties(
+    ${esp_idf_dir}/components/bootloader_support/src/flash_qio_mode.c
+    PROPERTIES COMPILE_FLAGS
+    "-Wno-unused-variable")
diff --git a/boot/espressif/hal/include/esp32c3/sdkconfig.h b/boot/espressif/hal/include/esp32c3/sdkconfig.h
new file mode 100644
index 0000000..f091a13
--- /dev/null
+++ b/boot/espressif/hal/include/esp32c3/sdkconfig.h
@@ -0,0 +1,20 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#define BOOTLOADER_BUILD 1
+#define CONFIG_IDF_FIRMWARE_CHIP_ID 0x0005
+#define CONFIG_IDF_TARGET_ESP32C3 1
+#define CONFIG_IDF_TARGET_ARCH_RISCV 1
+#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
diff --git a/boot/espressif/hal/include/esp32s2/esp32s2.cmake b/boot/espressif/hal/include/esp32s2/esp32s2.cmake
new file mode 100644
index 0000000..588ec1c
--- /dev/null
+++ b/boot/espressif/hal/include/esp32s2/esp32s2.cmake
@@ -0,0 +1,13 @@
+# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+#
+# SPDX-License-Identifier: Apache-2.0
+
+list(APPEND hal_srcs
+    ${esp_idf_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/regi2c_ctrl.c
+    ${esp_idf_dir}/components/efuse/src/esp_efuse_api_key_esp32xx.c
+    )
+
+list(APPEND LINKER_SCRIPTS
+    -T${esp_idf_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.newlib-funcs.ld
+    -T${esp_idf_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.spiflash.ld
+    )
diff --git a/boot/espressif/hal/include/esp32s2/sdkconfig.h b/boot/espressif/hal/include/esp32s2/sdkconfig.h
new file mode 100644
index 0000000..ed61b9b
--- /dev/null
+++ b/boot/espressif/hal/include/esp32s2/sdkconfig.h
@@ -0,0 +1,20 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#define BOOTLOADER_BUILD 1
+#define CONFIG_IDF_FIRMWARE_CHIP_ID 0x0002
+#define CONFIG_IDF_TARGET_ESP32S2 1
+#define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1
+#define CONFIG_ESP32S2_XTAL_FREQ 40
+#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 0x1000
+#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
diff --git a/boot/espressif/hal/include/esp32s3/esp32s3.cmake b/boot/espressif/hal/include/esp32s3/esp32s3.cmake
new file mode 100644
index 0000000..d8542e2
--- /dev/null
+++ b/boot/espressif/hal/include/esp32s3/esp32s3.cmake
@@ -0,0 +1,11 @@
+# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+#
+# SPDX-License-Identifier: Apache-2.0
+
+list(APPEND hal_srcs
+    ${esp_idf_dir}/components/efuse/src/esp_efuse_api_key_esp32xx.c
+)
+
+list(APPEND LINKER_SCRIPTS
+    -T${esp_idf_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.newlib.ld
+    )
diff --git a/boot/espressif/hal/include/esp32s3/sdkconfig.h b/boot/espressif/hal/include/esp32s3/sdkconfig.h
new file mode 100644
index 0000000..e88d74f
--- /dev/null
+++ b/boot/espressif/hal/include/esp32s3/sdkconfig.h
@@ -0,0 +1,19 @@
+/*
+ * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#define BOOTLOADER_BUILD 1
+#define CONFIG_IDF_FIRMWARE_CHIP_ID 0x0009
+#define CONFIG_IDF_TARGET_ESP32S3 1
+#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
diff --git a/boot/espressif/hal/include/esp_log.h b/boot/espressif/hal/include/esp_log.h
new file mode 100644
index 0000000..6fcab74
--- /dev/null
+++ b/boot/espressif/hal/include/esp_log.h
@@ -0,0 +1,26 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+#include <mcuboot_config/mcuboot_logging.h>
+
+/* Log levels from IDF are similar to MCUboot's */
+
+#ifndef CONFIG_BOOTLOADER_LOG_LEVEL
+#define CONFIG_BOOTLOADER_LOG_LEVEL MCUBOOT_LOG_LEVEL
+#endif
+
+#define ESP_LOGE(tag, fmt, ...) MCUBOOT_LOG_ERR("[%s] " fmt, tag, ##__VA_ARGS__)
+#define ESP_LOGW(tag, fmt, ...) MCUBOOT_LOG_WRN("[%s] " fmt, tag, ##__VA_ARGS__)
+#define ESP_LOGI(tag, fmt, ...) MCUBOOT_LOG_INF("[%s] " fmt, tag, ##__VA_ARGS__)
+#define ESP_LOGD(tag, fmt, ...) MCUBOOT_LOG_DBG("[%s] " fmt, tag, ##__VA_ARGS__)
+#define ESP_LOGV(tag, fmt, ...) MCUBOOT_LOG_DBG("[%s] " fmt, tag, ##__VA_ARGS__)
+
+#define ESP_EARLY_LOGE(tag, fmt, ...) MCUBOOT_LOG_ERR("[%s] " fmt, tag, ##__VA_ARGS__)
+#define ESP_EARLY_LOGW(tag, fmt, ...) MCUBOOT_LOG_WRN("[%s] " fmt, tag, ##__VA_ARGS__)
+#define ESP_EARLY_LOGI(tag, fmt, ...) MCUBOOT_LOG_INF("[%s] " fmt, tag, ##__VA_ARGS__)
+#define ESP_EARLY_LOGD(tag, fmt, ...) MCUBOOT_LOG_DBG("[%s] " fmt, tag, ##__VA_ARGS__)
+#define ESP_EARLY_LOGV(tag, fmt, ...) MCUBOOT_LOG_DBG("[%s] " fmt, tag, ##__VA_ARGS__)
diff --git a/boot/espressif/hal/include/esp_mcuboot_image.h b/boot/espressif/hal/include/esp_mcuboot_image.h
new file mode 100644
index 0000000..baccf08
--- /dev/null
+++ b/boot/espressif/hal/include/esp_mcuboot_image.h
@@ -0,0 +1,26 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+/* Magic is derived from sha256sum of the string "espmcuboot"
+ * The application header magic must match this number
+ */
+#define ESP_LOAD_HEADER_MAGIC 0xace637d3
+
+/* Load header that should be a part of application image
+ * for MCUboot-Espressif port booting.
+ */
+typedef struct esp_image_load_header {
+    uint32_t header_magic;          /* Magic for load header */
+    uint32_t entry_addr;            /* Application entry address */
+    uint32_t iram_dest_addr;        /* Destination address(VMA) for IRAM region */
+    uint32_t iram_flash_offset;     /* Flash offset(LMA) for start of IRAM region */
+    uint32_t iram_size;             /* Size of IRAM region */
+    uint32_t dram_dest_addr;        /* Destination address(VMA) for DRAM region */
+    uint32_t dram_flash_offset;     /* Flash offset(LMA) for start of DRAM region */
+    uint32_t dram_size;             /* Size of DRAM region */
+} esp_image_load_header_t;
diff --git a/boot/espressif/hal/include/mcuboot_config/mcuboot_config.h b/boot/espressif/hal/include/mcuboot_config/mcuboot_config.h
new file mode 100644
index 0000000..abbbd97
--- /dev/null
+++ b/boot/espressif/hal/include/mcuboot_config/mcuboot_config.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __MCUBOOT_CONFIG_H__
+#define __MCUBOOT_CONFIG_H__
+
+/*
+ * Signature types
+ *
+ * You must choose exactly one signature type - check bootloader.conf
+ * configuration file
+ */
+
+/* Uncomment for RSA signature support */
+#if defined(CONFIG_ESP_SIGN_RSA)
+#define MCUBOOT_SIGN_RSA
+#  if (CONFIG_ESP_SIGN_RSA_LEN != 2048 && \
+       CONFIG_ESP_SIGN_RSA_LEN != 3072)
+#    error "Invalid RSA key size (must be 2048 or 3072)"
+#  else
+#    define MCUBOOT_SIGN_RSA_LEN CONFIG_ESP_SIGN_RSA_LEN
+#  endif
+#elif defined(CONFIG_ESP_SIGN_EC256)
+#define MCUBOOT_SIGN_EC256
+#elif defined(CONFIG_ESP_SIGN_ED25519)
+#define MCUBOOT_SIGN_ED25519
+#endif
+
+#if defined(CONFIG_SECURE_FLASH_ENC_ENABLED)
+#define MCUBOOT_BOOT_MAX_ALIGN 32
+#endif
+
+/*
+ * Upgrade mode
+ *
+ * The default is to support A/B image swapping with rollback.  Other modes
+ * with simpler code path, which only supports overwriting the existing image
+ * with the update image or running the newest image directly from its flash
+ * partition, are also available.
+ *
+ * You can enable only one mode at a time from the list below to override
+ * the default upgrade mode.
+ */
+
+/* Uncomment to enable the overwrite-only code path. */
+/* #define MCUBOOT_OVERWRITE_ONLY */
+
+#ifdef MCUBOOT_OVERWRITE_ONLY
+/* Uncomment to only erase and overwrite those primary slot sectors needed
+ * to install the new image, rather than the entire image slot. */
+/* #define MCUBOOT_OVERWRITE_ONLY_FAST */
+#endif
+
+/* Uncomment to enable the direct-xip code path. */
+/* #define MCUBOOT_DIRECT_XIP */
+
+/* Uncomment to enable the ram-load code path. */
+/* #define MCUBOOT_RAM_LOAD */
+
+/*
+ * Cryptographic settings
+ *
+ * You must choose between Mbed TLS and Tinycrypt as source of
+ * cryptographic primitives. Other cryptographic settings are also
+ * available.
+ */
+
+/* Uncomment to use Mbed TLS cryptographic primitives */
+#if defined(CONFIG_ESP_USE_MBEDTLS)
+#define MCUBOOT_USE_MBED_TLS
+#else
+/* MCUboot requires the definition of a crypto lib,
+ * using Tinycrypt as default */
+#define MCUBOOT_USE_TINYCRYPT
+#endif
+
+/*
+ * Always check the signature of the image in the primary slot before booting,
+ * even if no upgrade was performed. This is recommended if the boot
+ * time penalty is acceptable.
+ */
+#define MCUBOOT_VALIDATE_PRIMARY_SLOT
+
+/*
+ * Flash abstraction
+ */
+
+/* Uncomment if your flash map API supports flash_area_get_sectors().
+ * See the flash APIs for more details. */
+#define MCUBOOT_USE_FLASH_AREA_GET_SECTORS
+
+/* Default maximum number of flash sectors per image slot; change
+ * as desirable. */
+#define MCUBOOT_MAX_IMG_SECTORS 512
+
+/* Default number of separately updateable images; change in case of
+ * multiple images. */
+#define MCUBOOT_IMAGE_NUMBER 1
+
+/*
+ * Logging
+ */
+
+/*
+ * If logging is enabled the following functions must be defined by the
+ * platform:
+ *
+ *    MCUBOOT_LOG_MODULE_REGISTER(domain)
+ *      Register a new log module and add the current C file to it.
+ *
+ *    MCUBOOT_LOG_MODULE_DECLARE(domain)
+ *      Add the current C file to an existing log module.
+ *
+ *    MCUBOOT_LOG_ERR(...)
+ *    MCUBOOT_LOG_WRN(...)
+ *    MCUBOOT_LOG_INF(...)
+ *    MCUBOOT_LOG_DBG(...)
+ *
+ * The function priority is:
+ *
+ *    MCUBOOT_LOG_ERR > MCUBOOT_LOG_WRN > MCUBOOT_LOG_INF > MCUBOOT_LOG_DBG
+ */
+#define MCUBOOT_HAVE_LOGGING 1
+/* #define MCUBOOT_LOG_LEVEL MCUBOOT_LOG_LEVEL_INFO */
+
+/*
+ * Assertions
+ */
+
+/* Uncomment if your platform has its own mcuboot_config/mcuboot_assert.h.
+ * If so, it must provide an ASSERT macro for use by bootutil. Otherwise,
+ * "assert" is used. */
+#define MCUBOOT_HAVE_ASSERT_H 1
+
+/*
+ * Watchdog feeding
+ */
+
+/* This macro might be implemented if the OS / HW watchdog is enabled while
+ * doing a swap upgrade and the time it takes for a swapping is long enough
+ * to cause an unwanted reset. If implementing this, the OS main.c must also
+ * enable the watchdog (if required)!
+ */
+#include <bootloader_wdt.h>
+  #define MCUBOOT_WATCHDOG_FEED() \
+      do { \
+          bootloader_wdt_feed(); \
+      } while (0)
+
+#endif /* __MCUBOOT_CONFIG_H__ */
diff --git a/boot/espressif/hal/include/mcuboot_config/mcuboot_logging.h b/boot/espressif/hal/include/mcuboot_config/mcuboot_logging.h
new file mode 100644
index 0000000..8e86322
--- /dev/null
+++ b/boot/espressif/hal/include/mcuboot_config/mcuboot_logging.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include "sdkconfig.h"
+#include "mcuboot_config.h"
+
+extern int ets_printf(const char *fmt, ...);
+
+#define MCUBOOT_LOG_LEVEL_OFF      0
+#define MCUBOOT_LOG_LEVEL_ERROR    1
+#define MCUBOOT_LOG_LEVEL_WARNING  2
+#define MCUBOOT_LOG_LEVEL_INFO     3
+#define MCUBOOT_LOG_LEVEL_DEBUG    4
+
+#if CONFIG_IDF_TARGET_ESP32
+#define TARGET "[esp32]"
+#elif CONFIG_IDF_TARGET_ESP32S2
+#define TARGET "[esp32s2]"
+#elif CONFIG_IDF_TARGET_ESP32S3
+#define TARGET "[esp32s3]"
+#elif CONFIG_IDF_TARGET_ESP32C3
+#define TARGET "[esp32c3]"
+#else
+#error "Selected target not supported."
+#endif
+
+#ifndef MCUBOOT_LOG_LEVEL
+#define MCUBOOT_LOG_LEVEL MCUBOOT_LOG_LEVEL_INFO
+#endif
+
+#if MCUBOOT_LOG_LEVEL >= MCUBOOT_LOG_LEVEL_ERROR
+#define MCUBOOT_LOG_ERR(_fmt, ...)                                      \
+    do {                                                                \
+            ets_printf(TARGET " [ERR] " _fmt "\n\r", ##__VA_ARGS__);         \
+    } while (0)
+#else
+#define MCUBOOT_LOG_ERR(_fmt, ...)
+#endif
+
+#if MCUBOOT_LOG_LEVEL >= MCUBOOT_LOG_LEVEL_WARNING
+#define MCUBOOT_LOG_WRN(_fmt, ...)                                      \
+    do {                                                                \
+            ets_printf(TARGET " [WRN] " _fmt "\n\r", ##__VA_ARGS__);         \
+    } while (0)
+#else
+#define MCUBOOT_LOG_WRN(_fmt, ...)
+#endif
+
+#if MCUBOOT_LOG_LEVEL >= MCUBOOT_LOG_LEVEL_INFO
+#define MCUBOOT_LOG_INF(_fmt, ...)                                      \
+    do {                                                                \
+            ets_printf(TARGET " [INF] " _fmt "\n\r", ##__VA_ARGS__);         \
+    } while (0)
+#else
+#define MCUBOOT_LOG_INF(_fmt, ...)
+#endif
+
+#if MCUBOOT_LOG_LEVEL >= MCUBOOT_LOG_LEVEL_DEBUG
+#define MCUBOOT_LOG_DBG(_fmt, ...)                                      \
+    do {                                                                \
+            ets_printf(TARGET " [DBG] " _fmt "\n\r", ##__VA_ARGS__);         \
+    } while (0)
+#else
+#define MCUBOOT_LOG_DBG(_fmt, ...)
+#endif
+
+#define MCUBOOT_LOG_MODULE_DECLARE(...)
+#define MCUBOOT_LOG_MODULE_REGISTER(...)
diff --git a/boot/espressif/hal/include/soc_log.h b/boot/espressif/hal/include/soc_log.h
new file mode 100644
index 0000000..3e8f231
--- /dev/null
+++ b/boot/espressif/hal/include/soc_log.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include <mcuboot_config/mcuboot_logging.h>
+#include <esp_rom_sys.h>
+
+#define SOC_LOGE(tag, fmt, ...) MCUBOOT_LOG_ERR("[%s] " fmt, tag, ##__VA_ARGS__)
+#define SOC_LOGW(tag, fmt, ...) MCUBOOT_LOG_WRN("[%s] " fmt, tag, ##__VA_ARGS__)
+#define SOC_LOGI(tag, fmt, ...) MCUBOOT_LOG_INF("[%s] " fmt, tag, ##__VA_ARGS__)
+#define SOC_LOGD(tag, fmt, ...) MCUBOOT_LOG_DBG("[%s] " fmt, tag, ##__VA_ARGS__)
diff --git a/boot/espressif/hal/src/esp32/bootloader_init.c b/boot/espressif/hal/src/esp32/bootloader_init.c
new file mode 100644
index 0000000..e7b1528
--- /dev/null
+++ b/boot/espressif/hal/src/esp32/bootloader_init.c
@@ -0,0 +1,218 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "sdkconfig.h"
+#include "esp_attr.h"
+#include "esp_image_format.h"
+
+#include "bootloader_init.h"
+#include "bootloader_mem.h"
+#include "bootloader_clock.h"
+#include "bootloader_flash_config.h"
+#include "bootloader_flash.h"
+#include "bootloader_flash_priv.h"
+
+#include "soc/dport_reg.h"
+#include "soc/efuse_reg.h"
+#include "soc/rtc.h"
+
+#include "hal/wdt_hal.h"
+
+#include "esp32/rom/cache.h"
+#include "esp32/rom/spi_flash.h"
+#include "esp32/rom/uart.h"
+
+esp_image_header_t WORD_ALIGNED_ATTR bootloader_image_hdr;
+
+void bootloader_clear_bss_section(void)
+{
+    memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start));
+}
+
+static void bootloader_common_vddsdio_configure(void)
+{
+    rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config();
+    if (cfg.enable == 1 && cfg.tieh == RTC_VDDSDIO_TIEH_1_8V) {    /* VDDSDIO regulator is enabled @ 1.8V */
+        cfg.drefh = 3;
+        cfg.drefm = 3;
+        cfg.drefl = 3;
+        cfg.force = 1;
+        rtc_vddsdio_set_config(cfg);
+        ets_delay_us(10); /* wait for regulator to become stable */
+    }
+}
+
+static void bootloader_reset_mmu(void)
+{
+    /* completely reset MMU in case serial bootloader was running */
+    Cache_Read_Disable(0);
+#if !CONFIG_FREERTOS_UNICORE
+    Cache_Read_Disable(1);
+#endif
+    Cache_Flush(0);
+#if !CONFIG_FREERTOS_UNICORE
+    Cache_Flush(1);
+#endif
+    mmu_init(0);
+#if !CONFIG_FREERTOS_UNICORE
+    /* The lines which manipulate DPORT_APP_CACHE_MMU_IA_CLR bit are
+        necessary to work around a hardware bug. */
+    DPORT_REG_SET_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
+    mmu_init(1);
+    DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
+#endif
+
+    /* normal ROM boot exits with DROM0 cache unmasked,
+        but serial bootloader exits with it masked. */
+    DPORT_REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MASK_DROM0);
+#if !CONFIG_FREERTOS_UNICORE
+    DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MASK_DROM0);
+#endif
+}
+
+static esp_err_t bootloader_check_rated_cpu_clock(void)
+{
+    int rated_freq = bootloader_clock_get_rated_freq_mhz();
+    if (rated_freq < 80) {
+        return ESP_FAIL;
+    }
+    return ESP_OK;
+}
+
+esp_err_t bootloader_read_bootloader_header(void)
+{
+    if (bootloader_flash_read(ESP_BOOTLOADER_OFFSET, &bootloader_image_hdr, sizeof(esp_image_header_t), true) != ESP_OK) {
+        return ESP_FAIL;
+    }
+    return ESP_OK;
+}
+
+static void update_flash_config(const esp_image_header_t *bootloader_hdr)
+{
+    uint32_t size;
+    switch (bootloader_hdr->spi_size) {
+    case ESP_IMAGE_FLASH_SIZE_1MB:
+        size = 1;
+        break;
+    case ESP_IMAGE_FLASH_SIZE_2MB:
+        size = 2;
+        break;
+    case ESP_IMAGE_FLASH_SIZE_4MB:
+        size = 4;
+        break;
+    case ESP_IMAGE_FLASH_SIZE_8MB:
+        size = 8;
+        break;
+    case ESP_IMAGE_FLASH_SIZE_16MB:
+        size = 16;
+        break;
+    default:
+        size = 2;
+    }
+    Cache_Read_Disable(0);
+    /* Set flash chip size */
+    esp_rom_spiflash_config_param(g_rom_flashchip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff);
+    /* TODO: set mode */
+    /* TODO: set frequency */
+    Cache_Flush(0);
+    Cache_Read_Enable(0);
+}
+
+static void IRAM_ATTR bootloader_init_flash_configure(void)
+{
+    bootloader_flash_gpio_config(&bootloader_image_hdr);
+    bootloader_flash_dummy_config(&bootloader_image_hdr);
+    bootloader_flash_cs_timing_config();
+}
+
+static esp_err_t bootloader_init_spi_flash(void)
+{
+    bootloader_init_flash_configure();
+    esp_rom_spiflash_unlock();
+
+    update_flash_config(&bootloader_image_hdr);
+    return ESP_OK;
+}
+
+void bootloader_config_wdt(void)
+{
+    wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL};
+    wdt_hal_write_protect_disable(&rtc_wdt_ctx);
+    wdt_hal_set_flashboot_en(&rtc_wdt_ctx, false);
+    wdt_hal_write_protect_enable(&rtc_wdt_ctx);
+
+#ifdef CONFIG_ESP_MCUBOOT_WDT_ENABLE
+    wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false);
+    uint32_t stage_timeout_ticks = (uint32_t)((uint64_t)CONFIG_BOOTLOADER_WDT_TIME_MS * rtc_clk_slow_freq_get_hz() / 1000);
+    wdt_hal_write_protect_disable(&rtc_wdt_ctx);
+    wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC);
+    wdt_hal_enable(&rtc_wdt_ctx);
+    wdt_hal_write_protect_enable(&rtc_wdt_ctx);
+#endif
+
+    wdt_hal_context_t wdt_ctx = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0};
+    wdt_hal_write_protect_disable(&wdt_ctx);
+    wdt_hal_set_flashboot_en(&wdt_ctx, false);
+    wdt_hal_write_protect_enable(&wdt_ctx);
+}
+
+static void bootloader_init_uart_console(void)
+{
+    const int uart_num = 0;
+
+    uartAttach();
+    ets_install_uart_printf();
+    uart_tx_wait_idle(0);
+
+    const int uart_baud = CONFIG_ESP_CONSOLE_UART_BAUDRATE;
+    uart_div_modify(uart_num, (rtc_clk_apb_freq_get() << 4) / uart_baud);
+}
+
+
+esp_err_t bootloader_init(void)
+{
+    esp_err_t ret = ESP_OK;
+
+    bootloader_init_mem();
+
+    /* check that static RAM is after the stack */
+#ifndef NDEBUG
+    {
+        assert(&_bss_start <= &_bss_end);
+        assert(&_data_start <= &_data_end);
+        assert(sp < &_bss_start);
+        assert(sp < &_data_start);
+    }
+#endif
+    /* clear bss section */
+    bootloader_clear_bss_section();
+    /* bootst up vddsdio */
+    bootloader_common_vddsdio_configure();
+    /* reset MMU */
+    bootloader_reset_mmu();
+    /* check rated CPU clock */
+    if ((ret = bootloader_check_rated_cpu_clock()) != ESP_OK) {
+        goto err;
+    }
+    /* config clock */
+    bootloader_clock_configure();
+    /* initialize uart console, from now on, we can use ets_printf */
+    bootloader_init_uart_console();
+    /* read bootloader header */
+    if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
+        goto err;
+    }
+    /* initialize spi flash */
+    if ((ret = bootloader_init_spi_flash()) != ESP_OK) {
+        goto err;
+    }
+    /* config WDT */
+    bootloader_config_wdt();
+err:
+    return ret;
+}
diff --git a/boot/espressif/hal/src/esp32c3/bootloader_init.c b/boot/espressif/hal/src/esp32c3/bootloader_init.c
new file mode 100644
index 0000000..ec74349
--- /dev/null
+++ b/boot/espressif/hal/src/esp32c3/bootloader_init.c
@@ -0,0 +1,243 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+
+#include "sdkconfig.h"
+#include "esp_attr.h"
+#include "esp_image_format.h"
+
+#include "esp_rom_efuse.h"
+#include "esp_rom_gpio.h"
+#include "esp_rom_uart.h"
+#include "esp_rom_sys.h"
+
+#include "bootloader_init.h"
+#include "bootloader_clock.h"
+#include "bootloader_flash_config.h"
+#include "bootloader_mem.h"
+#include "bootloader_flash.h"
+#include "bootloader_flash_priv.h"
+#include "regi2c_ctrl.h"
+
+#include "soc/extmem_reg.h"
+#include "soc/io_mux_reg.h"
+#include "soc/efuse_reg.h"
+#include "soc/rtc.h"
+
+#include "esp32c3/rom/cache.h"
+#include "esp32c3/rom/spi_flash.h"
+
+#include "hal/wdt_hal.h"
+
+extern uint8_t bootloader_common_get_chip_revision(void);
+
+esp_image_header_t WORD_ALIGNED_ATTR bootloader_image_hdr;
+
+void bootloader_clear_bss_section(void)
+{
+    memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start));
+}
+
+void IRAM_ATTR bootloader_configure_spi_pins(int drv)
+{
+    const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
+    uint8_t wp_pin = esp_rom_efuse_get_flash_wp_gpio();
+    uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM;
+    uint8_t q_gpio_num   = SPI_Q_GPIO_NUM;
+    uint8_t d_gpio_num   = SPI_D_GPIO_NUM;
+    uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM;
+    uint8_t hd_gpio_num  = SPI_HD_GPIO_NUM;
+    uint8_t wp_gpio_num  = SPI_WP_GPIO_NUM;
+    if (spiconfig != 0) {
+        clk_gpio_num = spiconfig         & 0x3f;
+        q_gpio_num = (spiconfig >> 6)    & 0x3f;
+        d_gpio_num = (spiconfig >> 12)   & 0x3f;
+        cs0_gpio_num = (spiconfig >> 18) & 0x3f;
+        hd_gpio_num = (spiconfig >> 24)  & 0x3f;
+        wp_gpio_num = wp_pin;
+    }
+    esp_rom_gpio_pad_set_drv(clk_gpio_num, drv);
+    esp_rom_gpio_pad_set_drv(q_gpio_num,   drv);
+    esp_rom_gpio_pad_set_drv(d_gpio_num,   drv);
+    esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv);
+    if (hd_gpio_num <= MAX_PAD_GPIO_NUM) {
+        esp_rom_gpio_pad_set_drv(hd_gpio_num, drv);
+    }
+    if (wp_gpio_num <= MAX_PAD_GPIO_NUM) {
+        esp_rom_gpio_pad_set_drv(wp_gpio_num, drv);
+    }
+}
+
+static void bootloader_reset_mmu(void)
+{
+    Cache_Suspend_ICache();
+    Cache_Invalidate_ICache_All();
+    Cache_MMU_Init();
+
+    REG_CLR_BIT(EXTMEM_ICACHE_CTRL1_REG, EXTMEM_ICACHE_SHUT_IBUS);
+    REG_CLR_BIT(EXTMEM_ICACHE_CTRL1_REG, EXTMEM_ICACHE_SHUT_DBUS);
+}
+
+esp_err_t bootloader_read_bootloader_header(void)
+{
+    if (bootloader_flash_read(ESP_BOOTLOADER_OFFSET, &bootloader_image_hdr, sizeof(esp_image_header_t), true) != ESP_OK) {
+        return ESP_FAIL;
+    }
+    return ESP_OK;
+}
+
+static void update_flash_config(const esp_image_header_t *bootloader_hdr)
+{
+    uint32_t size;
+    switch (bootloader_hdr->spi_size) {
+    case ESP_IMAGE_FLASH_SIZE_1MB:
+        size = 1;
+        break;
+    case ESP_IMAGE_FLASH_SIZE_2MB:
+        size = 2;
+        break;
+    case ESP_IMAGE_FLASH_SIZE_4MB:
+        size = 4;
+        break;
+    case ESP_IMAGE_FLASH_SIZE_8MB:
+        size = 8;
+        break;
+    case ESP_IMAGE_FLASH_SIZE_16MB:
+        size = 16;
+        break;
+    default:
+        size = 2;
+    }
+    uint32_t autoload = Cache_Suspend_ICache();
+    // Set flash chip size
+    esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff);
+    Cache_Resume_ICache(autoload);
+}
+
+static void IRAM_ATTR bootloader_init_flash_configure(void)
+{
+    bootloader_flash_dummy_config(&bootloader_image_hdr);
+    bootloader_flash_cs_timing_config();
+}
+
+static void bootloader_spi_flash_resume(void)
+{
+    bootloader_execute_flash_command(CMD_RESUME, 0, 0, 0);
+    esp_rom_spiflash_wait_idle(&g_rom_flashchip);
+}
+
+static esp_err_t bootloader_init_spi_flash(void)
+{
+    bootloader_init_flash_configure();
+    bootloader_spi_flash_resume();
+    esp_rom_spiflash_unlock();
+    update_flash_config(&bootloader_image_hdr);
+
+    return ESP_OK;
+}
+
+static inline void bootloader_hardware_init(void)
+{
+    // This check is always included in the bootloader so it can
+    // print the minimum revision error message later in the boot
+    if (bootloader_common_get_chip_revision() < 3) {
+        REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_XPD_IPH, 1);
+        REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_DREG_1P1_PVT, 12);
+    }
+}
+
+static inline void bootloader_glitch_reset_disable(void)
+{
+    /*
+      For origin chip & ECO1: only support swt reset;
+      For ECO2: fix brownout reset bug, support swt & brownout reset;
+      For ECO3: fix clock glitch reset bug, support all reset, include: swt & brownout & clock glitch reset.
+    */
+    uint8_t chip_version = bootloader_common_get_chip_revision();
+    if (chip_version < 2) {
+        REG_SET_FIELD(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SEL, RTC_CNTL_FIB_SUPER_WDT_RST);
+    } else if (chip_version == 2) {
+        REG_SET_FIELD(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SEL, RTC_CNTL_FIB_SUPER_WDT_RST | RTC_CNTL_FIB_BOR_RST);
+    }
+}
+
+static void bootloader_super_wdt_auto_feed(void)
+{
+    REG_WRITE(RTC_CNTL_SWD_WPROTECT_REG, RTC_CNTL_SWD_WKEY_VALUE);
+    REG_SET_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_AUTO_FEED_EN);
+    REG_WRITE(RTC_CNTL_SWD_WPROTECT_REG, 0);
+}
+
+void bootloader_config_wdt(void)
+{
+    wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL};
+    wdt_hal_write_protect_disable(&rtc_wdt_ctx);
+    wdt_hal_set_flashboot_en(&rtc_wdt_ctx, false);
+    wdt_hal_write_protect_enable(&rtc_wdt_ctx);
+
+#ifdef CONFIG_ESP_MCUBOOT_WDT_ENABLE
+    wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false);
+    uint32_t stage_timeout_ticks = (uint32_t)((uint64_t)CONFIG_BOOTLOADER_WDT_TIME_MS * rtc_clk_slow_freq_get_hz() / 1000);
+    wdt_hal_write_protect_disable(&rtc_wdt_ctx);
+    wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC);
+    wdt_hal_enable(&rtc_wdt_ctx);
+    wdt_hal_write_protect_enable(&rtc_wdt_ctx);
+#endif
+
+    wdt_hal_context_t wdt_ctx = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0};
+    wdt_hal_write_protect_disable(&wdt_ctx);
+    wdt_hal_set_flashboot_en(&wdt_ctx, false);
+    wdt_hal_write_protect_enable(&wdt_ctx);
+}
+
+static void bootloader_init_uart_console(void)
+{
+    const int uart_num = 0;
+
+    esp_rom_install_uart_printf();
+    esp_rom_uart_tx_wait_idle(0);
+    uint32_t clock_hz = UART_CLK_FREQ_ROM;
+    esp_rom_uart_set_clock_baudrate(uart_num, clock_hz, CONFIG_ESP_CONSOLE_UART_BAUDRATE);
+}
+
+esp_err_t bootloader_init(void)
+{
+    esp_err_t ret = ESP_OK;
+
+    bootloader_hardware_init();
+    bootloader_glitch_reset_disable();
+    bootloader_super_wdt_auto_feed();
+    // protect memory region
+    bootloader_init_mem();
+    /* check that static RAM is after the stack */
+    assert(&_bss_start <= &_bss_end);
+    assert(&_data_start <= &_data_end);
+    // clear bss section
+    bootloader_clear_bss_section();
+    // reset MMU
+    bootloader_reset_mmu();
+    // config clock
+    bootloader_clock_configure();
+    /* initialize uart console, from now on, we can use ets_printf */
+    bootloader_init_uart_console();
+    // update flash ID
+    bootloader_flash_update_id();
+    // read bootloader header
+    if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
+        goto err;
+    }
+    // initialize spi flash
+    if ((ret = bootloader_init_spi_flash()) != ESP_OK) {
+        goto err;
+    }
+    // config WDT
+    bootloader_config_wdt();
+err:
+    return ret;
+}
diff --git a/boot/espressif/hal/src/esp32s2/bootloader_init.c b/boot/espressif/hal/src/esp32s2/bootloader_init.c
new file mode 100644
index 0000000..5e36530
--- /dev/null
+++ b/boot/espressif/hal/src/esp32s2/bootloader_init.c
@@ -0,0 +1,208 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "sdkconfig.h"
+#include "esp_attr.h"
+#include "esp_image_format.h"
+
+#include "esp_rom_efuse.h"
+#include "esp_rom_gpio.h"
+
+#include "bootloader_init.h"
+#include "bootloader_mem.h"
+#include "bootloader_clock.h"
+#include "bootloader_flash_config.h"
+#include "bootloader_flash.h"
+#include "bootloader_flash_priv.h"
+
+#include "soc/dport_reg.h"
+#include "soc/efuse_reg.h"
+#include "soc/rtc.h"
+#include "soc/extmem_reg.h"
+#include "soc/io_mux_reg.h"
+
+#include "hal/wdt_hal.h"
+
+#include "esp32s2/rom/cache.h"
+#include "esp32s2/rom/ets_sys.h"
+#include "esp32s2/rom/spi_flash.h"
+#include "esp32s2/rom/uart.h"
+
+esp_image_header_t WORD_ALIGNED_ATTR bootloader_image_hdr;
+
+void bootloader_clear_bss_section(void)
+{
+    memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start));
+}
+
+static void bootloader_reset_mmu(void)
+{
+    Cache_Suspend_ICache();
+    Cache_Invalidate_ICache_All();
+    Cache_MMU_Init();
+
+    /* normal ROM boot exits with DROM0 cache unmasked,
+    but serial bootloader exits with it masked. */
+    REG_CLR_BIT(EXTMEM_PRO_ICACHE_CTRL1_REG, EXTMEM_PRO_ICACHE_MASK_DROM0);
+}
+
+esp_err_t bootloader_read_bootloader_header(void)
+{
+    if (bootloader_flash_read(ESP_BOOTLOADER_OFFSET, &bootloader_image_hdr, sizeof(esp_image_header_t), true) != ESP_OK) {
+        return ESP_FAIL;
+    }
+    return ESP_OK;
+}
+
+static void update_flash_config(const esp_image_header_t *bootloader_hdr)
+{
+    uint32_t size;
+    switch (bootloader_hdr->spi_size) {
+    case ESP_IMAGE_FLASH_SIZE_1MB:
+        size = 1;
+        break;
+    case ESP_IMAGE_FLASH_SIZE_2MB:
+        size = 2;
+        break;
+    case ESP_IMAGE_FLASH_SIZE_4MB:
+        size = 4;
+        break;
+    case ESP_IMAGE_FLASH_SIZE_8MB:
+        size = 8;
+        break;
+    case ESP_IMAGE_FLASH_SIZE_16MB:
+        size = 16;
+        break;
+    default:
+        size = 2;
+    }
+    uint32_t autoload = Cache_Suspend_ICache();
+    // Set flash chip size
+    esp_rom_spiflash_config_param(g_rom_flashchip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff);
+    Cache_Resume_ICache(autoload);
+}
+
+void IRAM_ATTR bootloader_configure_spi_pins(int drv)
+{
+    const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
+    uint8_t wp_pin = esp_rom_efuse_get_flash_wp_gpio();
+    uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM;
+    uint8_t q_gpio_num   = SPI_Q_GPIO_NUM;
+    uint8_t d_gpio_num   = SPI_D_GPIO_NUM;
+    uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM;
+    uint8_t hd_gpio_num  = SPI_HD_GPIO_NUM;
+    uint8_t wp_gpio_num  = SPI_WP_GPIO_NUM;
+    if (spiconfig != 0) {
+        clk_gpio_num = spiconfig         & 0x3f;
+        q_gpio_num = (spiconfig >> 6)    & 0x3f;
+        d_gpio_num = (spiconfig >> 12)   & 0x3f;
+        cs0_gpio_num = (spiconfig >> 18) & 0x3f;
+        hd_gpio_num = (spiconfig >> 24)  & 0x3f;
+        wp_gpio_num = wp_pin;
+    }
+    esp_rom_gpio_pad_set_drv(clk_gpio_num, drv);
+    esp_rom_gpio_pad_set_drv(q_gpio_num,   drv);
+    esp_rom_gpio_pad_set_drv(d_gpio_num,   drv);
+    esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv);
+    if (hd_gpio_num <= MAX_PAD_GPIO_NUM) {
+        esp_rom_gpio_pad_set_drv(hd_gpio_num, drv);
+    }
+    if (wp_gpio_num <= MAX_PAD_GPIO_NUM) {
+        esp_rom_gpio_pad_set_drv(wp_gpio_num, drv);
+    }
+}
+
+static void IRAM_ATTR bootloader_init_flash_configure(void)
+{
+    bootloader_flash_dummy_config(&bootloader_image_hdr);
+    bootloader_flash_cs_timing_config();
+}
+
+static esp_err_t bootloader_init_spi_flash(void)
+{
+    bootloader_init_flash_configure();
+    esp_rom_spiflash_unlock();
+
+    update_flash_config(&bootloader_image_hdr);
+    return ESP_OK;
+}
+
+void bootloader_config_wdt(void)
+{
+    wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL};
+    wdt_hal_write_protect_disable(&rtc_wdt_ctx);
+    wdt_hal_set_flashboot_en(&rtc_wdt_ctx, false);
+    wdt_hal_write_protect_enable(&rtc_wdt_ctx);
+
+#ifdef CONFIG_ESP_MCUBOOT_WDT_ENABLE
+    wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false);
+    uint32_t stage_timeout_ticks = (uint32_t)((uint64_t)CONFIG_BOOTLOADER_WDT_TIME_MS * rtc_clk_slow_freq_get_hz() / 1000);
+    wdt_hal_write_protect_disable(&rtc_wdt_ctx);
+    wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC);
+    wdt_hal_enable(&rtc_wdt_ctx);
+    wdt_hal_write_protect_enable(&rtc_wdt_ctx);
+#endif
+
+    wdt_hal_context_t wdt_ctx = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0};
+    wdt_hal_write_protect_disable(&wdt_ctx);
+    wdt_hal_set_flashboot_en(&wdt_ctx, false);
+    wdt_hal_write_protect_enable(&wdt_ctx);
+}
+
+static void bootloader_init_uart_console(void)
+{
+    const int uart_num = 0;
+
+    uartAttach(NULL);
+    ets_install_uart_printf();
+    uart_tx_wait_idle(0);
+
+    const int uart_baud = CONFIG_ESP_CONSOLE_UART_BAUDRATE;
+    uart_div_modify(uart_num, (rtc_clk_apb_freq_get() << 4) / uart_baud);
+}
+
+static void bootloader_super_wdt_auto_feed(void)
+{
+    REG_SET_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_AUTO_FEED_EN);
+}
+
+esp_err_t bootloader_init(void)
+{
+    esp_err_t ret = ESP_OK;
+    bootloader_super_wdt_auto_feed();
+
+    bootloader_init_mem();
+
+    /* check that static RAM is after the stack */
+#ifndef NDEBUG
+    {
+        assert(&_bss_start <= &_bss_end);
+        assert(&_data_start <= &_data_end);
+    }
+#endif
+    /* clear bss section */
+    bootloader_clear_bss_section();
+    /* reset MMU */
+    bootloader_reset_mmu();
+    /* config clock */
+    bootloader_clock_configure();
+    /* initialize uart console, from now on, we can use ets_printf */
+    bootloader_init_uart_console();
+    /* read bootloader header */
+    if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
+        goto err;
+    }
+    /* initialize spi flash */
+    if ((ret = bootloader_init_spi_flash()) != ESP_OK) {
+        goto err;
+    }
+    /* config WDT */
+    bootloader_config_wdt();
+err:
+    return ret;
+}
diff --git a/boot/espressif/hal/src/esp32s3/bootloader_init.c b/boot/espressif/hal/src/esp32s3/bootloader_init.c
new file mode 100644
index 0000000..c9d627a
--- /dev/null
+++ b/boot/espressif/hal/src/esp32s3/bootloader_init.c
@@ -0,0 +1,318 @@
+/*
+ * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "sdkconfig.h"
+#include "esp_attr.h"
+#include "esp_image_format.h"
+#include "flash_qio_mode.h"
+#include "esp_rom_efuse.h"
+#include "esp_rom_gpio.h"
+#include "esp_rom_sys.h"
+#include "esp_rom_uart.h"
+#include "esp_efuse.h"
+
+#include "bootloader_init.h"
+#include "bootloader_mem.h"
+#include "bootloader_clock.h"
+#include "bootloader_flash_config.h"
+#include "bootloader_flash.h"
+#include "bootloader_flash_priv.h"
+#include "bootloader_soc.h"
+
+#include "soc/cpu.h"
+#include "soc/dport_reg.h"
+#include "soc/efuse_reg.h"
+#include "soc/rtc.h"
+#include "soc/rtc_cntl_reg.h"
+#include "soc/extmem_reg.h"
+#include "soc/io_mux_reg.h"
+#include "soc/assist_debug_reg.h"
+
+#include "hal/wdt_hal.h"
+
+#include "esp32s3/rom/cache.h"
+#include "esp32s3/rom/ets_sys.h"
+#include "esp32s3/rom/spi_flash.h"
+#include "esp32s3/rom/uart.h"
+
+#include "esp_log.h"
+#include "mcuboot_config/mcuboot_config.h"
+
+static const char *TAG = "boot.esp32s3";
+
+esp_image_header_t WORD_ALIGNED_ATTR bootloader_image_hdr;
+
+void bootloader_clear_bss_section(void)
+{
+    memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start));
+}
+
+static void bootloader_reset_mmu(void)
+{
+    Cache_Suspend_DCache();
+    Cache_Invalidate_DCache_All();
+    Cache_MMU_Init();
+
+    REG_CLR_BIT(EXTMEM_ICACHE_CTRL1_REG, EXTMEM_ICACHE_SHUT_CORE0_BUS);
+    REG_CLR_BIT(EXTMEM_ICACHE_CTRL1_REG, EXTMEM_ICACHE_SHUT_CORE1_BUS);
+}
+
+esp_err_t bootloader_read_bootloader_header(void)
+{
+    if (bootloader_flash_read(ESP_BOOTLOADER_OFFSET, &bootloader_image_hdr, sizeof(esp_image_header_t), true) != ESP_OK) {
+        return ESP_FAIL;
+    }
+    return ESP_OK;
+}
+
+static void update_flash_config(const esp_image_header_t *bootloader_hdr)
+{
+    uint32_t size;
+    switch (bootloader_hdr->spi_size) {
+    case ESP_IMAGE_FLASH_SIZE_1MB:
+        size = 1;
+        break;
+    case ESP_IMAGE_FLASH_SIZE_2MB:
+        size = 2;
+        break;
+    case ESP_IMAGE_FLASH_SIZE_4MB:
+        size = 4;
+        break;
+    case ESP_IMAGE_FLASH_SIZE_8MB:
+        size = 8;
+        break;
+    case ESP_IMAGE_FLASH_SIZE_16MB:
+        size = 16;
+        break;
+    default:
+        size = 2;
+    }
+    uint32_t autoload = Cache_Suspend_DCache();
+    // Set flash chip size
+    esp_rom_spiflash_config_param(g_rom_flashchip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff);
+    Cache_Resume_DCache(autoload);
+}
+
+void IRAM_ATTR bootloader_configure_spi_pins(int drv)
+{
+    const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
+    uint8_t wp_pin = esp_rom_efuse_get_flash_wp_gpio();
+    uint8_t clk_gpio_num = SPI_CLK_GPIO_NUM;
+    uint8_t q_gpio_num   = SPI_Q_GPIO_NUM;
+    uint8_t d_gpio_num   = SPI_D_GPIO_NUM;
+    uint8_t cs0_gpio_num = SPI_CS0_GPIO_NUM;
+    uint8_t hd_gpio_num  = SPI_HD_GPIO_NUM;
+    uint8_t wp_gpio_num  = SPI_WP_GPIO_NUM;
+    if (spiconfig == 0) {
+
+    } else {
+        clk_gpio_num = spiconfig         & 0x3f;
+        q_gpio_num = (spiconfig >> 6)    & 0x3f;
+        d_gpio_num = (spiconfig >> 12)   & 0x3f;
+        cs0_gpio_num = (spiconfig >> 18) & 0x3f;
+        hd_gpio_num = (spiconfig >> 24)  & 0x3f;
+        wp_gpio_num = wp_pin;
+    }
+    esp_rom_gpio_pad_set_drv(clk_gpio_num, drv);
+    esp_rom_gpio_pad_set_drv(q_gpio_num,   drv);
+    esp_rom_gpio_pad_set_drv(d_gpio_num,   drv);
+    esp_rom_gpio_pad_set_drv(cs0_gpio_num, drv);
+    if (hd_gpio_num <= MAX_PAD_GPIO_NUM) {
+        esp_rom_gpio_pad_set_drv(hd_gpio_num, drv);
+    }
+    if (wp_gpio_num <= MAX_PAD_GPIO_NUM) {
+        esp_rom_gpio_pad_set_drv(wp_gpio_num, drv);
+    }
+}
+
+static void IRAM_ATTR bootloader_init_flash_configure(void)
+{
+    bootloader_flash_dummy_config(&bootloader_image_hdr);
+    bootloader_flash_cs_timing_config();
+}
+
+static esp_err_t bootloader_init_spi_flash(void)
+{
+    bootloader_init_flash_configure();
+#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
+    const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
+    if (spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_SPI && spiconfig != ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) {
+        ESP_LOGE(TAG, "SPI flash pins are overridden. Enable CONFIG_SPI_FLASH_ROM_DRIVER_PATCH in menuconfig");
+        return ESP_FAIL;
+    }
+#endif
+
+    bootloader_flash_unlock();
+    update_flash_config(&bootloader_image_hdr);
+    //ensure the flash is write-protected
+    bootloader_enable_wp();
+    return ESP_OK;
+}
+
+void bootloader_config_wdt(void)
+{
+    wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL};
+    wdt_hal_write_protect_disable(&rtc_wdt_ctx);
+    wdt_hal_set_flashboot_en(&rtc_wdt_ctx, false);
+    wdt_hal_write_protect_enable(&rtc_wdt_ctx);
+
+#ifdef CONFIG_ESP_MCUBOOT_WDT_ENABLE
+    wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false);
+    uint32_t stage_timeout_ticks = (uint32_t)((uint64_t)CONFIG_BOOTLOADER_WDT_TIME_MS * rtc_clk_slow_freq_get_hz() / 1000);
+    wdt_hal_write_protect_disable(&rtc_wdt_ctx);
+    wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC);
+    wdt_hal_enable(&rtc_wdt_ctx);
+    wdt_hal_write_protect_enable(&rtc_wdt_ctx);
+#endif
+
+    wdt_hal_context_t wdt_ctx = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0};
+    wdt_hal_write_protect_disable(&wdt_ctx);
+    wdt_hal_set_flashboot_en(&wdt_ctx, false);
+    wdt_hal_write_protect_enable(&wdt_ctx);
+}
+
+static void bootloader_init_uart_console(void)
+{
+    const int uart_num = 0;
+
+    esp_rom_install_uart_printf();
+    esp_rom_uart_tx_wait_idle(0);
+    uint32_t clock_hz = UART_CLK_FREQ_ROM;
+    esp_rom_uart_set_clock_baudrate(uart_num, clock_hz, CONFIG_ESP_CONSOLE_UART_BAUDRATE);
+}
+
+static void wdt_reset_cpu0_info_enable(void)
+{
+    REG_SET_BIT(SYSTEM_CPU_PERI_CLK_EN_REG, SYSTEM_CLK_EN_ASSIST_DEBUG);
+    REG_CLR_BIT(SYSTEM_CPU_PERI_RST_EN_REG, SYSTEM_RST_EN_ASSIST_DEBUG);
+    REG_WRITE(ASSIST_DEBUG_CORE_0_RCD_PDEBUGENABLE_REG, 1);
+    REG_WRITE(ASSIST_DEBUG_CORE_0_RCD_RECORDING_REG, 1);
+}
+
+#if MCUBOOT_LOG_LEVEL >= MCUBOOT_LOG_LEVEL_DEBUG
+static void wdt_reset_info_dump(int cpu)
+{
+    uint32_t inst = 0, pid = 0, stat = 0, data = 0, pc = 0,
+             lsstat = 0, lsaddr = 0, lsdata = 0, dstat = 0;
+    const char *cpu_name = cpu ? "APP" : "PRO";
+
+    stat = 0xdeadbeef;
+    pid = 0;
+    if (cpu == 0) {
+        inst    = REG_READ(ASSIST_DEBUG_CORE_0_RCD_PDEBUGINST_REG);
+        dstat   = REG_READ(ASSIST_DEBUG_CORE_0_RCD_PDEBUGSTATUS_REG);
+        data    = REG_READ(ASSIST_DEBUG_CORE_0_RCD_PDEBUGDATA_REG);
+        pc      = REG_READ(ASSIST_DEBUG_CORE_0_RCD_PDEBUGPC_REG);
+        lsstat  = REG_READ(ASSIST_DEBUG_CORE_0_RCD_PDEBUGLS0STAT_REG);
+        lsaddr  = REG_READ(ASSIST_DEBUG_CORE_0_RCD_PDEBUGLS0ADDR_REG);
+        lsdata  = REG_READ(ASSIST_DEBUG_CORE_0_RCD_PDEBUGLS0DATA_REG);
+    } else {
+        inst    = REG_READ(ASSIST_DEBUG_CORE_1_RCD_PDEBUGINST_REG);
+        dstat   = REG_READ(ASSIST_DEBUG_CORE_1_RCD_PDEBUGSTATUS_REG);
+        data    = REG_READ(ASSIST_DEBUG_CORE_1_RCD_PDEBUGDATA_REG);
+        pc      = REG_READ(ASSIST_DEBUG_CORE_1_RCD_PDEBUGPC_REG);
+        lsstat  = REG_READ(ASSIST_DEBUG_CORE_1_RCD_PDEBUGLS0STAT_REG);
+        lsaddr  = REG_READ(ASSIST_DEBUG_CORE_1_RCD_PDEBUGLS0ADDR_REG);
+        lsdata  = REG_READ(ASSIST_DEBUG_CORE_1_RCD_PDEBUGLS0DATA_REG);
+    }
+
+    ESP_LOGD(TAG, "WDT reset info: %s CPU STATUS        0x%08x", cpu_name, stat);
+    ESP_LOGD(TAG, "WDT reset info: %s CPU PID           0x%08x", cpu_name, pid);
+    ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGINST    0x%08x", cpu_name, inst);
+    ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGSTATUS  0x%08x", cpu_name, dstat);
+    ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGDATA    0x%08x", cpu_name, data);
+    ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGPC      0x%08x", cpu_name, pc);
+    ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0STAT 0x%08x", cpu_name, lsstat);
+    ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0ADDR 0x%08x", cpu_name, lsaddr);
+    ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0DATA 0x%08x", cpu_name, lsdata);
+}
+#endif
+
+static void bootloader_check_wdt_reset(void)
+{
+    int wdt_rst = 0;
+    soc_reset_reason_t rst_reas[2];
+
+    rst_reas[0] = esp_rom_get_reset_reason(0);
+    rst_reas[1] = esp_rom_get_reset_reason(1);
+    if (rst_reas[0] == RESET_REASON_CORE_RTC_WDT || rst_reas[0] == RESET_REASON_CORE_MWDT0 || rst_reas[0] == RESET_REASON_CORE_MWDT1 ||
+        rst_reas[0] == RESET_REASON_CPU0_MWDT0 || rst_reas[0] == RESET_REASON_CPU0_RTC_WDT) {
+        ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
+        wdt_rst = 1;
+    }
+    if (rst_reas[1] == RESET_REASON_CORE_RTC_WDT || rst_reas[1] == RESET_REASON_CORE_MWDT0 || rst_reas[1] == RESET_REASON_CORE_MWDT1 ||
+        rst_reas[1] == RESET_REASON_CPU1_MWDT1 || rst_reas[1] == RESET_REASON_CPU1_RTC_WDT) {
+        ESP_LOGW(TAG, "APP CPU has been reset by WDT.");
+        wdt_rst = 1;
+    }
+    if (wdt_rst) {
+#if MCUBOOT_LOG_LEVEL >= MCUBOOT_LOG_LEVEL_DEBUG
+        // if reset by WDT dump info from trace port
+        wdt_reset_info_dump(0);
+        wdt_reset_info_dump(1);
+#endif
+    }
+    wdt_reset_cpu0_info_enable();
+}
+
+static void bootloader_super_wdt_auto_feed(void)
+{
+    REG_WRITE(RTC_CNTL_SWD_WPROTECT_REG, RTC_CNTL_SWD_WKEY_VALUE);
+    REG_SET_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_AUTO_FEED_EN);
+    REG_WRITE(RTC_CNTL_SWD_WPROTECT_REG, 0);}
+
+static inline void bootloader_ana_reset_config(void)
+{
+    //Enable WDT, BOR, and GLITCH reset
+    bootloader_ana_super_wdt_reset_config(true);
+    bootloader_ana_bod_reset_config(true);
+    bootloader_ana_clock_glitch_reset_config(true);
+}
+
+esp_err_t bootloader_init(void)
+{
+    esp_err_t ret = ESP_OK;
+    bootloader_ana_reset_config();
+    bootloader_super_wdt_auto_feed();
+    // protect memory region
+    bootloader_init_mem();
+    /* check that static RAM is after the stack */
+#ifndef NDEBUG
+    {
+        assert(&_bss_start <= &_bss_end);
+        assert(&_data_start <= &_data_end);
+    }
+#endif
+    // clear bss section
+    bootloader_clear_bss_section();
+    // reset MMU
+    bootloader_reset_mmu();
+    // config clock
+    bootloader_clock_configure();
+    /* initialize uart console, from now on, we can use ets_printf */
+    bootloader_init_uart_console();
+    // Check and run XMC startup flow
+    if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) {
+       goto err;
+    }
+    // read bootloader header
+    if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
+        goto err;
+    }
+    // initialize spi flash
+    if ((ret = bootloader_init_spi_flash()) != ESP_OK) {
+        goto err;
+    }
+    // check whether a WDT reset happend
+    bootloader_check_wdt_reset();
+    // config WDT
+    bootloader_config_wdt();
+
+err:
+    return ret;
+}
diff --git a/boot/espressif/hal/src/flash_encrypt.c b/boot/espressif/hal/src/flash_encrypt.c
new file mode 100644
index 0000000..143571b
--- /dev/null
+++ b/boot/espressif/hal/src/flash_encrypt.c
@@ -0,0 +1,351 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <strings.h>
+#include "bootloader_flash_priv.h"
+#include "bootloader_random.h"
+#include "esp_image_format.h"
+#include "esp_flash_encrypt.h"
+#include "esp_flash_partitions.h"
+#include "esp_secure_boot.h"
+#include "esp_efuse.h"
+#include "esp_efuse_table.h"
+#include "esp_log.h"
+#include "hal/wdt_hal.h"
+
+#include "esp_mcuboot_image.h"
+
+#if CONFIG_IDF_TARGET_ESP32
+#define CRYPT_CNT ESP_EFUSE_FLASH_CRYPT_CNT
+#define WR_DIS_CRYPT_CNT ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT
+#else
+#define CRYPT_CNT ESP_EFUSE_SPI_BOOT_CRYPT_CNT
+#define WR_DIS_CRYPT_CNT ESP_EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT
+#endif
+
+/* This file implements FLASH ENCRYPTION related APIs to perform
+ * various operations such as programming necessary flash encryption
+ * eFuses, detect whether flash encryption is enabled (by reading eFuse)
+ * and if required encrypt the partitions in flash memory
+ */
+
+static const char *TAG = "flash_encrypt";
+
+/* Static functions for stages of flash encryption */
+static esp_err_t initialise_flash_encryption(void);
+static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_crypt_wr_dis) __attribute__((unused));
+static esp_err_t encrypt_bootloader(void);
+static esp_err_t encrypt_primary_slot(void);
+
+esp_err_t esp_flash_encrypt_check_and_update(void)
+{
+    size_t flash_crypt_cnt = 0;
+    esp_efuse_read_field_cnt(CRYPT_CNT, &flash_crypt_cnt);
+    bool flash_crypt_wr_dis = esp_efuse_read_field_bit(WR_DIS_CRYPT_CNT);
+
+    ESP_LOGV(TAG, "CRYPT_CNT %d, write protection %d", flash_crypt_cnt, flash_crypt_wr_dis);
+
+    if (flash_crypt_cnt % 2 == 1) {
+        /* Flash is already encrypted */
+        int left = (CRYPT_CNT[0]->bit_count - flash_crypt_cnt) / 2;
+        if (flash_crypt_wr_dis) {
+            left = 0; /* can't update FLASH_CRYPT_CNT, no more flashes */
+        }
+        ESP_LOGI(TAG, "flash encryption is enabled (%d plaintext flashes left)", left);
+        return ESP_OK;
+    } else {
+#ifndef CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED
+        /* Flash is not encrypted, so encrypt it! */
+        return encrypt_flash_contents(flash_crypt_cnt, flash_crypt_wr_dis);
+#else
+        ESP_LOGE(TAG, "flash encryption is not enabled, and SECURE_FLASH_REQUIRE_ALREADY_ENABLED "
+                      "is set, refusing to boot.");
+        return ESP_ERR_INVALID_STATE;
+#endif // CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED
+    }
+}
+
+static esp_err_t check_and_generate_encryption_keys(void)
+{
+    size_t key_size = 32;
+#ifdef CONFIG_IDF_TARGET_ESP32
+    enum { BLOCKS_NEEDED = 1 };
+    esp_efuse_purpose_t purposes[BLOCKS_NEEDED] = {
+        ESP_EFUSE_KEY_PURPOSE_FLASH_ENCRYPTION,
+    };
+    esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK_ENCRYPT_FLASH);
+    if (coding_scheme != EFUSE_CODING_SCHEME_NONE && coding_scheme != EFUSE_CODING_SCHEME_3_4) {
+        ESP_LOGE(TAG, "Unknown/unsupported CODING_SCHEME value 0x%x", coding_scheme);
+        return ESP_ERR_NOT_SUPPORTED;
+    }
+    if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
+        key_size = 24;
+    }
+#else
+#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_AES256
+    enum { BLOCKS_NEEDED = 2 };
+    esp_efuse_purpose_t purposes[BLOCKS_NEEDED] = {
+        ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1,
+        ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2,
+    };
+    if (esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY, NULL)) {
+        ESP_LOGE(TAG, "XTS_AES_128_KEY is already in use, XTS_AES_256_KEY_1/2 can not be used");
+        return ESP_ERR_INVALID_STATE;
+    }
+#else
+    enum { BLOCKS_NEEDED = 1 };
+    esp_efuse_purpose_t purposes[BLOCKS_NEEDED] = {
+        ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY,
+    };
+#endif // CONFIG_SECURE_FLASH_ENCRYPTION_AES256
+#endif // CONFIG_IDF_TARGET_ESP32
+
+    /* Initialize all efuse block entries to invalid (max) value */
+    esp_efuse_block_t blocks[BLOCKS_NEEDED] = {[0 ... BLOCKS_NEEDED-1] = EFUSE_BLK_KEY_MAX};
+    bool has_key = true;
+    for (unsigned i = 0; i < BLOCKS_NEEDED; i++) {
+        bool tmp_has_key = esp_efuse_find_purpose(purposes[i], &blocks[i]);
+        if (tmp_has_key) { // For ESP32: esp_efuse_find_purpose() always returns True, need to check whether the key block is used or not.
+            tmp_has_key &= !esp_efuse_key_block_unused(blocks[i]);
+        }
+        if (i == 1 && tmp_has_key != has_key) {
+            ESP_LOGE(TAG, "Invalid efuse key blocks: Both AES-256 key blocks must be set.");
+            return ESP_ERR_INVALID_STATE;
+        }
+        has_key &= tmp_has_key;
+    }
+
+    if (!has_key) {
+        /* Generate key */
+        uint8_t keys[BLOCKS_NEEDED][32] = { 0 };
+        ESP_LOGI(TAG, "Generating new flash encryption key...");
+        for (unsigned i = 0; i < BLOCKS_NEEDED; ++i) {
+            bootloader_fill_random(keys[i], key_size);
+        }
+        ESP_LOGD(TAG, "Key generation complete");
+
+        esp_err_t err = esp_efuse_write_keys(purposes, keys, BLOCKS_NEEDED);
+        if (err != ESP_OK) {
+            if (err == ESP_ERR_NOT_ENOUGH_UNUSED_KEY_BLOCKS) {
+                ESP_LOGE(TAG, "Not enough free efuse key blocks (need %d) to continue", BLOCKS_NEEDED);
+            } else {
+                ESP_LOGE(TAG, "Failed to write efuse block with purpose (err=0x%x). Can't continue.", err);
+            }
+            return err;
+        }
+    } else {
+        for (unsigned i = 0; i < BLOCKS_NEEDED; i++) {
+            if (!esp_efuse_get_key_dis_write(blocks[i])
+                || !esp_efuse_get_key_dis_read(blocks[i])
+                || !esp_efuse_get_keypurpose_dis_write(blocks[i])) { // For ESP32: no keypurpose, it returns always True.
+                ESP_LOGE(TAG, "Invalid key state, check read&write protection for key and keypurpose(if exists)");
+                return ESP_ERR_INVALID_STATE;
+            }
+        }
+        ESP_LOGI(TAG, "Using pre-loaded flash encryption key in efuse");
+    }
+    return ESP_OK;
+}
+
+static esp_err_t initialise_flash_encryption(void)
+{
+    esp_efuse_batch_write_begin(); /* Batch all efuse writes at the end of this function */
+
+    /* Before first flash encryption pass, need to initialise key & crypto config */
+    esp_err_t err = check_and_generate_encryption_keys();
+    if (err != ESP_OK) {
+        esp_efuse_batch_write_cancel();
+        return err;
+    }
+
+    err = esp_flash_encryption_enable_secure_features();
+    if (err != ESP_OK) {
+        esp_efuse_batch_write_cancel();
+        return err;
+    }
+
+    err = esp_efuse_batch_write_commit();
+    if (err != ESP_OK) {
+        ESP_LOGE(TAG, "Error programming security eFuses (err=0x%x).", err);
+        return err;
+    }
+
+    return ESP_OK;
+}
+
+/* Encrypt all flash data that should be encrypted */
+static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_crypt_wr_dis)
+{
+    esp_err_t err;
+
+    /* If all flash_crypt_cnt bits are burned or write-disabled, the
+       device can't re-encrypt itself. */
+    if (flash_crypt_wr_dis || flash_crypt_cnt == CRYPT_CNT[0]->bit_count) {
+        ESP_LOGE(TAG, "Cannot re-encrypt data CRYPT_CNT %d write disabled %d", flash_crypt_cnt, flash_crypt_wr_dis);
+        return ESP_FAIL;
+    }
+
+    if (flash_crypt_cnt == 0) {
+        /* Very first flash of encrypted data: generate keys, etc. */
+        err = initialise_flash_encryption();
+        if (err != ESP_OK) {
+            return err;
+        }
+    }
+
+    err = encrypt_bootloader();
+    if (err != ESP_OK) {
+        return err;
+    }
+
+    /* If the primary slot executable application is not encrypted,
+     * then encrypt it
+     */
+    err = encrypt_primary_slot();
+    if (err != ESP_OK) {
+        return err;
+    }
+
+    /* Unconditionally encrypts remaining regions
+     * This will need changes when implementing multi-slot support
+     */
+    ESP_LOGI(TAG, "Encrypting remaining flash...");
+    uint32_t region_addr = CONFIG_ESP_APPLICATION_SECONDARY_START_ADDRESS;
+    size_t region_size = CONFIG_ESP_APPLICATION_SIZE;
+    err = esp_flash_encrypt_region(region_addr, region_size);
+    if (err != ESP_OK) {
+        return err;
+    }
+    region_addr = CONFIG_ESP_SCRATCH_OFFSET;
+    region_size = CONFIG_ESP_SCRATCH_SIZE;
+    err = esp_flash_encrypt_region(region_addr, region_size);
+    if (err != ESP_OK) {
+        return err;
+    }
+
+#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE
+    // Go straight to max, permanently enabled
+    ESP_LOGI(TAG, "Setting CRYPT_CNT for permanent encryption");
+    size_t new_flash_crypt_cnt = CRYPT_CNT[0]->bit_count - flash_crypt_cnt;
+#else
+    /* Set least significant 0-bit in flash_crypt_cnt */
+    size_t new_flash_crypt_cnt = 1;
+#endif
+    ESP_LOGD(TAG, "CRYPT_CNT %d -> %d", flash_crypt_cnt, new_flash_crypt_cnt);
+    err = esp_efuse_write_field_cnt(CRYPT_CNT, new_flash_crypt_cnt);
+
+    ESP_LOGI(TAG, "Flash encryption completed");
+
+    return ESP_OK;
+}
+
+static esp_err_t encrypt_bootloader(void)
+{
+    esp_err_t err;
+    uint32_t image_length;
+    /* Check for plaintext bootloader (verification will fail if it's already encrypted) */
+    if (esp_image_verify_bootloader(&image_length) == ESP_OK) {
+        ESP_LOGI(TAG, "Encrypting bootloader...");
+
+        err = esp_flash_encrypt_region(ESP_BOOTLOADER_OFFSET, CONFIG_ESP_BOOTLOADER_SIZE);
+        if (err != ESP_OK) {
+            ESP_LOGE(TAG, "Failed to encrypt bootloader in place: 0x%x", err);
+            return err;
+        }
+        ESP_LOGI(TAG, "Bootloader encrypted successfully");
+    } else {
+        ESP_LOGW(TAG, "No valid bootloader was found");
+        return ESP_ERR_NOT_FOUND;
+    }
+
+    return ESP_OK;
+}
+
+static esp_err_t verify_img_header(uint32_t addr, const esp_image_load_header_t *image, bool silent)
+{
+    esp_err_t err = ESP_OK;
+
+    if (image->header_magic != ESP_LOAD_HEADER_MAGIC) {
+        if (!silent) {
+            ESP_LOGE(TAG, "image at 0x%x has invalid magic byte",
+                     addr);
+        }
+        err = ESP_ERR_IMAGE_INVALID;
+    }
+
+    return err;
+}
+
+static esp_err_t encrypt_primary_slot(void)
+{
+    esp_err_t err;
+
+    esp_image_load_header_t img_header;
+
+    /* Check if the slot is plaintext or encrypted, 0x20 offset is for skipping
+     * MCUboot header
+     */
+    err = bootloader_flash_read(CONFIG_ESP_APPLICATION_PRIMARY_START_ADDRESS + 0x20,
+                                &img_header, sizeof(esp_image_load_header_t), true);
+    if (err != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to read slot img header");
+        return err;
+    } else {
+        err = verify_img_header(CONFIG_ESP_APPLICATION_PRIMARY_START_ADDRESS,
+                                &img_header, true);
+    }
+
+    if (err == ESP_OK) {
+        ESP_LOGI(TAG, "Encrypting primary slot...");
+
+        err = esp_flash_encrypt_region(CONFIG_ESP_APPLICATION_PRIMARY_START_ADDRESS,
+                                       CONFIG_ESP_APPLICATION_SIZE);
+        if (err != ESP_OK) {
+            ESP_LOGE(TAG, "Failed to encrypt slot in place: 0x%x", err);
+            return err;
+        }
+    } else {
+        ESP_LOGW(TAG, "Slot already encrypted or no valid image was found");
+    }
+
+    return ESP_OK;
+}
+
+esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length)
+{
+    esp_err_t err;
+    uint32_t buf[FLASH_SECTOR_SIZE / sizeof(uint32_t)];
+
+    if (src_addr % FLASH_SECTOR_SIZE != 0) {
+        ESP_LOGE(TAG, "esp_flash_encrypt_region bad src_addr 0x%x", src_addr);
+        return ESP_FAIL;
+    }
+
+    wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL};
+    for (size_t i = 0; i < data_length; i += FLASH_SECTOR_SIZE) {
+        wdt_hal_write_protect_disable(&rtc_wdt_ctx);
+        wdt_hal_feed(&rtc_wdt_ctx);
+        wdt_hal_write_protect_enable(&rtc_wdt_ctx);
+        uint32_t sec_start = i + src_addr;
+        err = bootloader_flash_read(sec_start, buf, FLASH_SECTOR_SIZE, true);
+        if (err != ESP_OK) {
+            goto flash_failed;
+        }
+        err = bootloader_flash_erase_sector(sec_start / FLASH_SECTOR_SIZE);
+        if (err != ESP_OK) {
+            goto flash_failed;
+        }
+        err = bootloader_flash_write(sec_start, buf, FLASH_SECTOR_SIZE, true);
+        if (err != ESP_OK) {
+            goto flash_failed;
+        }
+    }
+    return ESP_OK;
+
+flash_failed:
+    ESP_LOGE(TAG, "flash operation failed: 0x%x", err);
+    return err;
+}
diff --git a/boot/espressif/hal/src/secure_boot.c b/boot/espressif/hal/src/secure_boot.c
new file mode 100644
index 0000000..9cb24be
--- /dev/null
+++ b/boot/espressif/hal/src/secure_boot.c
@@ -0,0 +1,248 @@
+/*
+ * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <string.h>
+#include "sdkconfig.h"
+#include "esp_log.h"
+#include "esp_secure_boot.h"
+#include "bootloader_flash_priv.h"
+#include "bootloader_sha.h"
+#include "bootloader_utility.h"
+#include "esp_image_format.h"
+#include "esp_efuse.h"
+#include "esp_efuse_table.h"
+
+/* The following API implementations are used only when called
+ * from the bootloader code.
+ */
+
+#ifdef CONFIG_SECURE_BOOT_V2_ENABLED
+
+#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
+static const char *TAG = "secure_boot_v2";
+
+/* A signature block is valid when it has correct magic byte, crc and image digest. */
+static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *block, int block_num, const uint8_t *image_digest)
+{
+    if (block->magic_byte != ETS_SECURE_BOOT_V2_SIGNATURE_MAGIC) {
+        // All signature blocks have been parsed, no new signature block present.
+        ESP_LOGD(TAG, "Signature block(%d) invalid/absent.", block_num);
+        return ESP_FAIL;
+    }
+    if (block->block_crc != esp_rom_crc32_le(0, (uint8_t *)block, CRC_SIGN_BLOCK_LEN)) {
+        ESP_LOGE(TAG, "Magic byte correct but incorrect crc.");
+        return ESP_FAIL;
+    }
+    if (memcmp(image_digest, block->image_digest, ESP_SECURE_BOOT_DIGEST_LEN)) {
+        ESP_LOGE(TAG, "Magic byte & CRC correct but incorrect image digest.");
+        return ESP_FAIL;
+    } else {
+        ESP_LOGD(TAG, "valid signature block(%d) found", block_num);
+        return ESP_OK;
+    }
+    return ESP_FAIL;
+}
+
+/* Generates the public key digests of the valid public keys in an image's
+   signature block, verifies each signature, and stores the key digests in the
+   public_key_digests structure.
+
+   @param flash_offset Image offset in flash
+   @param flash_size Image size in flash (not including signature block)
+   @param[out] public_key_digests Pointer to structure to hold the key digests for valid sig blocks
+
+
+   Note that this function doesn't read any eFuses, so it doesn't know if the
+   keys are ultimately trusted by the hardware or not
+
+   @return - ESP_OK if no signatures failed to verify, or if no valid signature blocks are found at all.
+           - ESP_FAIL if there's a valid signature block that doesn't verify using the included public key (unexpected!)
+*/
+static esp_err_t s_calculate_image_public_key_digests(uint32_t flash_offset, uint32_t flash_size, esp_image_sig_public_key_digests_t *public_key_digests)
+{
+    esp_err_t ret;
+    uint8_t image_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
+    uint8_t __attribute__((aligned(4))) key_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
+    size_t sig_block_addr = flash_offset + ALIGN_UP(flash_size, FLASH_SECTOR_SIZE);
+
+    ESP_LOGD(TAG, "calculating public key digests for sig blocks of image offset 0x%x (sig block offset 0x%x)", flash_offset, sig_block_addr);
+
+    bzero(public_key_digests, sizeof(esp_image_sig_public_key_digests_t));
+
+    ret = bootloader_sha256_flash_contents(flash_offset, sig_block_addr - flash_offset, image_digest);
+    if (ret != ESP_OK) {
+        ESP_LOGE(TAG, "error generating image digest, %d", ret);
+        return ret;
+    }
+
+    ESP_LOGD(TAG, "reading signature(s)");
+    const ets_secure_boot_signature_t *signatures = bootloader_mmap(sig_block_addr, sizeof(ets_secure_boot_signature_t));
+    if (signatures == NULL) {
+        ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", sig_block_addr, sizeof(ets_secure_boot_signature_t));
+        return ESP_FAIL;
+    }
+
+    /* Validating Signature block */
+    for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
+        const ets_secure_boot_sig_block_t *block = &signatures->block[i];
+
+        ret = validate_signature_block(block, i, image_digest);
+        if (ret != ESP_OK) {
+            ret = ESP_OK;  // past the last valid signature block
+            break;
+        }
+
+        /* Generating the SHA of the public key components in the signature block */
+        bootloader_sha256_handle_t sig_block_sha;
+        sig_block_sha = bootloader_sha256_start();
+        bootloader_sha256_data(sig_block_sha, &block->key, sizeof(block->key));
+        bootloader_sha256_finish(sig_block_sha, key_digest);
+
+        // Check we can verify the image using this signature and this key
+        uint8_t temp_verified_digest[ESP_SECURE_BOOT_DIGEST_LEN];
+        bool verified = ets_rsa_pss_verify(&block->key, block->signature, image_digest, temp_verified_digest);
+
+        if (!verified) {
+            /* We don't expect this: the signature blocks before we enable secure boot should all be verifiable or invalid,
+               so this is a fatal error
+            */
+            ret = ESP_FAIL;
+            ESP_LOGE(TAG, "Secure boot key (%d) verification failed.", i);
+            break;
+        }
+        ESP_LOGD(TAG, "Signature block (%d) is verified", i);
+        /* Copy the key digest to the buffer provided by the caller */
+        memcpy((void *)public_key_digests->key_digests[i], key_digest, ESP_SECURE_BOOT_DIGEST_LEN);
+        public_key_digests->num_digests++;
+    }
+
+    if (ret == ESP_OK && public_key_digests->num_digests > 0) {
+        ESP_LOGI(TAG, "Digests successfully calculated, %d valid signatures (image offset 0x%x)",
+                 public_key_digests->num_digests, flash_offset);
+    }
+
+    bootloader_munmap(signatures);
+    return ret;
+}
+
+esp_err_t check_and_generate_secure_boot_keys(void)
+{
+    esp_err_t ret;
+#ifdef CONFIG_IDF_TARGET_ESP32
+    esp_efuse_purpose_t secure_boot_key_purpose[SECURE_BOOT_NUM_BLOCKS] = {
+        ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2,
+    };
+    esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK_SECURE_BOOT);
+    if (coding_scheme != EFUSE_CODING_SCHEME_NONE) {
+        ESP_LOGE(TAG, "No coding schemes are supported in secure boot v2.(Detected scheme: 0x%x)", coding_scheme);
+        return ESP_ERR_NOT_SUPPORTED;
+    }
+#else
+    esp_efuse_purpose_t secure_boot_key_purpose[SECURE_BOOT_NUM_BLOCKS] = {
+        ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0,
+        ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1,
+        ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2,
+    };
+#endif // CONFIG_IDF_TARGET_ESP32
+
+    /* Verify the bootloader */
+    esp_image_metadata_t bootloader_data = { 0 };
+    ret = esp_image_verify_bootloader_data(&bootloader_data);
+    if (ret != ESP_OK) {
+        ESP_LOGE(TAG, "bootloader image appears invalid! error %d", ret);
+        return ret;
+    }
+
+    /* Initialize all efuse block entries to invalid (max) value */
+    esp_efuse_block_t blocks[SECURE_BOOT_NUM_BLOCKS] = {[0 ... SECURE_BOOT_NUM_BLOCKS-1] = EFUSE_BLK_KEY_MAX};
+    /* Check if secure boot digests are present */
+    bool has_secure_boot_digest = false;
+    for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
+        bool tmp_has_key = esp_efuse_find_purpose(secure_boot_key_purpose[i], &blocks[i]);
+        if (tmp_has_key) { // For ESP32: esp_efuse_find_purpose() always returns True, need to check whether the key block is used or not.
+            tmp_has_key &= !esp_efuse_key_block_unused(blocks[i]);
+        }
+        has_secure_boot_digest |= tmp_has_key;
+    }
+
+    esp_image_sig_public_key_digests_t boot_key_digests = {0};
+    ESP_LOGI(TAG, "Secure boot digests %s", has_secure_boot_digest ? "already present":"absent, generating..");
+
+    if (!has_secure_boot_digest) {
+        /* Generate the bootloader public key digests */
+        ret = s_calculate_image_public_key_digests(bootloader_data.start_addr, bootloader_data.image_len - SIG_BLOCK_PADDING, &boot_key_digests);
+        if (ret != ESP_OK) {
+            ESP_LOGE(TAG, "Bootloader signature block is invalid");
+            return ret;
+        }
+
+        if (boot_key_digests.num_digests == 0) {
+            ESP_LOGE(TAG, "No valid bootloader signature blocks found.");
+            return ESP_FAIL;
+        }
+        ESP_LOGI(TAG, "%d signature block(s) found appended to the bootloader.", boot_key_digests.num_digests);
+
+        ESP_LOGI(TAG, "Burning public key hash to eFuse");
+        ret = esp_efuse_write_keys(secure_boot_key_purpose, boot_key_digests.key_digests, boot_key_digests.num_digests);
+        if (ret != ESP_OK) {
+            if (ret == ESP_ERR_NOT_ENOUGH_UNUSED_KEY_BLOCKS) {
+                ESP_LOGE(TAG, "Bootloader signatures(%d) more than available key slots.", boot_key_digests.num_digests);
+            } else {
+                ESP_LOGE(TAG, "Failed to write efuse block with purpose (err=0x%x). Can't continue.", ret);
+            }
+            return ret;
+        }
+    } else {
+        for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
+            /* Check if corresponding digest slot is used or not */
+            if (blocks[i] == EFUSE_BLK_KEY_MAX) {
+                ESP_LOGD(TAG, "SECURE_BOOT_DIGEST%d slot is not used", i);
+                continue;
+            }
+
+#if SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
+            if (esp_efuse_get_digest_revoke(i)) {
+                continue;
+            }
+#endif
+            if (esp_efuse_get_key_dis_read(blocks[i])) {
+                ESP_LOGE(TAG, "Key digest (BLK%d) read protected, aborting...", blocks[i]);
+                return ESP_FAIL;
+            }
+            if (esp_efuse_block_is_empty(blocks[i])) {
+                ESP_LOGE(TAG, "%d eFuse block is empty, aborting...", blocks[i]);
+                return ESP_FAIL;
+            }
+            esp_efuse_set_key_dis_write(blocks[i]);
+            ret = esp_efuse_read_block(blocks[i], boot_key_digests.key_digests[boot_key_digests.num_digests], 0,
+                                            sizeof(boot_key_digests.key_digests[0]) * 8);
+            if (ret) {
+                ESP_LOGE(TAG, "Error during reading %d eFuse block (err=0x%x)", blocks[i], ret);
+                return ret;
+            }
+            boot_key_digests.num_digests++;
+        }
+        if (boot_key_digests.num_digests == 0) {
+            ESP_LOGE(TAG, "No valid pre-loaded public key digest in eFuse");
+            return ESP_FAIL;
+        }
+        ESP_LOGW(TAG, "Using pre-loaded public key digest in eFuse");
+    }
+
+#if SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
+    /* Revoke the empty signature blocks */
+    if (boot_key_digests.num_digests < SECURE_BOOT_NUM_BLOCKS) {
+        /* The revocation index can be 0, 1, 2. Bootloader count can be 1,2,3. */
+        for (unsigned i = boot_key_digests.num_digests; i < SECURE_BOOT_NUM_BLOCKS; i++) {
+            ESP_LOGI(TAG, "Revoking empty key digest slot (%d)...", i);
+            esp_efuse_set_digest_revoke(i);
+        }
+    }
+#endif // SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
+    return ESP_OK;
+}
+
+#endif // CONFIG_SECURE_BOOT_V2_ENABLED
diff --git a/boot/espressif/include/flash_map_backend/flash_map_backend.h b/boot/espressif/include/flash_map_backend/flash_map_backend.h
new file mode 100644
index 0000000..b56bcbc
--- /dev/null
+++ b/boot/espressif/include/flash_map_backend/flash_map_backend.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include <inttypes.h>
+
+struct flash_area {
+  uint8_t  fa_id;         /** The slot/scratch identification */
+  uint8_t  fa_device_id;  /** The device id (usually there's only one) */
+  uint16_t pad16;
+  uint32_t fa_off;        /** The flash offset from the beginning */
+  uint32_t fa_size;       /** The size of this sector */
+};
+
+//! Structure describing a sector within a flash area.
+struct flash_sector {
+  //! Offset of this sector, from the start of its flash area (not device).
+  uint32_t fs_off;
+
+  //! Size of this sector, in bytes.
+  uint32_t fs_size;
+};
+
+static inline uint8_t flash_area_get_device_id(const struct flash_area *fa)
+{
+    return (uint8_t)fa->fa_device_id;
+}
+static inline uint32_t flash_area_get_off(const struct flash_area *fa)
+{
+	return (uint32_t)fa->fa_off;
+}
+
+static inline uint32_t flash_area_get_size(const struct flash_area *fa)
+{
+	return (uint32_t)fa->fa_size;
+}
+
+static inline uint8_t flash_area_get_id(const struct flash_area *fa)
+{
+	return fa->fa_id;
+}
+
+static inline uint32_t flash_sector_get_off(const struct flash_sector *fs)
+{
+	return fs->fs_off;
+}
+
+static inline uint32_t flash_sector_get_size(const struct flash_sector *fs)
+{
+	return fs->fs_size;
+}
+
+//! Opens the area for use. id is one of the `fa_id`s */
+int flash_area_open(uint8_t id, const struct flash_area **area_outp);
+void flash_area_close(const struct flash_area *fa);
+
+//! Reads `len` bytes of flash memory at `off` to the buffer at `dst`
+int flash_area_read(const struct flash_area *fa, uint32_t off,
+                    void *dst, uint32_t len);
+//! Writes `len` bytes of flash memory at `off` from the buffer at `src`
+int flash_area_write(const struct flash_area *fa, uint32_t off,
+                     const void *src, uint32_t len);
+//! Erases `len` bytes of flash memory at `off`
+int flash_area_erase(const struct flash_area *fa,
+                     uint32_t off, uint32_t len);
+
+//! Returns this `flash_area`s alignment
+uint32_t flash_area_align(const struct flash_area *area);
+//! Returns the value read from an erased flash area byte
+uint8_t flash_area_erased_val(const struct flash_area *area);
+
+//! Given flash area ID, return info about sectors within the area
+int flash_area_get_sectors(int fa_id, uint32_t *count,
+                           struct flash_sector *sectors);
+
+//! Returns the `fa_id` for slot, where slot is 0 (primary) or 1 (secondary).
+//!
+//! `image_index` (0 or 1) is the index of the image. Image index is
+//!  relevant only when multi-image support support is enabled
+int flash_area_id_from_multi_image_slot(int image_index, int slot);
+int flash_area_id_from_image_slot(int slot);
+int flash_area_to_sectors(int idx, int *cnt, struct flash_area *fa);
diff --git a/boot/espressif/main.c b/boot/espressif/main.c
new file mode 100644
index 0000000..083efc5
--- /dev/null
+++ b/boot/espressif/main.c
@@ -0,0 +1,171 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <bootutil/bootutil.h>
+#include <bootutil/bootutil_log.h>
+#include <bootutil/fault_injection_hardening.h>
+#include <bootutil/image.h>
+
+#include "bootloader_init.h"
+#include "bootloader_utility.h"
+#include "bootloader_random.h"
+
+#if defined(CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH) || defined(CONFIG_SECURE_BOOT)
+#include "esp_efuse.h"
+#endif
+#ifdef CONFIG_SECURE_BOOT
+#include "esp_secure_boot.h"
+#endif
+#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
+#include "esp_flash_encrypt.h"
+#endif
+
+#include "esp_loader.h"
+#include "os/os_malloc.h"
+
+#ifdef CONFIG_SECURE_BOOT
+extern esp_err_t check_and_generate_secure_boot_keys(void);
+#endif
+
+void do_boot(struct boot_rsp *rsp)
+{
+    BOOT_LOG_INF("br_image_off = 0x%x", rsp->br_image_off);
+    BOOT_LOG_INF("ih_hdr_size = 0x%x", rsp->br_hdr->ih_hdr_size);
+    int slot = (rsp->br_image_off == CONFIG_ESP_APPLICATION_PRIMARY_START_ADDRESS) ? 0 : 1;
+    esp_app_image_load(slot, rsp->br_hdr->ih_hdr_size);
+}
+
+int main()
+{
+    bootloader_init();
+
+    BOOT_LOG_INF("Enabling RNG early entropy source...");
+    bootloader_random_enable();
+
+    /* Rough steps for a first boot when Secure Boot and/or Flash Encryption are still disabled on device:
+     * Secure Boot:
+     *   1) Calculate the SHA-256 hash digest of the public key and write to EFUSE.
+     *   2) Validate the application images and prepare the booting process.
+     *   3) Burn EFUSE to enable Secure Boot V2 (ABS_DONE_0).
+     * Flash Encryption:
+     *   4) Generate Flash Encryption key and write to EFUSE.
+     *   5) Encrypt flash in-place including bootloader, image primary/secondary slot and scratch.
+     *   6) Burn EFUSE to enable Flash Encryption.
+     *   7) Reset system to ensure Flash Encryption cache resets properly.
+     */
+
+#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
+    BOOT_LOG_WRN("eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!");
+    esp_efuse_init_virtual_mode_in_flash(CONFIG_EFUSE_VIRTUAL_OFFSET, CONFIG_EFUSE_VIRTUAL_SIZE);
+#endif
+
+#ifdef CONFIG_SECURE_BOOT
+    /* Steps 1 (see above for full description):
+     *   1) Compute digest of the public key.
+     */
+
+    BOOT_LOG_INF("enabling secure boot v2...");
+
+    bool sb_hw_enabled = esp_secure_boot_enabled();
+
+    if (sb_hw_enabled) {
+        BOOT_LOG_INF("secure boot v2 is already enabled, continuing..");
+    } else {
+        esp_efuse_batch_write_begin(); /* Batch all efuse writes at the end of this function */
+
+        esp_err_t err;
+        err = check_and_generate_secure_boot_keys();
+        if (err != ESP_OK) {
+            esp_efuse_batch_write_cancel();
+            FIH_PANIC;
+        }
+    }
+#endif
+
+    BOOT_LOG_INF("*** Booting MCUboot build %s ***", MCUBOOT_VER);
+
+    os_heap_init();
+
+    struct boot_rsp rsp;
+
+    fih_int fih_rc = FIH_FAILURE;
+
+    /* Step 2 (see above for full description):
+     *   2) MCUboot validates the application images and prepares the booting process.
+     */
+
+    FIH_CALL(boot_go, fih_rc, &rsp);
+
+    if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
+        BOOT_LOG_ERR("Unable to find bootable image");
+#ifdef CONFIG_SECURE_BOOT
+        esp_efuse_batch_write_cancel();
+#endif
+        FIH_PANIC;
+    }
+
+#ifdef CONFIG_SECURE_BOOT
+    /* Step 3 (see above for full description):
+     *   3) Burn EFUSE to enable Secure Boot V2.
+     */
+
+    if (!sb_hw_enabled) {
+        BOOT_LOG_INF("blowing secure boot efuse...");
+        esp_err_t err;
+        err = esp_secure_boot_enable_secure_features();
+        if (err != ESP_OK) {
+            esp_efuse_batch_write_cancel();
+            FIH_PANIC;
+        }
+
+        err = esp_efuse_batch_write_commit();
+        if (err != ESP_OK) {
+            BOOT_LOG_ERR("Error programming security eFuses (err=0x%x).", err);
+            FIH_PANIC;
+        }
+
+#ifdef CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE
+        assert(esp_efuse_read_field_bit(ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE));
+#endif
+
+        assert(esp_secure_boot_enabled());
+        BOOT_LOG_INF("Secure boot permanently enabled");
+    }
+#endif
+
+#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
+    /* Step 4, 5 & 6 (see above for full description):
+     *   4) Generate Flash Encryption key and write to EFUSE.
+     *   5) Encrypt flash in-place including bootloader, image primary/secondary slot and scratch.
+     *   6) Burn EFUSE to enable flash encryption
+     */
+
+    int rc;
+
+    BOOT_LOG_INF("Checking flash encryption...");
+    bool flash_encryption_enabled = esp_flash_encryption_enabled();
+    rc = esp_flash_encrypt_check_and_update();
+    if (rc != ESP_OK) {
+        BOOT_LOG_ERR("Flash encryption check failed (%d).", rc);
+        FIH_PANIC;
+    }
+
+    /* Step 7 (see above for full description):
+     *   7) Reset system to ensure flash encryption cache resets properly.
+     */
+    if (!flash_encryption_enabled && esp_flash_encryption_enabled()) {
+        BOOT_LOG_INF("Resetting with flash encryption enabled...");
+        bootloader_reset();
+    }
+#endif
+
+    BOOT_LOG_INF("Disabling RNG early entropy source...");
+    bootloader_random_disable();
+
+    do_boot(&rsp);
+
+    while(1);
+}
diff --git a/boot/espressif/os.c b/boot/espressif/os.c
new file mode 100644
index 0000000..2a2e9ca
--- /dev/null
+++ b/boot/espressif/os.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifdef CONFIG_ESP_USE_MBEDTLS
+
+#include <mbedtls/platform.h>
+#include <mbedtls/memory_buffer_alloc.h>
+
+#define CRYPTO_HEAP_SIZE 8192
+
+static unsigned char memory_buf[CRYPTO_HEAP_SIZE];
+
+/*
+ * Initialize Mbed TLS to be able to use the local heap.
+ */
+void os_heap_init(void)
+{
+    mbedtls_memory_buffer_alloc_init(memory_buf, sizeof(memory_buf));
+}
+#else
+
+void os_heap_init(void)
+{
+}
+
+#endif
diff --git a/boot/espressif/port/esp32/ld/bootloader.ld b/boot/espressif/port/esp32/ld/bootloader.ld
new file mode 100644
index 0000000..9933bd3
--- /dev/null
+++ b/boot/espressif/port/esp32/ld/bootloader.ld
@@ -0,0 +1,164 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/* Simplified memory map for the bootloader.
+ *
+ * The main purpose is to make sure the bootloader can load into main memory
+ * without overwriting itself.
+ */
+
+MEMORY
+{
+  iram_seg (RWX) :                  org = 0x40093000, len = 0x8800
+  iram_loader_seg (RWX) :           org = 0x4009B800, len = 0x4800
+  dram_seg (RW) :                   org = 0x3FFF5000, len = 0x8900
+}
+
+/*  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_esp32.*(.literal .text .literal.* .text.*)
+    *libhal.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*)
+    *libhal.a:bootloader_common_loader.*(.literal .text .literal.* .text.*)
+    *libhal.a:bootloader_flash.*(.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_esp32.*(.literal .text .literal.* .text.*)
+    *libhal.a:bootloader_utility.*(.literal .text .literal.* .text.*)
+    *libhal.a:bootloader_sha.*(.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: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_esp32.*(.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
+  .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/esp32c3/ld/bootloader.ld b/boot/espressif/port/esp32c3/ld/bootloader.ld
new file mode 100644
index 0000000..c627cb9
--- /dev/null
+++ b/boot/espressif/port/esp32c3/ld/bootloader.ld
@@ -0,0 +1,172 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/* Simplified memory map for the bootloader.
+ *
+ * The main purpose is to make sure the bootloader can load into main memory
+ * without overwriting itself.
+ */
+
+MEMORY
+{
+  iram_seg (RWX) :                  org = 0x403C8000, len = 0x8000
+  iram_loader_seg (RWX) :           org = 0x403D0000, len = 0x4800
+  dram_seg (RW) :                   org = 0x3FCD5000, len = 0x8C00
+}
+
+/*  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_esp32c3.*(.literal .text .literal.* .text.*)
+    *libhal.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*)
+    *libhal.a:bootloader_common_loader.*(.literal .text .literal.* .text.*)
+    *libhal.a:bootloader_flash.*(.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_esp32c3.*(.literal .text .literal.* .text.*)
+    *libhal.a:bootloader_utility.*(.literal .text .literal.* .text.*)
+    *libhal.a:bootloader_sha.*(.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: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_esp32xx.*(.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/esp32s2/ld/bootloader.ld b/boot/espressif/port/esp32s2/ld/bootloader.ld
new file mode 100644
index 0000000..3521894
--- /dev/null
+++ b/boot/espressif/port/esp32s2/ld/bootloader.ld
@@ -0,0 +1,172 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/* Simplified memory map for the bootloader.
+ *
+ * The main purpose is to make sure the bootloader can load into main memory
+ * without overwriting itself.
+ */
+
+MEMORY
+{
+  iram_seg (RWX) :                  org = 0x40048000, len = 0x8000
+  iram_loader_seg (RWX) :           org = 0x40050000, len = 0x5000
+  dram_seg (RW) :                   org = 0x3FFE5000, len = 0x8E00
+}
+
+/*  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_esp32s2.*(.literal .text .literal.* .text.*)
+    *libhal.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*)
+    *libhal.a:bootloader_common_loader.*(.literal .text .literal.* .text.*)
+    *libhal.a:bootloader_flash.*(.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_esp32s2.*(.literal .text .literal.* .text.*)
+    *libhal.a:bootloader_utility.*(.literal .text .literal.* .text.*)
+    *libhal.a:bootloader_sha.*(.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: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_esp32xx.*(.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/esp32s3/ld/bootloader.ld b/boot/espressif/port/esp32s3/ld/bootloader.ld
new file mode 100644
index 0000000..0bc9af6
--- /dev/null
+++ b/boot/espressif/port/esp32s3/ld/bootloader.ld
@@ -0,0 +1,172 @@
+/*
+ * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/* Simplified memory map for the bootloader.
+ *
+ * The main purpose is to make sure the bootloader can load into main memory
+ * without overwriting itself.
+ */
+
+MEMORY
+{
+  iram_seg (RWX) :                  org = 0x403B2500, len = 0x7B00
+  iram_loader_seg (RWX) :           org = 0x403BA000, len = 0x6000
+  dram_seg (RW) :                   org = 0x3FCD8000, len = 0x9A00
+}
+
+/*  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_esp32s3.*(.literal .text .literal.* .text.*)
+    *libhal.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*)
+    *libhal.a:bootloader_common_loader.*(.literal .text .literal.* .text.*)
+    *libhal.a:bootloader_flash.*(.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_esp32s3.*(.literal .text .literal.* .text.*)
+    *libhal.a:bootloader_utility.*(.literal .text .literal.* .text.*)
+    *libhal.a:bootloader_sha.*(.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: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_esp32xx.*(.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/esp_loader.c b/boot/espressif/port/esp_loader.c
new file mode 100644
index 0000000..1d3e55f
--- /dev/null
+++ b/boot/espressif/port/esp_loader.c
@@ -0,0 +1,91 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <string.h>
+
+#include <bootutil/bootutil_log.h>
+#include <bootutil/fault_injection_hardening.h>
+
+#include "bootloader_flash_priv.h"
+#include "esp_flash_encrypt.h"
+#include "soc/soc_memory_layout.h"
+
+#if CONFIG_IDF_TARGET_ESP32
+#include "esp32/rom/uart.h"
+#elif CONFIG_IDF_TARGET_ESP32S2
+#include "esp32s2/rom/uart.h"
+#elif CONFIG_IDF_TARGET_ESP32S3
+#include "esp32s3/rom/uart.h"
+#elif CONFIG_IDF_TARGET_ESP32C3
+#include "esp32c3/rom/uart.h"
+#endif
+
+#include "esp_mcuboot_image.h"
+#include "esp_loader.h"
+#include "flash_map_backend/flash_map_backend.h"
+
+
+static int load_segment(const struct flash_area *fap, uint32_t data_addr, uint32_t data_len, uint32_t load_addr)
+{
+    const uint32_t *data = (const uint32_t *)bootloader_mmap((fap->fa_off + data_addr), data_len);
+    if (!data) {
+        BOOT_LOG_ERR("%s: Bootloader mmap failed", __func__);
+        return -1;
+    }
+    memcpy((void *)load_addr, data, data_len);
+    bootloader_munmap(data);
+    return 0;
+}
+
+void esp_app_image_load(int slot, unsigned int hdr_offset)
+{
+    const struct flash_area *fap;
+    int area_id;
+    int rc;
+
+    area_id = flash_area_id_from_image_slot(slot);
+    rc = flash_area_open(area_id, &fap);
+    if (rc != 0) {
+        BOOT_LOG_ERR("%s: flash_area_open failed with %d", __func__, rc);
+    }
+
+    const uint32_t *data = (const uint32_t *)bootloader_mmap((fap->fa_off + hdr_offset), sizeof(esp_image_load_header_t));
+    esp_image_load_header_t load_header = {0};
+    memcpy((void *)&load_header, data, sizeof(esp_image_load_header_t));
+    bootloader_munmap(data);
+
+    if (load_header.header_magic != ESP_LOAD_HEADER_MAGIC) {
+        BOOT_LOG_ERR("Load header magic verification failed. Aborting");
+        FIH_PANIC;
+    }
+
+    if (!esp_ptr_in_iram((void *)load_header.iram_dest_addr) || !esp_ptr_in_iram((void *)(load_header.iram_dest_addr + load_header.iram_size))) {
+        BOOT_LOG_ERR("IRAM region in load header is not valid. Aborting");
+        FIH_PANIC;
+    }
+
+    if (!esp_ptr_in_dram((void *)load_header.dram_dest_addr) || !esp_ptr_in_dram((void *)load_header.dram_dest_addr + load_header.dram_size)) {
+        BOOT_LOG_ERR("DRAM region in load header is not valid. Aborting");
+        FIH_PANIC;
+    }
+
+    if (!esp_ptr_in_iram((void *)load_header.entry_addr)) {
+        BOOT_LOG_ERR("Application entry point (0x%x) is not in IRAM. Aborting", load_header.entry_addr);
+        FIH_PANIC;
+    }
+
+    BOOT_LOG_INF("DRAM segment: start=0x%x, size=0x%x, vaddr=0x%x", load_header.dram_flash_offset, load_header.dram_size, load_header.dram_dest_addr);
+    load_segment(fap, load_header.dram_flash_offset, load_header.dram_size, load_header.dram_dest_addr);
+
+    BOOT_LOG_INF("IRAM segment: start=0x%x, size=0x%x, vaddr=0x%x", load_header.iram_flash_offset, load_header.iram_size, load_header.iram_dest_addr);
+    load_segment(fap, load_header.iram_flash_offset, load_header.iram_size, load_header.iram_dest_addr);
+
+    BOOT_LOG_INF("start=0x%x", load_header.entry_addr);
+    uart_tx_wait_idle(0);
+    void *start = (void *) load_header.entry_addr;
+    ((void (*)(void))start)(); /* Call to application entry address should not return */
+    FIH_PANIC;
+}
diff --git a/boot/espressif/port/esp_mcuboot.c b/boot/espressif/port/esp_mcuboot.c
new file mode 100644
index 0000000..5cda2ae
--- /dev/null
+++ b/boot/espressif/port/esp_mcuboot.c
@@ -0,0 +1,316 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <bootutil/bootutil.h>
+#include <bootutil/bootutil_log.h>
+
+#include "sdkconfig.h"
+#include "esp_err.h"
+#include "bootloader_flash_priv.h"
+#include "esp_flash_encrypt.h"
+
+#include "flash_map_backend/flash_map_backend.h"
+#include "sysflash/sysflash.h"
+
+#ifndef ARRAY_SIZE
+#  define ARRAY_SIZE(arr)           (sizeof(arr) / sizeof((arr)[0]))
+#endif
+
+#ifndef MIN
+#  define MIN(a, b)                 (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef ALIGN_UP
+#  define ALIGN_UP(num, align)      (((num) + ((align) - 1)) & ~((align) - 1))
+#endif
+
+#ifndef ALIGN_DOWN
+#  define ALIGN_DOWN(num, align)    ((num) & ~((align) - 1))
+#endif
+
+#ifndef ALIGN_OFFSET
+#  define ALIGN_OFFSET(num, align)  ((num) & ((align) - 1))
+#endif
+
+#ifndef IS_ALIGNED
+#  define IS_ALIGNED(num, align)    (ALIGN_OFFSET((num), (align)) == 0)
+#endif
+
+#define FLASH_BUFFER_SIZE           256 /* SPI Flash block size */
+
+_Static_assert(IS_ALIGNED(FLASH_BUFFER_SIZE, 4), "Buffer size for SPI Flash operations must be 4-byte aligned.");
+
+#define BOOTLOADER_START_ADDRESS CONFIG_BOOTLOADER_OFFSET_IN_FLASH
+#define BOOTLOADER_SIZE CONFIG_ESP_BOOTLOADER_SIZE
+#define APPLICATION_PRIMARY_START_ADDRESS CONFIG_ESP_APPLICATION_PRIMARY_START_ADDRESS
+#define APPLICATION_SECONDARY_START_ADDRESS CONFIG_ESP_APPLICATION_SECONDARY_START_ADDRESS
+#define APPLICATION_SIZE CONFIG_ESP_APPLICATION_SIZE
+#define SCRATCH_OFFSET CONFIG_ESP_SCRATCH_OFFSET
+#define SCRATCH_SIZE CONFIG_ESP_SCRATCH_SIZE
+
+extern int ets_printf(const char *fmt, ...);
+
+static const struct flash_area bootloader = {
+    .fa_id = FLASH_AREA_BOOTLOADER,
+    .fa_device_id = FLASH_DEVICE_INTERNAL_FLASH,
+    .fa_off = BOOTLOADER_START_ADDRESS,
+    .fa_size = BOOTLOADER_SIZE,
+};
+
+static const struct flash_area primary_img0 = {
+    .fa_id = FLASH_AREA_IMAGE_PRIMARY(0),
+    .fa_device_id = FLASH_DEVICE_INTERNAL_FLASH,
+    .fa_off = APPLICATION_PRIMARY_START_ADDRESS,
+    .fa_size = APPLICATION_SIZE,
+};
+
+static const struct flash_area secondary_img0 = {
+    .fa_id = FLASH_AREA_IMAGE_SECONDARY(0),
+    .fa_device_id = FLASH_DEVICE_INTERNAL_FLASH,
+    .fa_off = APPLICATION_SECONDARY_START_ADDRESS,
+    .fa_size = APPLICATION_SIZE,
+};
+
+static const struct flash_area scratch_img0 = {
+    .fa_id = FLASH_AREA_IMAGE_SCRATCH,
+    .fa_device_id = FLASH_DEVICE_INTERNAL_FLASH,
+    .fa_off = SCRATCH_OFFSET,
+    .fa_size = SCRATCH_SIZE,
+};
+
+static const struct flash_area *s_flash_areas[] = {
+    &bootloader,
+    &primary_img0,
+    &secondary_img0,
+    &scratch_img0,
+};
+
+static const struct flash_area *prv_lookup_flash_area(uint8_t id) {
+    for (size_t i = 0; i < ARRAY_SIZE(s_flash_areas); i++) {
+        const struct flash_area *area = s_flash_areas[i];
+        if (id == area->fa_id) {
+            return area;
+        }
+    }
+    return NULL;
+}
+
+int flash_area_open(uint8_t id, const struct flash_area **area_outp)
+{
+    BOOT_LOG_DBG("%s: ID=%d", __func__, (int)id);
+    const struct flash_area *area = prv_lookup_flash_area(id);
+    *area_outp = area;
+    return area != NULL ? 0 : -1;
+}
+
+void flash_area_close(const struct flash_area *area)
+{
+
+}
+
+static bool aligned_flash_read(uintptr_t addr, void *dest, size_t size)
+{
+    if (IS_ALIGNED(addr, 4) && IS_ALIGNED((uintptr_t)dest, 4) && IS_ALIGNED(size, 4)) {
+        /* A single read operation is enough when when all parameters are aligned */
+
+        return bootloader_flash_read(addr, dest, size, true) == ESP_OK;
+    }
+
+    const uint32_t aligned_addr = ALIGN_DOWN(addr, 4);
+    const uint32_t addr_offset = ALIGN_OFFSET(addr, 4);
+    uint32_t bytes_remaining = size;
+    uint8_t read_data[FLASH_BUFFER_SIZE] = {0};
+
+    /* Align the read address to 4-byte boundary and ensure read size is a multiple of 4 bytes */
+
+    uint32_t bytes = MIN(bytes_remaining + addr_offset, sizeof(read_data));
+    if (bootloader_flash_read(aligned_addr, read_data, ALIGN_UP(bytes, 4), true) != ESP_OK) {
+        return false;
+    }
+
+    /* Skip non-useful data which may have been read for adjusting the alignment */
+
+    uint32_t bytes_read = bytes - addr_offset;
+    memcpy(dest, &read_data[addr_offset], bytes_read);
+
+    bytes_remaining -= bytes_read;
+
+    /* Read remaining data from Flash in case requested size is greater than buffer size */
+
+    uint32_t offset = bytes;
+
+    while (bytes_remaining != 0) {
+        bytes = MIN(bytes_remaining, sizeof(read_data));
+        if (bootloader_flash_read(aligned_addr + offset, read_data, ALIGN_UP(bytes, 4), true) != ESP_OK) {
+            return false;
+        }
+
+        memcpy(&((uint8_t *)dest)[bytes_read], read_data, bytes);
+
+        offset += bytes;
+        bytes_read += bytes;
+        bytes_remaining -= bytes;
+    }
+
+    return true;
+}
+
+int flash_area_read(const struct flash_area *fa, uint32_t off, void *dst,
+                    uint32_t len)
+{
+    if (fa->fa_device_id != FLASH_DEVICE_INTERNAL_FLASH) {
+        return -1;
+    }
+
+    const uint32_t end_offset = off + len;
+    if (end_offset > fa->fa_size) {
+        BOOT_LOG_ERR("%s: Out of Bounds (0x%x vs 0x%x)", __func__, end_offset, fa->fa_size);
+        return -1;
+    }
+
+    bool success = aligned_flash_read(fa->fa_off + off, dst, len);
+    if (!success) {
+        BOOT_LOG_ERR("%s: Flash read failed", __func__);
+
+        return -1;
+    }
+
+    return 0;
+}
+
+int flash_area_write(const struct flash_area *fa, uint32_t off, const void *src,
+                     uint32_t len)
+{
+    if (fa->fa_device_id != FLASH_DEVICE_INTERNAL_FLASH) {
+        return -1;
+    }
+
+    const uint32_t end_offset = off + len;
+    if (end_offset > fa->fa_size) {
+        BOOT_LOG_ERR("%s: Out of Bounds (0x%x vs 0x%x)", __func__, end_offset, fa->fa_size);
+        return -1;
+    }
+
+    bool flash_encryption_enabled = esp_flash_encryption_enabled();
+
+    const uint32_t start_addr = fa->fa_off + off;
+    BOOT_LOG_DBG("%s: Addr: 0x%08x Length: %d", __func__, (int)start_addr, (int)len);
+
+    if (bootloader_flash_write(start_addr, (void *)src, len, flash_encryption_enabled) != ESP_OK) {
+        BOOT_LOG_ERR("%s: Flash write failed", __func__);
+        return -1;
+    }
+
+    return 0;
+}
+
+int flash_area_erase(const struct flash_area *fa, uint32_t off, uint32_t len)
+{
+    if (fa->fa_device_id != FLASH_DEVICE_INTERNAL_FLASH) {
+        return -1;
+    }
+
+    if ((len % FLASH_SECTOR_SIZE) != 0 || (off % FLASH_SECTOR_SIZE) != 0) {
+        BOOT_LOG_ERR("%s: Not aligned on sector Offset: 0x%x Length: 0x%x",
+                     __func__, (int)off, (int)len);
+        return -1;
+    }
+
+    const uint32_t start_addr = fa->fa_off + off;
+    BOOT_LOG_DBG("%s: Addr: 0x%08x Length: %d", __func__, (int)start_addr, (int)len);
+
+    if (bootloader_flash_erase_range(start_addr, len) != ESP_OK) {
+        BOOT_LOG_ERR("%s: Flash erase failed", __func__);
+        return -1;
+    }
+#if VALIDATE_PROGRAM_OP
+    for (size_t i = 0; i < len; i++) {
+        uint8_t *val = (void *)(start_addr + i);
+        if (*val != 0xff) {
+            BOOT_LOG_ERR("%s: Erase at 0x%x Failed", __func__, (int)val);
+            assert(0);
+        }
+    }
+#endif
+
+    return 0;
+}
+
+uint32_t flash_area_align(const struct flash_area *area)
+{
+    static size_t align = 0;
+
+    if (align == 0) {
+        bool flash_encryption_enabled = esp_flash_encryption_enabled();
+
+        if (flash_encryption_enabled) {
+            align = 32;
+        } else {
+            align = 4;
+        }
+    }
+    return align;
+}
+
+uint8_t flash_area_erased_val(const struct flash_area *area)
+{
+    return 0xff;
+}
+
+int flash_area_get_sectors(int fa_id, uint32_t *count,
+                           struct flash_sector *sectors)
+{
+    const struct flash_area *fa = prv_lookup_flash_area(fa_id);
+    if (fa->fa_device_id != FLASH_DEVICE_INTERNAL_FLASH) {
+        return -1;
+    }
+
+    const size_t sector_size = FLASH_SECTOR_SIZE;
+    uint32_t total_count = 0;
+    for (size_t off = 0; off < fa->fa_size; off += sector_size) {
+        // Note: Offset here is relative to flash area, not device
+        sectors[total_count].fs_off = off;
+        sectors[total_count].fs_size = sector_size;
+        total_count++;
+    }
+
+    *count = total_count;
+    return 0;
+}
+
+int flash_area_id_from_multi_image_slot(int image_index, int slot)
+{
+    BOOT_LOG_DBG("%s", __func__);
+    switch (slot) {
+      case 0:
+        return FLASH_AREA_IMAGE_PRIMARY(image_index);
+      case 1:
+        return FLASH_AREA_IMAGE_SECONDARY(image_index);
+    }
+
+    BOOT_LOG_ERR("Unexpected Request: image_index=%d, slot=%d", image_index, slot);
+    return -1; /* flash_area_open will fail on that */
+}
+
+int flash_area_id_from_image_slot(int slot)
+{
+    return flash_area_id_from_multi_image_slot(0, slot);
+}
+
+int flash_area_to_sectors(int idx, int *cnt, struct flash_area *fa)
+{
+    return -1;
+}
+
+void mcuboot_assert_handler(const char *file, int line, const char *func)
+{
+    ets_printf("assertion failed: file \"%s\", line %d, func: %s\n", file, line, func);
+    abort();
+}
diff --git a/boot/espressif/secureboot-sign-ec256.conf b/boot/espressif/secureboot-sign-ec256.conf
new file mode 100644
index 0000000..98894fa
--- /dev/null
+++ b/boot/espressif/secureboot-sign-ec256.conf
@@ -0,0 +1,27 @@
+# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+#
+# SPDX-License-Identifier: Apache-2.0
+
+# ATTENTION:
+# This configuration file targets the building for CI environment and contains
+# a set of definitions to resemble a bootloader image for RELEASE environment.
+# Running the generated firmware image may result in irreversible operations
+# to the chip!
+
+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
+CONFIG_SECURE_FLASH_ENC_ENABLED=1
+CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE=1
+CONFIG_ESP_SIGN_KEY_FILE=root-ec-p256.pem
+CONFIG_ESP_USE_TINYCRYPT=1
+CONFIG_ESP_SIGN_EC256=1
+CONFIG_ESP_BOOTLOADER_SIZE=0xF000
+CONFIG_ESP_APPLICATION_PRIMARY_START_ADDRESS=0x10000
+CONFIG_ESP_APPLICATION_SIZE=0x100000
+CONFIG_ESP_APPLICATION_SECONDARY_START_ADDRESS=0x110000
+CONFIG_ESP_MCUBOOT_WDT_ENABLE=1
+CONFIG_ESP_SCRATCH_OFFSET=0x210000
+CONFIG_ESP_SCRATCH_SIZE=0x40000
diff --git a/boot/espressif/secureboot-sign-ed25519.conf b/boot/espressif/secureboot-sign-ed25519.conf
new file mode 100644
index 0000000..67e6dcd
--- /dev/null
+++ b/boot/espressif/secureboot-sign-ed25519.conf
@@ -0,0 +1,27 @@
+# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+#
+# SPDX-License-Identifier: Apache-2.0
+
+# ATTENTION:
+# This configuration file targets the building for CI environment and contains
+# a set of definitions to resemble a bootloader image for RELEASE environment.
+# Running the generated firmware image may result in irreversible operations
+# to the chip!
+
+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
+CONFIG_SECURE_FLASH_ENC_ENABLED=1
+CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE=1
+CONFIG_ESP_SIGN_KEY_FILE=root-ed25519.pem
+CONFIG_ESP_USE_TINYCRYPT=1
+CONFIG_ESP_SIGN_ED25519=1
+CONFIG_ESP_BOOTLOADER_SIZE=0xF000
+CONFIG_ESP_APPLICATION_PRIMARY_START_ADDRESS=0x10000
+CONFIG_ESP_APPLICATION_SIZE=0x100000
+CONFIG_ESP_APPLICATION_SECONDARY_START_ADDRESS=0x110000
+CONFIG_ESP_MCUBOOT_WDT_ENABLE=1
+CONFIG_ESP_SCRATCH_OFFSET=0x210000
+CONFIG_ESP_SCRATCH_SIZE=0x40000
diff --git a/boot/espressif/secureboot-sign-rsa2048.conf b/boot/espressif/secureboot-sign-rsa2048.conf
new file mode 100644
index 0000000..e5888f7
--- /dev/null
+++ b/boot/espressif/secureboot-sign-rsa2048.conf
@@ -0,0 +1,28 @@
+# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+#
+# SPDX-License-Identifier: Apache-2.0
+
+# ATTENTION:
+# This configuration file targets the building for CI environment and contains
+# a set of definitions to resemble a bootloader image for RELEASE environment.
+# Running the generated firmware image may result in irreversible operations
+# to the chip!
+
+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
+CONFIG_SECURE_FLASH_ENC_ENABLED=1
+CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE=1
+CONFIG_ESP_SIGN_KEY_FILE=root-rsa-2048.pem
+CONFIG_ESP_USE_MBEDTLS=1
+CONFIG_ESP_SIGN_RSA=1
+CONFIG_ESP_SIGN_RSA_LEN=2048
+CONFIG_ESP_BOOTLOADER_SIZE=0xF000
+CONFIG_ESP_APPLICATION_PRIMARY_START_ADDRESS=0x10000
+CONFIG_ESP_APPLICATION_SIZE=0x100000
+CONFIG_ESP_APPLICATION_SECONDARY_START_ADDRESS=0x110000
+CONFIG_ESP_MCUBOOT_WDT_ENABLE=1
+CONFIG_ESP_SCRATCH_OFFSET=0x210000
+CONFIG_ESP_SCRATCH_SIZE=0x40000
diff --git a/boot/espressif/secureboot-sign-rsa3072.conf b/boot/espressif/secureboot-sign-rsa3072.conf
new file mode 100644
index 0000000..66825e0
--- /dev/null
+++ b/boot/espressif/secureboot-sign-rsa3072.conf
@@ -0,0 +1,28 @@
+# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+#
+# SPDX-License-Identifier: Apache-2.0
+
+# ATTENTION:
+# This configuration file targets the building for CI environment and contains
+# a set of definitions to resemble a bootloader image for RELEASE environment.
+# Running the generated firmware image may result in irreversible operations
+# to the chip!
+
+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
+CONFIG_SECURE_FLASH_ENC_ENABLED=1
+CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE=1
+CONFIG_ESP_SIGN_KEY_FILE=root-rsa-3072.pem
+CONFIG_ESP_USE_MBEDTLS=1
+CONFIG_ESP_SIGN_RSA=1
+CONFIG_ESP_SIGN_RSA_LEN=3072
+CONFIG_ESP_BOOTLOADER_SIZE=0xF000
+CONFIG_ESP_APPLICATION_PRIMARY_START_ADDRESS=0x10000
+CONFIG_ESP_APPLICATION_SIZE=0x100000
+CONFIG_ESP_APPLICATION_SECONDARY_START_ADDRESS=0x110000
+CONFIG_ESP_MCUBOOT_WDT_ENABLE=1
+CONFIG_ESP_SCRATCH_OFFSET=0x210000
+CONFIG_ESP_SCRATCH_SIZE=0x40000
diff --git a/boot/espressif/tools/toolchain-esp32s3.cmake b/boot/espressif/tools/toolchain-esp32s3.cmake
new file mode 100644
index 0000000..43bb918
--- /dev/null
+++ b/boot/espressif/tools/toolchain-esp32s3.cmake
@@ -0,0 +1,14 @@
+# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+#
+# SPDX-License-Identifier: Apache-2.0
+
+set(CMAKE_SYSTEM_NAME Generic)
+
+set(CMAKE_C_COMPILER xtensa-esp32s3-elf-gcc)
+set(CMAKE_CXX_COMPILER xtensa-esp32s3-elf-g++)
+set(CMAKE_ASM_COMPILER xtensa-esp32s3-elf-gcc)
+
+set(CMAKE_C_FLAGS "-mlongcalls" CACHE STRING "C Compiler Base Flags")
+set(CMAKE_CXX_FLAGS "-mlongcalls" CACHE STRING "C++ Compiler Base Flags")
+
+set(CMAKE_EXE_LINKER_FLAGS "-Wl,--gc-sections" CACHE STRING "Linker Base Flags")