boot/espressif: Add hal subdirectory for IDF sources and headers

Signed-off-by: Shubham Kulkarni <shubham.kulkarni@espressif.com>
diff --git a/.gitmodules b/.gitmodules
index adcdcb8..ed78f3c 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -22,3 +22,7 @@
 [submodule "ext/cddl-gen"]
 	path = ext/cddl-gen
 	url = https://github.com/NordicSemiconductor/cddl-gen.git
+[submodule "boot/espressif/hal/esp-idf"]
+	path = boot/espressif/hal/esp-idf
+	url = https://github.com/espressif/esp-idf.git
+	branch = release/v4.3
diff --git a/boot/espressif/CMakeLists.txt b/boot/espressif/CMakeLists.txt
index 8094031..de2b3cf 100644
--- a/boot/espressif/CMakeLists.txt
+++ b/boot/espressif/CMakeLists.txt
@@ -6,11 +6,15 @@
 
 project(mcuboot_${MCUBOOT_TARGET})
 
+add_definitions(-DMCUBOOT_TARGET=${MCUBOOT_TARGET})
+
 if (NOT DEFINED IDF_PATH)
-    if (DEFINED ENV{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 set IDF_PATH environment variable or pass -DIDF_PATH flag.")
+        message(FATAL_ERROR "IDF_PATH not found. Please update submodules or set IDF_PATH environment variable or pass -DIDF_PATH flag.")
     endif()
 endif()
 
@@ -123,6 +127,7 @@
     "-lc"
     )
 
+add_subdirectory(hal)
 add_executable(
     ${APP_EXECUTABLE}
     ${CMAKE_CURRENT_LIST_DIR}/main.c
@@ -156,3 +161,9 @@
     -T${CMAKE_CURRENT_LIST_DIR}/port/${MCUBOOT_TARGET}/ld/bootloader.ld
     ${LDFLAGS}
     )
+
+target_link_libraries(
+    ${APP_EXECUTABLE}
+    PUBLIC
+    hal
+    )
diff --git a/boot/espressif/hal/CMakeLists.txt b/boot/espressif/hal/CMakeLists.txt
new file mode 100644
index 0000000..96adc30
--- /dev/null
+++ b/boot/espressif/hal/CMakeLists.txt
@@ -0,0 +1,128 @@
+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/esp_common/include
+    ${esp_idf_dir}/components/esp_rom/include
+    ${esp_idf_dir}/components/xtensa/${MCUBOOT_TARGET}/include
+    ${esp_idf_dir}/components/spi_flash/include
+    ${esp_idf_dir}/components/spi_flash/private_include
+    ${esp_idf_dir}/components/xtensa/include
+    ${esp_idf_dir}/components/soc/${MCUBOOT_TARGET}/include
+    ${esp_idf_dir}/components/${MCUBOOT_TARGET}/include
+    ${esp_idf_dir}/components/soc/include
+    ${esp_idf_dir}/components/esp_hw_support/include
+    ${esp_idf_dir}/components/hal/${MCUBOOT_TARGET}/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/bootloader_support/include
+    ${esp_idf_dir}/components/bootloader_support/include_bootloader
+    ${esp_idf_dir}/components/hal/include
+    ${esp_idf_dir}/components/efuse/include
+    ${esp_idf_dir}/components/efuse/${MCUBOOT_TARGET}/include
+    )
+set(hal_srcs
+    ${SRC_DIR}/bootloader_init.c
+    ${SRC_DIR}/bootloader_wdt.c
+    ${esp_idf_dir}/components/hal/mpu_hal.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/spi_flash/${MCUBOOT_TARGET}/spi_flash_rom_patch.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/${MCUBOOT_TARGET}/clk.c
+    )
+
+set(CFLAGS
+    "-nostdlib"
+    "-mlongcalls"
+    "-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
+    "-mlongcalls"
+    "-Wno-frame-address"
+    "-Wl,--cref"
+    "-Wl,--Map=${APP_NAME}.map"
+    "-fno-rtti"
+    "-fno-lto"
+    "-Wl,--gc-sections"
+    "-Wl,--undefined=uxTopUsedPriority"
+    "-lm"
+    "-lgcc"
+    "-lgcov"
+    "-lstdc++"
+    "-lc"
+    )
+
+add_library(hal STATIC ${hal_srcs} ${INCLUDE_DIRS})
+
+set_source_files_properties(
+    ${esp_idf_dir}/components/bootloader_support/src/bootloader_flash.c
+    ${esp_idf_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/rtc_clk_init.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_time.c
+    PROPERTIES COMPILE_FLAGS
+    "-Wno-unused-variable")
+
+target_include_directories(
+    hal
+    PUBLIC
+    ${INCLUDE_DIRS}
+    )
+
+target_compile_options(
+    hal
+    PUBLIC
+    ${CFLAGS}
+    )
+
+target_link_libraries(
+    hal
+    PUBLIC
+    ${LDFLAGS}
+    -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/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.peripherals.ld
+    -T${esp_idf_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.newlib-funcs.ld
+    )
diff --git a/boot/espressif/hal/esp-idf b/boot/espressif/hal/esp-idf
new file mode 160000
index 0000000..c9646ff
--- /dev/null
+++ b/boot/espressif/hal/esp-idf
@@ -0,0 +1 @@
+Subproject commit c9646ff0beffc86d2c6d1bfbad34da16e328e0e3
diff --git a/boot/espressif/hal/include/bootloader_wdt.h b/boot/espressif/hal/include/bootloader_wdt.h
new file mode 100644
index 0000000..e5ac551
--- /dev/null
+++ b/boot/espressif/hal/include/bootloader_wdt.h
@@ -0,0 +1,8 @@
+/*
+ * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#pragma once
+
+void bootloader_wdt_feed(void);
diff --git a/boot/espressif/hal/include/esp32/sdkconfig.h b/boot/espressif/hal/include/esp32/sdkconfig.h
new file mode 100644
index 0000000..547d2ae
--- /dev/null
+++ b/boot/espressif/hal/include/esp32/sdkconfig.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#define BOOTLOADER_BUILD 1
+#define CONFIG_IDF_TARGET_ESP32 1
+#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
diff --git a/boot/espressif/hal/include/esp_log.h b/boot/espressif/hal/include/esp_log.h
new file mode 100644
index 0000000..a55640e
--- /dev/null
+++ b/boot/espressif/hal/include/esp_log.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+#include <mcuboot_config/mcuboot_logging.h>
+
+#define ESP_LOGE(tag, fmt, ...) MCUBOOT_LOG_ERR(fmt, ##__VA_ARGS__)
+#define ESP_LOGW(tag, fmt, ...) MCUBOOT_LOG_WRN(fmt, ##__VA_ARGS__)
+#define ESP_LOGI(tag, fmt, ...) MCUBOOT_LOG_INF(fmt, ##__VA_ARGS__)
+#define ESP_LOGD(tag, fmt, ...) MCUBOOT_LOG_DBG(fmt, ##__VA_ARGS__)
diff --git a/boot/espressif/hal/include/mcuboot_config/mcuboot_assert.h b/boot/espressif/hal/include/mcuboot_config/mcuboot_assert.h
new file mode 100644
index 0000000..aaad1a3
--- /dev/null
+++ b/boot/espressif/hal/include/mcuboot_config/mcuboot_assert.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+extern void mcuboot_assert_handler(const char *file, int line, const char *func);
+#define assert(arg)                                                 \
+    do {                                                            \
+        if (!(arg)) {                                               \
+            mcuboot_assert_handler(__FILE__, __LINE__, __func__);   \
+        }                                                           \
+    } while(0)
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..ab5f4c5
--- /dev/null
+++ b/boot/espressif/hal/include/mcuboot_config/mcuboot_config.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __MCUBOOT_CONFIG_H__
+#define __MCUBOOT_CONFIG_H__
+
+/*
+ * Template configuration file for MCUboot.
+ *
+ * When porting MCUboot to a new target, copy it somewhere that your
+ * include path can find it as mcuboot_config/mcuboot_config.h, and
+ * make adjustments to suit your platform.
+ *
+ * For examples, see:
+ *
+ * boot/zephyr/include/mcuboot_config/mcuboot_config.h
+ * boot/mynewt/mcuboot_config/include/mcuboot_config/mcuboot_config.h
+ */
+
+/*
+ * Signature types
+ *
+ * You must choose exactly one signature type.
+ */
+
+/* Uncomment for RSA signature support */
+/* #define MCUBOOT_SIGN_RSA */
+
+/* Uncomment for ECDSA signatures using curve P-256. */
+/* #define MCUBOOT_SIGN_EC256 */
+
+
+/*
+ * 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 mbedTLS and Tinycrypt as source of
+ * cryptographic primitives. Other cryptographic settings are also
+ * available.
+ */
+
+/* Uncomment to use ARM's mbedTLS cryptographic primitives */
+#define MCUBOOT_USE_MBED_TLS
+/* Uncomment to use Tinycrypt's. */
+/* #define MCUBOOT_USE_TINYCRYPT */
+
+/*
+ * 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
+
+/*
+ * 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..1968cec
--- /dev/null
+++ b/boot/espressif/hal/include/mcuboot_config/mcuboot_logging.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+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 (MCUBOOT_TARGET == esp32)
+#define TARGET "[esp32]"
+#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..8210e7a
--- /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(fmt, ##__VA_ARGS__)
+#define SOC_LOGW(tag, fmt, ...) MCUBOOT_LOG_WRN(fmt, ##__VA_ARGS__)
+#define SOC_LOGI(tag, fmt, ...) MCUBOOT_LOG_INF(fmt, ##__VA_ARGS__)
+#define SOC_LOGD(tag, fmt, ...) MCUBOOT_LOG_DBG(fmt, ##__VA_ARGS__)
diff --git a/boot/espressif/hal/src/bootloader_init.c b/boot/espressif/hal/src/bootloader_init.c
new file mode 100644
index 0000000..8ffe15c
--- /dev/null
+++ b/boot/espressif/hal/src/bootloader_init.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 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/ets_sys.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/bootloader_wdt.c b/boot/espressif/hal/src/bootloader_wdt.c
new file mode 100644
index 0000000..64cbaea
--- /dev/null
+++ b/boot/espressif/hal/src/bootloader_wdt.c
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <bootloader_wdt.h>
+#include <hal/wdt_hal.h>
+
+void bootloader_wdt_feed(void)
+{
+    wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL};
+    wdt_hal_write_protect_disable(&rtc_wdt_ctx);
+    wdt_hal_feed(&rtc_wdt_ctx);
+    wdt_hal_write_protect_enable(&rtc_wdt_ctx);
+}