Add support for slots with different sector sizes

This adds bootutil support for slots on different flash devices
the happen to have different sector sizes.

It consists basically in relaxing the `boot_slots_compatible` to
allow swaps as long as the sectors that are required to fit both
images are able to fit inside scratch and both slot's sectors have
sizes that are multiple of each other.

This is now tested on the simulator and was tested in a Nordic's
pca10056 using slot0 in internal flash, and slot1 in the external
QSPI flash, configured with 4K, 8K and 16K sized sectors (the HW
is 4KB but Mynewt allows emulating multiples of that!)

Signed-off-by: Fabio Utzig <utzig@apache.org>
diff --git a/boot/bootutil/src/bootutil_priv.h b/boot/bootutil/src/bootutil_priv.h
index 163d5e9..bc9c61f 100644
--- a/boot/bootutil/src/bootutil_priv.h
+++ b/boot/bootutil/src/bootutil_priv.h
@@ -164,7 +164,11 @@
         size_t num_sectors;
     } imgs[BOOT_NUM_SLOTS];
 
-    const struct flash_area *scratch_area;
+    struct {
+        const struct flash_area *area;
+        boot_sector_t *sectors;
+        size_t num_sectors;
+    } scratch;
 
     uint8_t write_sz;
 };
@@ -198,7 +202,7 @@
 
 /* These are macros so they can be used as lvalues. */
 #define BOOT_IMG_AREA(state, slot) ((state)->imgs[(slot)].area)
-#define BOOT_SCRATCH_AREA(state) ((state)->scratch_area)
+#define BOOT_SCRATCH_AREA(state) ((state)->scratch.area)
 #define BOOT_WRITE_SZ(state) ((state)->write_sz)
 
 static inline struct image_header*
@@ -213,6 +217,12 @@
     return state->imgs[slot].num_sectors;
 }
 
+static inline size_t
+boot_scratch_num_sectors(struct boot_loader_state *state)
+{
+    return state->scratch.num_sectors;
+}
+
 /*
  * Offset of the slot from the beginning of the flash device.
  */
@@ -224,7 +234,7 @@
 
 static inline size_t boot_scratch_area_size(struct boot_loader_state *state)
 {
-    return state->scratch_area->fa_size;
+    return BOOT_SCRATCH_AREA(state)->fa_size;
 }
 
 #ifndef MCUBOOT_USE_FLASH_AREA_GET_SECTORS
@@ -252,27 +262,26 @@
 boot_initialize_area(struct boot_loader_state *state, int flash_area)
 {
     int num_sectors = BOOT_MAX_IMG_SECTORS;
-    size_t slot;
     int rc;
 
     switch (flash_area) {
     case FLASH_AREA_IMAGE_0:
-        slot = 0;
+        rc = flash_area_to_sectors(flash_area, &num_sectors, state->imgs[0].sectors);
+        state->imgs[0].num_sectors = (size_t)num_sectors;
         break;
     case FLASH_AREA_IMAGE_1:
-        slot = 1;
+        rc = flash_area_to_sectors(flash_area, &num_sectors, state->imgs[1].sectors);
+        state->imgs[1].num_sectors = (size_t)num_sectors;
+        break;
+    case FLASH_AREA_IMAGE_SCRATCH:
+        rc = flash_area_to_sectors(flash_area, &num_sectors, state->scratch.sectors);
+        state->scratch.num_sectors = (size_t)num_sectors;
         break;
     default:
         return BOOT_EFLASH;
     }
 
-    rc = flash_area_to_sectors(flash_area, &num_sectors,
-                               state->imgs[slot].sectors);
-    if (rc != 0) {
-        return rc;
-    }
-    state->imgs[slot].num_sectors = (size_t)num_sectors;
-    return 0;
+    return rc;
 }
 
 #else  /* defined(MCUBOOT_USE_FLASH_AREA_GET_SECTORS) */
@@ -311,6 +320,11 @@
         out_sectors = state->imgs[1].sectors;
         out_num_sectors = &state->imgs[1].num_sectors;
         break;
+    case FLASH_AREA_IMAGE_SCRATCH:
+        num_sectors = BOOT_MAX_IMG_SECTORS;
+        out_sectors = state->scratch.sectors;
+        out_num_sectors = &state->scratch.num_sectors;
+        break;
     default:
         return -1;
     }