FWU: Add checking the state of the running image

The Firmware Update partition reads the image_ok flag to check
whether the running image has been confirmed. The running image
state is set according to this flag in psa_fwu_query().

Change-Id: I9cf58b7d6f3b87a50e0ac6f926e30170bb01b8f1
Signed-off-by: Sherry Zhang <sherry.zhang2@arm.com>
diff --git a/docs/technical_references/tfm_fwu_service.rst b/docs/technical_references/tfm_fwu_service.rst
index 030c094..46c98f3 100644
--- a/docs/technical_references/tfm_fwu_service.rst
+++ b/docs/technical_references/tfm_fwu_service.rst
@@ -174,7 +174,7 @@
 
 .. code-block:: c
 
-    psa_status_t fwu_bootloader_mark_image_accepted(void);
+    psa_status_t fwu_bootloader_mark_image_accepted(bl_image_id_t bootloader_image_id);
 
 **Description**
 
diff --git a/docs/technical_references/tfm_secure_boot.rst b/docs/technical_references/tfm_secure_boot.rst
index 528e7b7..1907cea 100644
--- a/docs/technical_references/tfm_secure_boot.rst
+++ b/docs/technical_references/tfm_secure_boot.rst
@@ -797,8 +797,9 @@
 The shim layer of the Firmware Update partition calls the APIs in
 bootutil_misc.c to control the image status.
 
-- Call ``boot_write_magic()`` to make the image as a candidate image for booting.
-- Call ``boot_set_confirmed()`` to make the image as a permanent image.
+- Call ``boot_set_pending_multi()`` to make the image as a candidate image for
+  booting.
+- Call ``boot_set_confirmed_multi()`` to make the image as a permanent image.
 
 .. Note::
     Currently, in direct-xip mode and ram-load mode, TF-M cannot get the
diff --git a/interface/include/psa/update.h b/interface/include/psa/update.h
index 65d7d2d..d7de5ac 100644
--- a/interface/include/psa/update.h
+++ b/interface/include/psa/update.h
@@ -207,6 +207,8 @@
 /**
  * \brief Indicates to the implementation that the upgrade was successful.
  *
+ * \param[in] image_id         The image_id of the image to query
+ *
  * \return A status indicating the success/failure of the operation
  *
  * \retval PSA_SUCCESS                  The image and its dependencies have
@@ -217,7 +219,7 @@
  * \retval PSA_ERROR_NOT_PERMITTED      The caller is not permitted to make
  *                                      this call
  */
