espressif:esp32: Add multi image support

Changes on configuration and flash area organization for supporting
multi image and implementation for booting on different processors
on esp32

Signed-off-by: Almir Okato <almir.okato@espressif.com>
diff --git a/boot/espressif/main.c b/boot/espressif/main.c
index 083efc5..6fe93a2 100644
--- a/boot/espressif/main.c
+++ b/boot/espressif/main.c
@@ -22,22 +22,75 @@
 #ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
 #include "esp_flash_encrypt.h"
 #endif
+#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
+#include "app_cpu_start.h"
+#endif
 
 #include "esp_loader.h"
 #include "os/os_malloc.h"
 
+#define IMAGE_INDEX_0   0
+#define IMAGE_INDEX_1   1
+
+#define PRIMARY_SLOT    0
+#define SECONDARY_SLOT  1
+
 #ifdef CONFIG_SECURE_BOOT
 extern esp_err_t check_and_generate_secure_boot_keys(void);
 #endif
 
 void do_boot(struct boot_rsp *rsp)
 {
+    unsigned int entry_addr;
     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 slot = (rsp->br_image_off == CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS) ? PRIMARY_SLOT : SECONDARY_SLOT;
+    esp_app_image_load(IMAGE_INDEX_0, slot, rsp->br_hdr->ih_hdr_size, &entry_addr);
+    ((void (*)(void))entry_addr)(); /* Call to application entry address should not return */
+    FIH_PANIC; /* It should not get here */
 }
 
+#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
+int read_image_header(uint32_t img_index, uint32_t slot, struct image_header *img_header)
+{
+    const struct flash_area *fap;
+    int area_id;
+    int rc = 0;
+
+    area_id = flash_area_id_from_multi_image_slot(img_index, slot);
+    rc = flash_area_open(area_id, &fap);
+    if (rc != 0) {
+        rc = BOOT_EFLASH;
+        goto done;
+    }
+
+    if (flash_area_read(fap, 0, img_header, sizeof(struct image_header))) {
+        rc = BOOT_EFLASH;
+        goto done;
+    }
+
+    BOOT_LOG_INF("Image offset = 0x%x", fap->fa_off);
+    BOOT_LOG_INF("Image header size = 0x%x", img_header->ih_hdr_size);
+
+done:
+    flash_area_close(fap);
+    return rc;
+}
+
+void do_boot_appcpu(uint32_t img_index, uint32_t slot)
+{
+    unsigned int entry_addr;
+    struct image_header img_header;
+
+    if (read_image_header(img_index, slot, &img_header) != 0) {
+        FIH_PANIC;
+    }
+
+    esp_app_image_load(img_index, slot, img_header.ih_hdr_size, &entry_addr);
+    appcpu_start(entry_addr);
+}
+#endif
+
 int main()
 {
     bootloader_init();
@@ -97,8 +150,10 @@
      *   2) MCUboot validates the application images and prepares the booting process.
      */
 
+    /* MCUboot's boot_go validates and checks all images for update and returns
+     * the load information for booting the main image
+     */
     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
@@ -165,6 +220,13 @@
     BOOT_LOG_INF("Disabling RNG early entropy source...");
     bootloader_random_disable();
 
+#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
+    /* Multi image independent boot
+     * Boot on the second processor happens before the image0 boot
+     */
+    do_boot_appcpu(IMAGE_INDEX_1, PRIMARY_SLOT);
+#endif
+
     do_boot(&rsp);
 
     while(1);