Boot: integrate MCUBoot with TF-M to act as a BL2 bootloader

Modifications in MCUBoot to be aligned with BL2 requirements in TF-M:
 -- OS dependency was removed, no need to copy any OS repo to build it
 -- CMSIS serial driver is used
 -- flash driver interface is aligned with original version
 -- S and NS images are handeled as a single binary blob
 -- automatic image concatenation and signing at build time
 -- authentication based on SHA256 and RSA-2048 digital signature
 -- mbedTLS library is used for cryptographic operation
 -- static analyser warnings fixed in some files

Change-Id: I54891762eac8d0df634e954ff19a9505b16f3028
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
diff --git a/bl2/ext/mcuboot/flash_map.c b/bl2/ext/mcuboot/flash_map.c
index 899c5ad..0fb8b1a 100644
--- a/bl2/ext/mcuboot/flash_map.c
+++ b/bl2/ext/mcuboot/flash_map.c
@@ -17,14 +17,14 @@
  * under the License.
  */
 
-#include <zephyr.h>
-#include <flash.h>
+#include <errno.h>
+#include <stdbool.h>
 
 #include "target.h"
+#include <flash.h>
 
 #include <flash_map/flash_map.h>
 #include <hal/hal_flash.h>
-#include <sysflash/sysflash.h>
 
 #define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_INFO
 #include "bootutil/bootutil_log.h"
@@ -38,7 +38,7 @@
  * anything "real".
  */
 #define FLASH_DEVICE_ID 100
-#define FLASH_DEVICE_BASE CONFIG_FLASH_BASE_ADDRESS
+#define FLASH_DEVICE_BASE FLASH_BASE_ADDRESS
 
 #define FLASH_MAP_ENTRY_MAGIC 0xd00dbeef
 
@@ -140,12 +140,13 @@
     entry->ref_count--;
 }
 