-psa_status_t psa_fwu_accept(void);
+psa_status_t psa_fwu_accept(psa_image_id_t image_id);
 
 /**
  * \brief Stores a manifest object and associates it with a particular image ID.
diff --git a/interface/src/tfm_firmware_update_func_api.c b/interface/src/tfm_firmware_update_func_api.c
index 4870288..5100d44 100644
--- a/interface/src/tfm_firmware_update_func_api.c
+++ b/interface/src/tfm_firmware_update_func_api.c
@@ -122,12 +122,15 @@
     return status;
 }
 
-psa_status_t psa_fwu_accept(void)
+psa_status_t psa_fwu_accept(psa_image_id_t image_id)
 {
     psa_status_t status;
+    psa_invec in_vec[] = {
+        { .base = &image_id, .len = sizeof(image_id) }
+    };
 
     status = tfm_ns_interface_dispatch((veneer_fn)tfm_fwu_accept_req_veneer,
-                                       (uint32_t)NULL, 0,
+                                       (uint32_t)in_vec, IOVEC_LEN(in_vec),
                                        (uint32_t)NULL, 0);
 
     if (status == (psa_status_t)TFM_ERROR_INVALID_PARAMETER) {
diff --git a/interface/src/tfm_firmware_update_ipc_api.c b/interface/src/tfm_firmware_update_ipc_api.c
index a21a333..60d4b2e 100644
--- a/interface/src/tfm_firmware_update_ipc_api.c
+++ b/interface/src/tfm_firmware_update_ipc_api.c
@@ -155,10 +155,13 @@
     return status;
 }
 
-psa_status_t psa_fwu_accept(void)
+psa_status_t psa_fwu_accept(psa_image_id_t image_id)
 {
     psa_handle_t handle;
     psa_status_t status;
+    psa_invec in_vec[] = {
+        { .base = &image_id, .len = sizeof(image_id) }
+    };
 
     handle = psa_connect(TFM_FWU_ACCEPT_SID,
                          TFM_FWU_ACCEPT_VERSION);
@@ -166,7 +169,7 @@
         return PSA_ERROR_GENERIC_ERROR;
     }
 
-    status = psa_call(handle, PSA_IPC_CALL, NULL, 0, NULL, 0);
+    status = psa_call(handle, PSA_IPC_CALL, in_vec, IOVEC_LEN(in_vec), NULL, 0);
 
     psa_close(handle);
 
diff --git a/secure_fw/partitions/firmware_update/bootloader/mcuboot/CMakeLists.txt b/secure_fw/partitions/firmware_update/bootloader/mcuboot/CMakeLists.txt
index b764c9e..405d0b5 100644
--- a/secure_fw/partitions/firmware_update/bootloader/mcuboot/CMakeLists.txt
+++ b/secure_fw/partitions/firmware_update/bootloader/mcuboot/CMakeLists.txt
@@ -11,7 +11,7 @@
 
 target_sources(tfm_fwu_mcuboot_util
     INTERFACE
-        ${MCUBOOT_PATH}/boot/bootutil/src/bootutil_misc.c
+        ${MCUBOOT_PATH}/boot/bootutil/src/bootutil_public.c
         ${MCUBOOT_PATH}/boot/bootutil/src/tlv.c
         ${CMAKE_SOURCE_DIR}/bl2/src/flash_map.c
         ${CMAKE_SOURCE_DIR}/bl2/ext/mcuboot/flash_map_extended.c
diff --git a/secure_fw/partitions/firmware_update/bootloader/mcuboot/tfm_mcuboot_fwu.c b/secure_fw/partitions/firmware_update/bootloader/mcuboot/tfm_mcuboot_fwu.c
index 034f8fe..c0966f2 100644
--- a/secure_fw/partitions/firmware_update/bootloader/mcuboot/tfm_mcuboot_fwu.c
+++ b/secure_fw/partitions/firmware_update/bootloader/mcuboot/tfm_mcuboot_fwu.c
@@ -6,7 +6,7 @@
  */
 
 #include "psa/crypto.h"
-#include "log/tfm_log.h"
+#include "tfm_sp_log.h"
 #include "bootutil_priv.h"
 #include "bootutil/bootutil.h"
 #include "bootutil/image.h"
@@ -52,8 +52,6 @@
 static tfm_fwu_mcuboot_ctx_t mcuboot_ctx[TFM_FWU_MAX_IMAGES];
 static fwu_image_info_data_t boot_shared_data;
 extern const uint32_t boot_img_magic[];
-#define BOOT_MAGIC_ARR_SZ \
-    (sizeof(boot_img_magic) / sizeof(boot_img_magic[0]))
 
 static int convert_id_from_bl_to_mcuboot(bl_image_id_t bl_image_id,
                                          uint8_t *mcuboot_image_id)
@@ -61,7 +59,7 @@
 #if (MCUBOOT_IMAGE_NUMBER == 1)
     /* Only full image upgrade is supported in this case. */
     if (bl_image_id != FWU_IMAGE_TYPE_FULL) {
-        LOG_MSG("TFM FWU: multi-image is not supported in current mcuboot configuration.");
+        LOG_ERRFMT("TFM FWU: multi-image is not supported in current mcuboot configuration.");
         return -1;
     }
 
@@ -75,7 +73,7 @@
         /* The image id in mcuboot. 1: the non-secure image. */
         *mcuboot_image_id = 1;
     }  else {
-        LOG_MSG("TFM FWU: invalid image_type: %d", bl_image_id);
+        LOG_ERRFMT("TFM FWU: invalid image_type: %d", bl_image_id);
         return -1;
     }
 #endif
@@ -99,7 +97,7 @@
         /* The image id in mcuboot. 1: the non-secure image. */
         image_type = FWU_IMAGE_TYPE_NONSECURE;
     }  else {
-        LOG_MSG("TFM FWU: invalid mcuboot image id\n\r: %d",
+        LOG_ERRFMT("TFM FWU: invalid mcuboot image id\n\r: %d",
                 mcuboot_image_id);
         return -1;
     }
@@ -199,7 +197,7 @@
 
     if (flash_area_open(FLASH_AREA_IMAGE_SECONDARY(mcuboot_image_id),
                         &fap) != 0) {
-        LOG_MSG("TFM FWU: opening flash failed.\r\n");
+        LOG_ERRFMT("TFM FWU: opening flash failed.\r\n");
         return PSA_ERROR_GENERIC_ERROR;
     }
 
@@ -215,7 +213,7 @@
     }
 
     if (flash_area_erase(fap, 0, fap->fa_size) != 0) {
-        LOG_MSG("TFM FWU: erasing flash failed.\r\n");
+        LOG_ERRFMT("TFM FWU: erasing flash failed.\r\n");
         return PSA_ERROR_GENERIC_ERROR;
     }
 
