boot: zephyr: add config for swap without scratch

Add Zephyr option to enable building a bootloader that uses an
alternative swap algorithm, that first moves up all sectors in slot1 and
then directly swaps between slot0 and slot1.

Signed-off-by: Fabio Utzig <utzig@apache.org>
diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt
index f559844..5f21aea 100644
--- a/boot/zephyr/CMakeLists.txt
+++ b/boot/zephyr/CMakeLists.txt
@@ -92,6 +92,9 @@
 zephyr_library_include_directories(${BOOT_DIR}/bootutil/include)
 zephyr_library_sources(
   ${BOOT_DIR}/bootutil/src/loader.c
+  ${BOOT_DIR}/bootutil/src/swap_misc.c
+  ${BOOT_DIR}/bootutil/src/swap_scratch.c
+  ${BOOT_DIR}/bootutil/src/swap_move.c
   ${BOOT_DIR}/bootutil/src/bootutil_misc.c
   ${BOOT_DIR}/bootutil/src/image_validate.c
   ${BOOT_DIR}/bootutil/src/encrypted.c
diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig
index 56b5b19..f93f7f9 100644
--- a/boot/zephyr/Kconfig
+++ b/boot/zephyr/Kconfig
@@ -126,6 +126,19 @@
 	  of swapping them. This prevents the fallback recovery, but
 	  uses a much simpler code path.
 
+config BOOT_SWAP_USING_MOVE
+	bool "Swap mode that can run without a scratch partition [EXPERIMENTAL]"
+	default n
+	help
+	  If y, the swap upgrade is done in two steps, where first every
+	  sector of the primary slot is moved up one sector, then for
+	  each sector X in the secondary slot, it is moved to index X in
+	  the primary slot, then the sector at X+1 in the primary is
+	  moved to index X in the secondary.
+	  This allows a swap upgrade without using a scratch partition,
+	  but is currently limited to all sectors in both slots being of
+	  the same size.
+
 config BOOT_BOOTSTRAP
 	bool "Bootstrap erased the primary slot from the secondary slot"
 	default n
diff --git a/boot/zephyr/flash_map_extended.c b/boot/zephyr/flash_map_extended.c
index 47da3b7..c50a1e9 100644
--- a/boot/zephyr/flash_map_extended.c
+++ b/boot/zephyr/flash_map_extended.c
@@ -58,7 +58,9 @@
     switch (slot) {
     case 0: return FLASH_AREA_IMAGE_PRIMARY(image_index);
     case 1: return FLASH_AREA_IMAGE_SECONDARY(image_index);
+#if !defined(CONFIG_BOOT_SWAP_USING_MOVE)
     case 2: return FLASH_AREA_IMAGE_SCRATCH;
+#endif
     }
 
     return -EINVAL; /* flash_area_open will fail on that */
diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h
index f517b7e..4fff4b1 100644
--- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h
+++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h
@@ -53,6 +53,10 @@
 #define MCUBOOT_OVERWRITE_ONLY_FAST
 #endif
 
+#ifdef CONFIG_BOOT_SWAP_USING_MOVE
+#define MCUBOOT_SWAP_USING_MOVE 1
+#endif
+
 #ifdef CONFIG_LOG
 #define MCUBOOT_HAVE_LOGGING 1
 #endif
diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h
index c422efd..25487ee 100644
--- a/boot/zephyr/include/sysflash/sysflash.h
+++ b/boot/zephyr/include/sysflash/sysflash.h
@@ -37,6 +37,8 @@
 #error "Image slot and flash area mapping is not defined"
 #endif
 
+#if !defined(CONFIG_BOOT_SWAP_USING_MOVE)
 #define FLASH_AREA_IMAGE_SCRATCH    DT_FLASH_AREA_IMAGE_SCRATCH_ID
+#endif
 
 #endif /* __SYSFLASH_H__ */
diff --git a/boot/zephyr/include/target.h b/boot/zephyr/include/target.h
index 99f6361..f156c32 100644
--- a/boot/zephyr/include/target.h
+++ b/boot/zephyr/include/target.h
@@ -35,8 +35,8 @@
     !defined(FLASH_AREA_IMAGE_0_SIZE) || \
     !defined(FLASH_AREA_IMAGE_1_OFFSET) || \
     !defined(FLASH_AREA_IMAGE_1_SIZE) || \
-    !defined(FLASH_AREA_IMAGE_SCRATCH_OFFSET) || \
-    !defined(FLASH_AREA_IMAGE_SCRATCH_SIZE)
+    (!defined(CONFIG_BOOT_SWAP_USING_MOVE) && !defined(FLASH_AREA_IMAGE_SCRATCH_OFFSET)) || \
+    (!defined(CONFIG_BOOT_SWAP_USING_MOVE) && !defined(FLASH_AREA_IMAGE_SCRATCH_SIZE))
 #error "Target support is incomplete; cannot build mcuboot."
 #endif
 
diff --git a/boot/zephyr/prj.conf b/boot/zephyr/prj.conf
index 89e55f5..30af1e4 100644
--- a/boot/zephyr/prj.conf
+++ b/boot/zephyr/prj.conf
@@ -9,6 +9,8 @@
 CONFIG_BOOT_ENCRYPT_RSA=n
 CONFIG_BOOT_ENCRYPT_EC256=n
 
+CONFIG_BOOT_UPGRADE_ONLY=n
+CONFIG_BOOT_SWAP_USING_MOVE=n
 CONFIG_BOOT_BOOTSTRAP=n
 
 ### Default to RSA