mcuboot - Initial migration.
diff --git a/bootutil/src/bootutil_misc.c b/bootutil/src/bootutil_misc.c
new file mode 100644
index 0000000..f3ab9d5
--- /dev/null
+++ b/bootutil/src/bootutil_misc.c
@@ -0,0 +1,456 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "syscfg/syscfg.h"
+#include "sysflash/sysflash.h"
+#include "hal/hal_bsp.h"
+#include "hal/hal_flash.h"
+#include "flash_map/flash_map.h"
+#include "os/os.h"
+#include "bootutil/image.h"
+#include "bootutil/bootutil.h"
+#include "bootutil_priv.h"
+
+int boot_current_slot;
+
+const uint32_t boot_img_magic[4] = {
+    0xf395c277,
+    0x7fefd260,
+    0x0f505235,
+    0x8079b62c,
+};
+
+struct boot_swap_table {
+    /** * For each field, a value of 0 means "any". */
+    uint8_t bsw_magic_slot0;
+    uint8_t bsw_magic_slot1;
+    uint8_t bsw_image_ok_slot0;
+
+    uint8_t bsw_swap_type;
+};
+
+/**
+ * This set of tables maps image trailer contents to swap operation type.
+ * When searching for a match, these tables must be iterated sequentially.
+ */
+static const struct boot_swap_table boot_swap_tables[] = {
+    {
+        /*          | slot-0     | slot-1     |
+         *----------+------------+------------|
+         *    magic | Unset      | Unset      |
+         * image-ok | Any        | N/A        |
+         * ---------+------------+------------'
+         * swap: none                         |
+         * -----------------------------------'
+         */
+        .bsw_magic_slot0 =      BOOT_MAGIC_UNSET,
+        .bsw_magic_slot1 =      BOOT_MAGIC_UNSET,
+        .bsw_image_ok_slot0 =   0,
+        .bsw_swap_type =        BOOT_SWAP_TYPE_NONE,
+    },
+
+    {
+        /*          | slot-0     | slot-1     |
+         *----------+------------+------------|
+         *    magic | Any        | Good       |
+         * image-ok | Any        | N/A        |
+         * ---------+------------+------------'
+         * swap: test                         |
+         * -----------------------------------'
+         */
+        .bsw_magic_slot0 =      0,
+        .bsw_magic_slot1 =      BOOT_MAGIC_GOOD,
+        .bsw_image_ok_slot0 =   0,
+        .bsw_swap_type =        BOOT_SWAP_TYPE_TEST,
+    },
+
+    {
+        /*          | slot-0     | slot-1     |
+         *----------+------------+------------|
+         *    magic | Good       | Unset      |
+         * image-ok | 0xff       | N/A        |
+         * ---------+------------+------------'
+         * swap: revert (test image running)  |
+         * -----------------------------------'
+         */
+        .bsw_magic_slot0 =      BOOT_MAGIC_GOOD,
+        .bsw_magic_slot1 =      BOOT_MAGIC_UNSET,
+        .bsw_image_ok_slot0 =   0xff,
+        .bsw_swap_type =        BOOT_SWAP_TYPE_REVERT,
+    },
+
+    {
+        /*          | slot-0     | slot-1     |
+         *----------+------------+------------|
+         *    magic | Good       | Unset      |
+         * image-ok | 0x01       | N/A        |
+         * ---------+------------+------------'
+         * swap: none (confirmed test image)  |
+         * -----------------------------------'
+         */
+        .bsw_magic_slot0 =      BOOT_MAGIC_GOOD,
+        .bsw_magic_slot1 =      BOOT_MAGIC_UNSET,
+        .bsw_image_ok_slot0 =   0x01,
+        .bsw_swap_type =        BOOT_SWAP_TYPE_NONE,
+    },
+};
+
+#define BOOT_SWAP_TABLES_COUNT \
+    (sizeof boot_swap_tables / sizeof boot_swap_tables[0])
+
+int
+boot_magic_code(const uint32_t *magic)
+{
+    int i;
+
+    if (memcmp(magic, boot_img_magic, sizeof boot_img_magic) == 0) {
+        return BOOT_MAGIC_GOOD;
+    }
+
+    for (i = 0; i < 4; i++) {
+        if (magic[i] == 0xffffffff) {
+            return BOOT_MAGIC_UNSET;
+        }
+    }
+
+    return BOOT_MAGIC_BAD;
+}
+
+uint32_t
+boot_status_sz(uint8_t min_write_sz)
+{
+    return BOOT_STATUS_MAX_ENTRIES * BOOT_STATUS_STATE_COUNT * min_write_sz;
+}
+
+uint32_t
+boot_trailer_sz(uint8_t min_write_sz)
+{
+    return sizeof boot_img_magic            +
+           boot_status_sz(min_write_sz)     +
+           min_write_sz * 2;
+}
+
+static uint32_t
+boot_magic_off(const struct flash_area *fap)
+{
+    uint32_t off_from_end;
+    uint8_t elem_sz;
+
+    elem_sz = flash_area_align(fap);
+
+    off_from_end = boot_trailer_sz(elem_sz);
+
+    assert(off_from_end <= fap->fa_size);
+    return fap->fa_size - off_from_end;
+}
+
+uint32_t
+boot_status_off(const struct flash_area *fap)
+{
+    return boot_magic_off(fap) + sizeof boot_img_magic;
+}
+
+static uint32_t
+boot_copy_done_off(const struct flash_area *fap)
+{
+    return fap->fa_size - flash_area_align(fap) * 2;
+}
+
+static uint32_t
+boot_image_ok_off(const struct flash_area *fap)
+{
+    return fap->fa_size - flash_area_align(fap);
+}
+
+int
+boot_read_swap_state(const struct flash_area *fap,
+                     struct boot_swap_state *state)
+{
+    uint32_t magic[4];
+    uint32_t off;
+    int rc;
+
+    off = boot_magic_off(fap);
+    rc = flash_area_read(fap, off, magic, sizeof magic);
+    if (rc != 0) {
+        return BOOT_EFLASH;
+    }
+    state->magic = boot_magic_code(magic);
+
+    off = boot_copy_done_off(fap);
+    rc = flash_area_read(fap, off, &state->copy_done, 1);
+    if (rc != 0) {
+        return BOOT_EFLASH;
+    }
+
+    off = boot_image_ok_off(fap);
+    rc = flash_area_read(fap, off, &state->image_ok, 1);
+    if (rc != 0) {
+        return BOOT_EFLASH;
+    }
+
+    return 0;
+}
+
+/**
+ * Reads the image trailer from the scratch area.
+ */
+int
+boot_read_swap_state_scratch(struct boot_swap_state *state)
+{
+    const struct flash_area *fap;
+    int rc;
+
+    rc = flash_area_open(FLASH_AREA_IMAGE_SCRATCH, &fap);
+    if (rc) {
+        rc = BOOT_EFLASH;
+        goto done;
+    }
+
+    rc = boot_read_swap_state(fap, state);
+    if (rc != 0) {
+        goto done;
+    }
+
+    rc = 0;
+
+done:
+    flash_area_close(fap);
+    return rc;
+}
+
+/**
+ * Reads the image trailer from a given image slot.
+ */
+int
+boot_read_swap_state_img(int slot, struct boot_swap_state *state)
+{
+    const struct flash_area *fap;
+    int area_id;
+    int rc;
+
+    area_id = flash_area_id_from_image_slot(slot);
+    rc = flash_area_open(area_id, &fap);
+    if (rc != 0) {
+        rc = BOOT_EFLASH;
+        goto done;
+    }
+
+    rc = boot_read_swap_state(fap, state);
+    if (rc != 0) {
+        goto done;
+    }
+
+    rc = 0;
+
+done:
+    flash_area_close(fap);
+    return rc;
+}
+
+int
+boot_write_magic(const struct flash_area *fap)
+{
+    uint32_t off;
+    int rc;
+
+    off = boot_magic_off(fap);
+
+    rc = flash_area_write(fap, off, boot_img_magic, sizeof boot_img_magic);
+    if (rc != 0) {
+        return BOOT_EFLASH;
+    }
+
+    return 0;
+}
+
+int
+boot_write_copy_done(const struct flash_area *fap)
+{
+    uint32_t off;
+    uint8_t val;
+    int rc;
+
+    off = boot_copy_done_off(fap);
+
+    val = 1;
+    rc = flash_area_write(fap, off, &val, 1);
+    if (rc != 0) {
+        return BOOT_EFLASH;
+    }
+
+    return 0;
+}
+
+int
+boot_write_image_ok(const struct flash_area *fap)
+{
+    uint32_t off;
+    uint8_t val;
+    int rc;
+
+    off = boot_image_ok_off(fap);
+
+    val = 1;
+    rc = flash_area_write(fap, off, &val, 1);
+    if (rc != 0) {
+        return BOOT_EFLASH;
+    }
+
+    return 0;
+}
+
+int
+boot_swap_type(void)
+{
+    const struct boot_swap_table *table;
+    struct boot_swap_state state_slot0;
+    struct boot_swap_state state_slot1;
+    int rc;
+    int i;
+
+    rc = boot_read_swap_state_img(0, &state_slot0);
+    assert(rc == 0);
+
+    rc = boot_read_swap_state_img(1, &state_slot1);
+    assert(rc == 0);
+
+    for (i = 0; i < BOOT_SWAP_TABLES_COUNT; i++) {
+        table = boot_swap_tables + i;
+
+        if ((table->bsw_magic_slot0     == 0    ||
+             table->bsw_magic_slot0     == state_slot0.magic)           &&
+            (table->bsw_magic_slot1     == 0    ||
+             table->bsw_magic_slot1     == state_slot1.magic)           &&
+            (table->bsw_image_ok_slot0  == 0    ||
+             table->bsw_image_ok_slot0  == state_slot0.image_ok)) {
+
+            return table->bsw_swap_type;
+        }
+    }
+
+    assert(0);
+    return BOOT_SWAP_TYPE_NONE;
+}
+
+/**
+ * Marks the image in slot 1 as pending.  On the next reboot, the system will
+ * perform a one-time boot of the slot 1 image.
+ *
+ * @return                  0 on success; nonzero on failure.
+ */
+int
+boot_set_pending(void)
+{
+    const struct flash_area *fap;
+    struct boot_swap_state state_slot1;
+    int area_id;
+    int rc;
+
+    rc = boot_read_swap_state_img(1, &state_slot1);
+    if (rc != 0) {
+        return rc;
+    }
+
+    switch (state_slot1.magic) {
+    case BOOT_MAGIC_GOOD:
+        /* Swap already scheduled. */
+        return 0;
+
+    case BOOT_MAGIC_UNSET:
+        area_id = flash_area_id_from_image_slot(1);
+        rc = flash_area_open(area_id, &fap);
+        if (rc != 0) {
+            rc = BOOT_EFLASH;
+        } else {
+            rc = boot_write_magic(fap);
+        }
+
+        flash_area_close(fap);
+        return rc;
+
+    default:
+        /* XXX: Temporary assert. */
+        assert(0);
+        return -1;
+    }
+}
+
+/**
+ * Marks the image in slot 0 as confirmed.  The system will continue booting into the image in slot 0 until told to boot from a different slot.
+ *
+ * @return                  0 on success; nonzero on failure.
+ */
+int
+boot_set_confirmed(void)
+{
+    const struct flash_area *fap;
+    struct boot_swap_state state_slot0;
+    int rc;
+
+    rc = boot_read_swap_state_img(0, &state_slot0);
+    if (rc != 0) {
+        return rc;
+    }
+
+    switch (state_slot0.magic) {
+    case BOOT_MAGIC_GOOD:
+        /* Confirm needed; proceed. */
+        break;
+
+    case BOOT_MAGIC_UNSET:
+        /* Already confirmed. */
+        return 0;
+
+    case BOOT_MAGIC_BAD:
+        /* Unexpected state. */
+        return BOOT_EBADVECT;
+    }
+
+    if (state_slot0.copy_done == 0xff) {
+        /* Swap never completed.  This is unexpected. */
+        return BOOT_EBADVECT;
+    }
+
+    if (state_slot0.image_ok != 0xff) {
+        /* Already confirmed. */
+        return 0;
+    }
+
+    rc = flash_area_open(FLASH_AREA_IMAGE_0, &fap);
+    if (rc) {
+        rc = BOOT_EFLASH;
+        goto done;
+    }
+
+    rc = boot_write_image_ok(fap);
+    if (rc != 0) {
+        goto done;
+    }
+
+    rc = 0;
+
+done:
+    flash_area_close(fap);
+    return rc;
+}