@@ -248,7 +246,7 @@
     }
 
     if (flash_area_write(fap, block_offset, block, block_size) != 0) {
-        LOG_MSG("TFM FWU: write flash failed.\r\n");
+        LOG_ERRFMT("TFM FWU: write flash failed.\r\n");
         return PSA_ERROR_GENERIC_ERROR;
     }
 
@@ -452,14 +450,15 @@
      * are installed, the user should call the psa_fwu_install API to install
      * this image again.
      */
-    if (boot_write_magic(fap) != 0) {
+    if (boot_set_pending_multi(mcuboot_image_id, false) != 0) {
         return PSA_ERROR_GENERIC_ERROR;
     } else {
         return ret;
     }
 }
 
-psa_status_t fwu_bootloader_mark_image_accepted(void)
+psa_status_t fwu_bootloader_mark_image_accepted(
+                                              bl_image_id_t bootloader_image_id)
 {
     /* As DIRECT_XIP, RAM_LOAD and OVERWRITE_ONLY do not support image revert.
      * So there is nothing to do in these three upgrade strategies. Image
@@ -470,11 +469,20 @@
      */
 #if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD) && \
     !defined(MCUBOOT_OVERWRITE_ONLY)
-    if (boot_set_confirmed() != 0) {
+    uint8_t mcuboot_image_id = 0;
+
+    if (convert_id_from_bl_to_mcuboot(bootloader_image_id,
+                                    &mcuboot_image_id) != 0) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    if (boot_set_confirmed_multi(mcuboot_image_id) != 0) {
         return PSA_ERROR_GENERIC_ERROR;
     }
-#endif
+#else
+    (void)bootloader_image_id;
     return PSA_SUCCESS;
+#endif
 }
 
 psa_status_t fwu_bootloader_abort(bl_image_id_t bootloader_image_id)
@@ -559,13 +567,13 @@
 
     if ((flash_area_open(FLASH_AREA_IMAGE_SECONDARY(image_id),
                             &fap)) != 0) {
-        LOG_MSG("TFM FWU: opening flash failed.\r\n");
+        LOG_ERRFMT("TFM FWU: opening flash failed.\r\n");
         return PSA_ERROR_GENERIC_ERROR;
     }
 
     if (flash_area_read(fap, 0, &hdr, sizeof(hdr)) != 0) {
         flash_area_close(fap);
-        LOG_MSG("TFM FWU: reading flash failed.\r\n");
+        LOG_ERRFMT("TFM FWU: reading flash failed.\r\n");
         return PSA_ERROR_GENERIC_ERROR;
     }
 
@@ -588,7 +596,7 @@
             info->version.iv_minor = hdr.ih_ver.iv_minor;
             info->version.iv_revision = hdr.ih_ver.iv_revision;
             info->version.iv_build_num = hdr.ih_ver.iv_build_num;
-            LOG_MSG("version= %d., %d., %d.,+ %d\n\r",
+            LOG_ERRFMT("version= %d., %d., %d.,+ %d\n\r",
                     info->version.iv_major,
                     info->version.iv_minor,
                     info->version.iv_revision,
@@ -625,7 +633,11 @@
 {
     struct image_version image_ver = { 0 };
     uint8_t mcuboot_image_id = 0;
-
+#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD) && \
+    !defined(MCUBOOT_OVERWRITE_ONLY)
+    const struct flash_area *fap = NULL;
+    uint8_t image_ok = BOOT_FLAG_UNSET;
+#endif
     if (info == NULL) {
         return PSA_ERROR_INVALID_ARGUMENT;
     }
@@ -639,12 +651,33 @@
     memset(info->digest, TFM_IMAGE_INFO_INVALID_DIGEST, sizeof(info->digest));
 
     if (active_image) {
-        /* Set the image state as accepted. */
-        /* TODO: check the image state by reading the image_ok flag in SWAP
-         * case.
-         */
-        info->state = PSA_IMAGE_INSTALLED;
+    /* As DIRECT_XIP, RAM_LOAD and OVERWRITE_ONLY do not support image revert.
+     * So the running image is in INSTALLED state in these three upgrade
+     * strategies. In the SWAP case, the image_ok flag should be read to check
+     * whether the running image has been confirmed as a pernament image.
+     */
+#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD) && \
+    !defined(MCUBOOT_OVERWRITE_ONLY)
+        if ((flash_area_open(FLASH_AREA_IMAGE_PRIMARY(mcuboot_image_id),
+                            &fap)) != 0) {
+            LOG_ERRFMT("TFM FWU: opening flash failed.\r\n");
+            return PSA_ERROR_GENERIC_ERROR;
+        }
 
+        /* Get value of image-ok flag of the image to check whether application
+         * itself is already confirmed.
+         */
+        if (boot_read_image_ok(fap, &image_ok) != 0) {
+            return PSA_ERROR_GENERIC_ERROR;
+        }
+        if (image_ok == BOOT_FLAG_SET) {
+            info->state = PSA_IMAGE_INSTALLED;
+        } else {
+            info->state = PSA_IMAGE_PENDING_INSTALL;
+        }
+#else
+        info->state = PSA_IMAGE_INSTALLED;
+#endif
         if (get_running_image_version(mcuboot_image_id,
                                       &image_ver) == PSA_SUCCESS) {
             info->version.iv_major = image_ver.iv_major;
diff --git a/secure_fw/partitions/firmware_update/bootloader/tfm_bootloader_fwu_abstraction.h b/secure_fw/partitions/firmware_update/bootloader/tfm_bootloader_fwu_abstraction.h
index 06c3eff..002fb74 100644
--- a/secure_fw/partitions/firmware_update/bootloader/tfm_bootloader_fwu_abstraction.h
+++ b/secure_fw/partitions/firmware_update/bootloader/tfm_bootloader_fwu_abstraction.h
@@ -116,7 +116,8 @@
  * \return PSA_SUCCESS         On success
  *         PSA_ERROR_GENERIC_ERROR       A fatal error occurred
  */
-psa_status_t fwu_bootloader_mark_image_accepted(void);
+psa_status_t fwu_bootloader_mark_image_accepted(
+                                             bl_image_id_t bootloader_image_id);
 
 /**
  * \brief Abort the current image download process.
diff --git a/secure_fw/partitions/firmware_update/tfm_fwu.c b/secure_fw/partitions/firmware_update/tfm_fwu.c
index 3768f65..025d241 100644
--- a/secure_fw/partitions/firmware_update/tfm_fwu.c
+++ b/secure_fw/partitions/firmware_update/tfm_fwu.c
@@ -6,7 +6,7 @@
  */
 
 #include <stdint.h>
-#include "log/tfm_log.h"
+#include "tfm_sp_log.h"
 #include "tfm_platform_api.h"
 #include "tfm_fwu.h"
 
@@ -17,7 +17,7 @@
 
     /* Check the image slot, the target should be the staging slot. */
     if (slot_id != FWU_IMAGE_ID_SLOT_STAGE) {
-        LOG_MSG("TFM FWU: invalid slot_id: %d", slot_id);
+        LOG_ERRFMT("TFM FWU: invalid slot_id: %d", slot_id);
         return PSA_ERROR_INVALID_ARGUMENT;
     }
 
@@ -54,7 +54,7 @@
 
     /* Check the image slot, the target should be the staging slot. */
     if (slot_id != FWU_IMAGE_ID_SLOT_STAGE) {
-        LOG_MSG("TFM FWU: invalid slot_id: %d", slot_id);
+        LOG_ERRFMT("TFM FWU: invalid slot_id: %d", slot_id);
         return PSA_ERROR_INVALID_ARGUMENT;
     }
 
@@ -100,7 +100,7 @@
     } else if (slot_id == FWU_IMAGE_ID_SLOT_ACTIVE) {
         active_image = true;
     } else {
-        LOG_MSG("TFM FWU: invalid slot_id: %d", slot_id);
+        LOG_ERRFMT("TFM FWU: invalid slot_id: %d", slot_id);
         return PSA_ERROR_INVALID_ARGUMENT;
     }
 
@@ -112,7 +112,9 @@
     tfm_platform_system_reset();
 }
 
-psa_status_t tfm_internal_fwu_accept(void)
+psa_status_t tfm_internal_fwu_accept(psa_image_id_t image_id)
 {
-    return fwu_bootloader_mark_image_accepted();
+    uint8_t image_type = (uint8_t)FWU_IMAGE_ID_GET_TYPE(image_id);
+
+    return fwu_bootloader_mark_image_accepted(image_type);
 }
diff --git a/secure_fw/partitions/firmware_update/tfm_fwu.h b/secure_fw/partitions/firmware_update/tfm_fwu.h
index a4cc83f..ec64d9a 100644
--- a/secure_fw/partitions/firmware_update/tfm_fwu.h
+++ b/secure_fw/partitions/firmware_update/tfm_fwu.h
@@ -56,7 +56,7 @@
 /*
  * Marks the image in the primary slot as confirmed.
  */
-psa_status_t tfm_internal_fwu_accept(void);
+psa_status_t tfm_internal_fwu_accept(psa_image_id_t image_id);
 
 #ifdef __cplusplus
 }
diff --git a/secure_fw/partitions/firmware_update/tfm_fwu_req_mngr.c b/secure_fw/partitions/firmware_update/tfm_fwu_req_mngr.c
index e1a225a..8c25aa4 100644
--- a/secure_fw/partitions/firmware_update/tfm_fwu_req_mngr.c
+++ b/secure_fw/partitions/firmware_update/tfm_fwu_req_mngr.c
@@ -211,17 +211,22 @@
 }
 
 psa_status_t tfm_fwu_accept_req(psa_invec *in_vec, size_t in_len,
-                               psa_outvec *out_vec, size_t out_len)
+                                psa_outvec *out_vec, size_t out_len)
 {
-    (void)in_vec;
     (void)out_vec;
-    (void)in_len;
     (void)out_len;
 
+    psa_image_id_t image_id;
+
+    if (in_vec[0].len != sizeof(image_id) || in_len != 1) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+    image_id = *((psa_image_id_t *)in_vec[0].base);
+
     /* This operation set the running image to INSTALLED state, the images
      * in the staging area does not impact this operation.
      */
-    return tfm_internal_fwu_accept();
+    return tfm_internal_fwu_accept(image_id);
 }
 
 /* Abort the currently running FWU. */
@@ -417,10 +422,22 @@
 
 static psa_status_t tfm_fwu_accept_ipc(void)
 {
+    psa_image_id_t image_id;
+    size_t num;
+
+    /* Check input parameters. */
+    if (msg.in_size[0] != sizeof(image_id)) {
+        return PSA_ERROR_PROGRAMMER_ERROR;
+    }
+    num = psa_read(msg.handle, 0, &image_id, sizeof(image_id));
+    if (num != sizeof(image_id)) {
+        return PSA_ERROR_PROGRAMMER_ERROR;
+    }
+
     /* This operation set the running image to INSTALLED state, the images
      * in the staging area does not impact this operation.
      */
-    return tfm_internal_fwu_accept();
+    return tfm_internal_fwu_accept(image_id);
 }
 
 static psa_status_t tfm_fwu_abort_ipc(void)
diff --git a/secure_fw/partitions/firmware_update/tfm_fwu_secure_api.c b/secure_fw/partitions/firmware_update/tfm_fwu_secure_api.c
index aefd1b6..20633bd 100644
--- a/secure_fw/partitions/firmware_update/tfm_fwu_secure_api.c
+++ b/secure_fw/partitions/firmware_update/tfm_fwu_secure_api.c
@@ -211,12 +211,15 @@
     return status;
 }
 
-psa_status_t psa_fwu_accept(void)
+psa_status_t psa_fwu_accept(psa_image_id_t image_id)
 {
     psa_status_t status;
 #ifdef TFM_PSA_API
     psa_handle_t handle;
 #endif
+    psa_invec in_vec[] = {
+        { .base = &image_id, .len = sizeof(image_id) }
+    };
 
 #ifdef TFM_PSA_API
     handle = psa_connect(TFM_FWU_ACCEPT_SID,
@@ -225,11 +228,11 @@
         return PSA_ERROR_GENERIC_ERROR;
     }
 
-    status = psa_call(handle, PSA_IPC_CALL, NULL, 0, NULL, 0);
+    status = psa_call(handle, PSA_IPC_CALL, in_vec, IOVEC_LEN(in_vec), NULL, 0);
 
     psa_close(handle);
 #else
-    status = tfm_fwu_accept_req_veneer(NULL, 0, NULL, 0);
+    status = tfm_fwu_accept_req_veneer(in_vec, IOVEC_LEN(in_vec), NULL, 0);
 #endif
 
     if (status == (psa_status_t)TFM_ERROR_INVALID_PARAMETER) {