-void zephyr_flash_area_warn_on_open(void)
+void flash_area_warn_on_open(void)
 {
     int i;
+    struct flash_map_entry *entry;
 
     for (i = 0; i < ARRAY_SIZE(part_map); i++) {
-        struct flash_map_entry *entry = &part_map[i];
+        entry = &part_map[i];
         if (entry->ref_count) {
             BOOT_LOG_WRN("area %u has %u users",
                          entry->area.fa_id, entry->ref_count);
@@ -160,8 +161,8 @@
     return flash_read(boot_flash_device, area->fa_off + off, dst, len);
 }
 
-int flash_area_write(const struct flash_area *area, uint32_t off, const void *src,
-             uint32_t len)
+int flash_area_write(const struct flash_area *area, uint32_t off,
+                     const void *src, uint32_t len)
 {
     int rc = 0;
 
@@ -197,19 +198,12 @@
     return slot + FLASH_AREA_IMAGE_0;
 }
 
-/*
- * This is used by the legacy file as well; don't mark it static until
- * that file is removed.
- */
-int flash_area_get_bounds(int idx, uint32_t *off, uint32_t *len)
+static int validate_idx(int idx, uint32_t *off, uint32_t *len)
 {
     /*
      * This simple layout has uniform slots, so just fill in the
      * right one.
      */
-    if (idx < FLASH_AREA_IMAGE_0 || idx > FLASH_AREA_IMAGE_SCRATCH) {
-        return -1;
-    }
 
     switch (idx) {
     case FLASH_AREA_IMAGE_0:
@@ -229,132 +223,92 @@
         return -1;
     }
 
-    BOOT_LOG_DBG("area %d: offset=0x%x, length=0x%x", idx, *off, *len);
+    BOOT_LOG_DBG("area %d: offset=0x%x, length=0x%x, sector size=0x%x",
+                 idx, *off, *len, FLASH_AREA_IMAGE_SECTOR_SIZE);
     return 0;
 }
 
-/*
- * The legacy fallbacks are used instead if the flash driver doesn't
- * provide page layout support.
- */
-#if defined(CONFIG_FLASH_PAGE_LAYOUT)
-struct layout_data {
-    uint32_t area_idx;
-    uint32_t area_off;
-    uint32_t area_len;
-    void *ret;        /* struct flash_area* or struct flash_sector* */
-    uint32_t ret_idx;
-    uint32_t ret_len;
-    int status;
-};
-
-/*
- * Generic page layout discovery routine. This is kept separate to
- * support both the deprecated flash_area_to_sectors() and the current
- * flash_area_get_sectors(). A lot of this can be inlined once
- * flash_area_to_sectors() is removed.
- */
-static int flash_area_layout(int idx, int *cnt, void *ret,
-                             flash_page_cb cb, struct layout_data *cb_data)
-{
-    cb_data->area_idx = idx;
-    if (flash_area_get_bounds(idx, &cb_data->area_off, &cb_data->area_len)) {
-        return -1;
-    }
-    cb_data->ret = ret;
-    cb_data->ret_idx = 0;
-    cb_data->ret_len = *cnt;
-    cb_data->status = 0;
-
-    flash_page_foreach(boot_flash_device, cb, cb_data);
-
-    if (cb_data->status == 0) {
-        *cnt = cb_data->ret_idx;
-    }
-
-    return cb_data->status;
-}
-
-/*
- * Check if a flash_page_foreach() callback should exit early, due to
- * one of the following conditions:
- *
- * - The flash page described by "info" is before the area of interest
- *   described in "data"
- * - The flash page is after the end of the area
- * - There are too many flash pages on the device to fit in the array
- *   held in data->ret. In this case, data->status is set to -ENOMEM.
- *
- * The value to return to flash_page_foreach() is stored in
- * "bail_value" if the callback should exit early.
- */
-static bool should_bail(const struct flash_pages_info *info,
-                        struct layout_data *data,
-                        bool *bail_value)
-{
-    if (info->start_offset < data->area_off) {
-        *bail_value = true;
-        return true;
-    } else if (info->start_offset >= data->area_off + data->area_len) {
-        *bail_value = false;
-        return true;
-    } else if (data->ret_idx >= data->ret_len) {
-        data->status = -ENOMEM;
-        *bail_value = false;
-        return true;
-    }
-
-    return false;
-}
-
-static bool to_sectors_cb(const struct flash_pages_info *info, void *datav)
-{
-    struct layout_data *data = datav;
-    struct flash_area *ret = data->ret;
-    bool bail;
-
-    if (should_bail(info, data, &bail)) {
-        return bail;
-    }
-
-    ret[data->ret_idx].fa_id = data->area_idx;
-    ret[data->ret_idx].fa_device_id = 0;
-    ret[data->ret_idx].pad16 = 0;
-    ret[data->ret_idx].fa_off = info->start_offset;
-    ret[data->ret_idx].fa_size = info->size;
-    data->ret_idx++;
-
-    return true;
-}
-
 int flash_area_to_sectors(int idx, int *cnt, struct flash_area *ret)
 {
-    struct layout_data data;
+    uint32_t off;
+    uint32_t len;
+    uint32_t max_cnt = *cnt;
+    uint32_t rem_len;
 
-    return flash_area_layout(idx, cnt, ret, to_sectors_cb, &data);
-}
-
-static bool get_sectors_cb(const struct flash_pages_info *info, void *datav)
-{
-    struct layout_data *data = datav;
-    struct flash_sector *ret = data->ret;
-    bool bail;
-
-    if (should_bail(info, data, &bail)) {
-        return bail;
+    if (validate_idx(idx, &off, &len)) {
+        return -1;
     }
 
-    ret[data->ret_idx].fs_off = info->start_offset - data->area_off;
-    ret[data->ret_idx].fs_size = info->size;
-    data->ret_idx++;
+    if (*cnt < 1) {
+        return -1;
+    }
 
-    return true;
+    rem_len = len;
+    *cnt = 0;
+    while (rem_len > 0 && *cnt < max_cnt) {
+        if (rem_len < FLASH_AREA_IMAGE_SECTOR_SIZE) {
+            BOOT_LOG_ERR("area %d size 0x%x not divisible by sector size 0x%x",
+                     idx, len, FLASH_AREA_IMAGE_SECTOR_SIZE);
+            return -1;
+        }
+
+        ret[*cnt].fa_id = idx;
+        ret[*cnt].fa_device_id = 0;
+        ret[*cnt].pad16 = 0;
+        ret[*cnt].fa_off = off + (FLASH_AREA_IMAGE_SECTOR_SIZE * (*cnt));
+        ret[*cnt].fa_size = FLASH_AREA_IMAGE_SECTOR_SIZE;
+        *cnt = *cnt + 1;
+        rem_len -= FLASH_AREA_IMAGE_SECTOR_SIZE;
+    }
+
+    if (*cnt >= max_cnt) {
+        BOOT_LOG_ERR("flash area %d sector count overflow", idx);
+        return -1;
+    }
+
+    return 0;
 }
 
+/*
+ * Lookup the sector map for a given flash area.  This should fill in
+ * `ret` with all of the sectors in the area.  `*cnt` will be set to
+ * the storage at `ret` and should be set to the final number of
+ * sectors in this area.
+ */
 int flash_area_get_sectors(int idx, uint32_t *cnt, struct flash_sector *ret)
 {
-    struct layout_data data;
+    uint32_t off;
+    uint32_t len;
+    uint32_t max_cnt = *cnt;
+    uint32_t rem_len;
 
-    return flash_area_layout(idx, cnt, ret, get_sectors_cb, &data);
+    if (validate_idx(idx, &off, &len)) {
+        return -1;
+    }
+
+    if (*cnt < 1) {
+        return -1;
+    }
+
+    rem_len = len;
+    *cnt = 0;
+    while (rem_len > 0 && *cnt < max_cnt) {
+        if (rem_len < FLASH_AREA_IMAGE_SECTOR_SIZE) {
+            BOOT_LOG_ERR("area %d size 0x%x not divisible by sector size 0x%x",
+                         idx, len, FLASH_AREA_IMAGE_SECTOR_SIZE);
+            return -1;
+        }
+
+        ret[*cnt].fs_off = FLASH_AREA_IMAGE_SECTOR_SIZE * (*cnt);
+        ret[*cnt].fs_size = FLASH_AREA_IMAGE_SECTOR_SIZE;
+        *cnt = *cnt + 1;
+        rem_len -= FLASH_AREA_IMAGE_SECTOR_SIZE;
+    }
+
+    if (*cnt >= max_cnt) {
+        BOOT_LOG_ERR("flash area %d sector count overflow", idx);
+        return -1;
+    }
+
+    return 0;
 }
-#endif /* defined(CONFIG_FLASH_PAGE_LAYOUT) */