boot: Introduce direct execute-in-place (XIP) mode

This patch introduces the direct execute-in-place (XIP) mode in addition
to the other upgrade modes (swap strategies, overwrite-only). When
direct-XIP is enabled with the MCUBOOT_DIRECT_XIP option, mcuboot
selects the newest valid image based on the image version numbers from
the image header, thereafter the selected image runs directly from its
flash partition (slot) instead of moving it. Therefore the images must
be linked to be executed from the given image slot. It means that in
direct-XIP mode either of the primary and the secondary slots can hold
the active image.

This patch is based on the NO_SWAP upgrade strategy which was first
introduced in the Trusted Firmware-M project.
Source TF-M version: TF-Mv1.0.

Change-Id: If584cf01ae5aa7208845f6a6fa206f0595e0e61e
Signed-off-by: David Vincze <david.vincze@linaro.org>
diff --git a/boot/bootutil/src/bootutil_priv.h b/boot/bootutil/src/bootutil_priv.h
index cd33f76..171b409 100644
--- a/boot/bootutil/src/bootutil_priv.h
+++ b/boot/bootutil/src/bootutil_priv.h
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2017-2020 Linaro LTD
  * Copyright (c) 2017-2019 JUUL Labs
- * Copyright (c) 2019 Arm Limited
+ * Copyright (c) 2019-2020 Arm Limited
  *
  * Original license:
  *
@@ -66,11 +66,15 @@
 /** Number of image slots in flash; currently limited to two. */
 #define BOOT_NUM_SLOTS                  2
 
-#if defined(MCUBOOT_OVERWRITE_ONLY) && defined(MCUBOOT_SWAP_USING_MOVE)
-#error "Please enable only one of MCUBOOT_OVERWRITE_ONLY or MCUBOOT_SWAP_USING_MOVE"
+#if (defined(MCUBOOT_OVERWRITE_ONLY) + \
+     defined(MCUBOOT_SWAP_USING_MOVE) + \
+     defined(MCUBOOT_DIRECT_XIP)) > 1
+#error "Please enable only one of MCUBOOT_OVERWRITE_ONLY, MCUBOOT_SWAP_USING_MOVE or MCUBOOT_DIRECT_XIP"
 #endif
 
-#if !defined(MCUBOOT_OVERWRITE_ONLY) && !defined(MCUBOOT_SWAP_USING_MOVE)
+#if !defined(MCUBOOT_OVERWRITE_ONLY) && \
+    !defined(MCUBOOT_SWAP_USING_MOVE) && \
+    !defined(MCUBOOT_DIRECT_XIP)
 #define MCUBOOT_SWAP_USING_SCRATCH 1
 #endif
 
@@ -166,6 +170,19 @@
 
 _Static_assert(BOOT_IMAGE_NUMBER > 0, "Invalid value for BOOT_IMAGE_NUMBER");
 
+#if !defined(MCUBOOT_DIRECT_XIP)
+#define IS_IN_XIP_MODE()    0
+#else
+#define IS_IN_XIP_MODE()    1
+
+#if (BOOT_IMAGE_NUMBER != 1)
+#error "The MCUBOOT_DIRECT_XIP mode only supports single-image boot (MCUBOOT_IMAGE_NUMBER=1)."
+#endif
+#ifdef MCUBOOT_ENC_IMAGES
+#error "Image encryption (MCUBOOT_ENC_IMAGES) is not supported when MCUBOOT_DIRECT_XIP mode is selected."
+#endif
+#endif /* MCUBOOT_DIRECT_XIP */
+
 #define BOOT_MAX_IMG_SECTORS       MCUBOOT_MAX_IMG_SECTORS
 
 /*
@@ -183,6 +200,14 @@
                                                                 | (type);      \
                                                     }
 
+#define BOOT_LOG_IMAGE_INFO(slot, hdr)                                    \
+    BOOT_LOG_INF("%-9s slot: version=%u.%u.%u+%u",                        \
+                 ((slot) == BOOT_PRIMARY_SLOT) ? "Primary" : "Secondary", \
+                 (hdr)->ih_ver.iv_major,                                  \
+                 (hdr)->ih_ver.iv_minor,                                  \
+                 (hdr)->ih_ver.iv_revision,                               \
+                 (hdr)->ih_ver.iv_build_num)
+
 /*
  * The current flashmap API does not check the amount of space allocated when
  * loading sector data from the flash device, allowing for smaller counts here