FWU: Add Firmware Update partition

Firmware Update(FWU) partition provides the functionality
of updating firmware images. This patch implemented the
partition in Library mode.

Change-Id: I736477549b055c64cd8106ad57c3ad7b1b2007ee
Signed-off-by: Sherry Zhang <sherry.zhang2@arm.com>
diff --git a/interface/include/psa/update.h b/interface/include/psa/update.h
new file mode 100644
index 0000000..65d7d2d
--- /dev/null
+++ b/interface/include/psa/update.h
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PSA_UPDATE_H
+#define PSA_UPDATE_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "psa/error.h"
+#include "tfm_fwu_defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PSA_FWU_MAX_BLOCK_SIZE               1024
+#define TFM_FWU_INVALID_IMAGE_ID             0
+
+/* The maximum size of an image digest in bytes. This is dependent
+ * on the hash algorithm used.
+ */
+#define PSA_FWU_MAX_DIGEST_SIZE              32
+#define TFM_IMAGE_INFO_INVALID_DIGEST        0xFF
+
+/* The image ID macros. */
+#define FWU_IMAGE_ID_SLOT_POSITION           0U
+
+/* The area where the image is running. */
+#define FWU_IMAGE_ID_SLOT_ACTIVE             0x01U
+
+/* The area to stage the image. */
+#define FWU_IMAGE_ID_SLOT_STAGE              0x02U
+#define FWU_IMAGE_ID_SLOT_MASK               0x00FF
+
+#define FWU_IMAGE_ID_TYPE_POSITION           8U
+#define FWU_IMAGE_ID_SPECIFIC_ID_POSITION    16U
+
+#define FWU_CALCULATE_IMAGE_ID(slot, type, specific_id)             \
+                             ((slot & FWU_IMAGE_ID_SLOT_MASK) |     \
+                             (type << FWU_IMAGE_ID_TYPE_POSITION) | \
+                             (specific_id << FWU_IMAGE_ID_SPECIFIC_ID_POSITION))
+#define FWU_IMAGE_ID_GET_TYPE(image_id) (image_id >> FWU_IMAGE_ID_TYPE_POSITION)
+#define FWU_IMAGE_ID_GET_SLOT(image_id) (image_id & FWU_IMAGE_ID_SLOT_MASK)
+
+/* Image state macros. */
+#define PSA_IMAGE_UNDEFINED            0
+#define PSA_IMAGE_CANDIDATE            1
+#define PSA_IMAGE_INSTALLED            2
+#define PSA_IMAGE_REJECTED             3
+#define PSA_IMAGE_PENDING_INSTALL      4
+#define PSA_IMAGE_REBOOT_NEEDED        5
+
+/*
+ * image_id[7:0]: slot.
+ * image_id[15:8]: image type.
+ * image_id[31:16]: specific image ID.
+ */
+typedef uint32_t psa_image_id_t;
+
+typedef struct tfm_image_version_s {
+    uint8_t iv_major;
+    uint8_t iv_minor;
+    uint16_t iv_revision;
+    uint32_t iv_build_num;
+} psa_image_version_t;
+
+typedef struct tfm_image_info_s {
+    psa_image_version_t version;
+    uint8_t state;
+    uint8_t digest[PSA_FWU_MAX_DIGEST_SIZE];
+} psa_image_info_t;
+
+typedef struct psa_hash_s {
+    uint8_t value[PSA_FWU_MAX_DIGEST_SIZE];
+} psa_hash_t;
+
+/**
+ * \brief Writes an image to its staging area.
+ *
+ * Writes the image data 'block' with length 'block_size' to its staging area.
+ * If the image size is less than or equal to PSA_FWU_MAX_BLOCK_SIZE, the
+ * caller can send the entire image in one call.
+ * If the image size is greater than PSA_FWU_MAX_BLOCK_SIZE, the caller must
+ * send parts of the image by calling this API multiple times with different
+ * data blocks.
+ *
+ * \param[in] image_id        The identifier of the image
+ * \param[in] block_offset    The offset of the block being passed into block,
+ *                            in bytes
+ * \param[in] block           A buffer containing a block of image data. This
+ *                            might be a complete image or a subset.
+ * \param[in] block_size      Size of block. The size must not be greater than
+ *                            PSA_FWU_MAX_BLOCK_SIZE.
+ *
+ * \return A status indicating the success/failure of the operation
+ *
+ * \retval PSA_SUCCESS                     The data in block has been
+ *                                         successfully stored.
+ * \retval PSA_ERROR_INVALID_ARGUMENT      One of the following error
+ *                                         conditions occurred:
+ *                                         The parameter size is greater than
+ *                                         PSA_FWU_MAX_BLOCK_SIZE;
+ *                                         The parameter size is 0;
+ *                                         The combination of offset and size
+ *                                         is out of bounds.
+ *
+ * \retval PSA_ERROR_INSUFFICIENT_MEMORY   There is not enough memory to
+ *                                         process the update
+ * \retval PSA_ERROR_INSUFFICIENT_STORAGE  There is not enough storage to
+ *                                         process the update
+ * \retval PSA_ERROR_GENERAL_ERROR         A fatal error occurred
+ * \retval PSA_ERROR_CURRENTLY_INSTALLING        The image is currently locked for
+ *                                         writing.
+ */
+psa_status_t psa_fwu_write(psa_image_id_t image_id,
+                           size_t block_offset,
+                           const void *block,
+                           size_t block_size);
+
+
+/**
+ * \brief Starts the installation of an image.
+ *
+ * The authenticity and integrity of the image is checked during installation.
+ * If a reboot is required to complete installation then the implementation
+ * can choose to defer the authenticity checks to that point.
+ *
+ * \param[in] image_id            The identifier of the image to install
+ * \param[out] dependency_uuid    If PSA_ERROR_DEPENDENCY_NEEDED is returned,
+ *                                this parameter is filled with dependency
+ *                                information
+ * \param[out] dependency_version If PSA_ERROR_DEPENDENCY_NEEDED is returned,
+ *                                this parameter is filled with the minimum
+ *                                required version for the dependency
+ *
+ * \return A status indicating the success/failure of the operation
+ *
+ * \retval PSA_SUCCESS                     The image was successfully
+ *                                         installed. The platform does not
+ *                                         require a reboot.
+ * \retval PSA_SUCCESS_REBOOT              A system reboot is needed to finish
+ *                                         installation.
+ * \retval PSA_ERROR_INVALID_ARGUMENT      Bad input parameter
+ * \retval PSA_ERROR_INVALID_SIGNATURE     The signature is incorrect
+ * \retval PSA_ERROR_GENERAL_ERROR         A fatal error occurred
+ * \retval PSA_ERROR_DEPENDENCY_NEEDED     A different image requires
+ *                                         installation first
+ * \retval PSA_ERROR_STORAGE_FAILURE       Some persistent storage could not be
+ *                                         read or written by the
+ *                                         implementation
+ */
+psa_status_t psa_fwu_install(psa_image_id_t image_id,
+                             psa_image_id_t *dependency_uuid,
+                             psa_image_version_t *dependency_version);
+
+/**
+ * \brief Aborts an ongoing installation and erases the staging area of the
+ *        image.
+ *
+ * \param[in] image_id      The identifier of the image to abort installation
+ *
+ * \return A status indicating the success/failure of the operation
+ *
+ * \retval PSA_SUCCESS                    Installation of the provided image_id
+ *                                        has been aborted
+ * \retval PSA_ERROR_INVALID_ARGUMENT     No image with the provided image_id
+ *                                        is currently being installed
+ * \retval PSA_ERROR_NOT_PERMITTED        The caller is not authorized to
+ *                                        abort an installation
+ */
+psa_status_t psa_fwu_abort(psa_image_id_t image_id);
+
+/**
+ * \brief Returns information for an image of a particular image_id.
+ *
+ * \param[in] image_id         The image_id of the image to query
+ *
+ * \param[out] info            Output parameter for image information
+ *                             related to the image_id
+ *
+ * \return A status indicating the success/failure of the operation
+ *
+ * \retval PSA_SUCCESS                     Image information has been returned
+ * \retval PSA_ERROR_NOT_PERMITTED         The caller is not authorized to
+ *                                         access platform version information
+ */
+psa_status_t psa_fwu_query(psa_image_id_t image_id,
+                           psa_image_info_t *info);
+
+/**
+ * \brief Requests the platform to reboot. On success, the platform initiates
+ *        a reboot, and might not return to the caller.
+ *
+ * \return A status indicating the success/failure of the operation
+ *
+ * \retval PSA_SUCCESS                   The platform will reboot soon
+ * \retval PSA_ERROR_NOT_PERMITTED       The caller is not authorized to
+ *                                       reboot the platform
+ */
+psa_status_t psa_fwu_request_reboot(void);
+
+/**
+ * \brief Indicates to the implementation that the upgrade was successful.
+ *
+ * \return A status indicating the success/failure of the operation
+ *
+ * \retval PSA_SUCCESS                  The image and its dependencies have
+ *                                      transitioned into a PSA_IMAGE_INSTALLED
+ *                                      state
+ * \retval PSA_ERROR_NOT_SUPPORTED      The implementation does not support a
+ *                                      PSA_IMAGE_PENDING_INSTALL state
+ * \retval PSA_ERROR_NOT_PERMITTED      The caller is not permitted to make
+ *                                      this call
+ */
+psa_status_t psa_fwu_accept(void);
+
+/**
+ * \brief Stores a manifest object and associates it with a particular image ID.
+ *
+ * \param[in] image_id            The identifier of the image
+ *
+ * \param[in] manifest            A pointer to a buffer containing a manifest
+ *                                object
+ *
+ * \param[in] manifest_size       The size of the manifest parameter
+ *
+ * \param[in] manifest_dependency Output parameter containing the hash of a
+ *                                required manifest when
+ *                                PSA_ERROR_DEPENDENCY_NEEDED is returned
+ *
+ * \return A status indicating the success/failure of the operation
+ *
+ * \retval PSA_SUCCESS                     The manifest is persisted
+ * \retval PSA_ERROR_NOT_PERMITTED         The manifest is too old to be
+ *                                         installed
+ * \retval PSA_ERROR_WRONG_DEVICE          The manifest is not intended for this
+ *                                         device
+ * \retval PSA_ERROR_INVALID_SIGNATURE     The manifest signature is not valid
+ * \retval PSA_ERROR_DEPENDENCY_NEEDED     A different manifest is needed
+ * \retval PSA_ERROR_INVALID_ARGUMENT      Parameter size is 0 or a pointer
+ *                                         parameter is NULL
+ * \retval PSA_ERROR_COMMUNICATION_FAILURE The system could not communicate with
+ *                                         the installer
+ * \retval PSA_ERROR_NOT_SUPPORTED         This function is not implemented
+ * \retval PSA_ERROR_CURRENTLY_INSTALLING  An existing manifest for image ID is
+ *                                         currently being installed and is
+ *                                         locked from writing
+ * \retval PSA_ERROR_GENERIC_ERROR         A fatal error occurred
+ */
+psa_status_t psa_fwu_set_manifest(psa_image_id_t image_id,
+                                  const void *manifest,
+                                  size_t manifest_size,
+                                  psa_hash_t *manifest_dependency);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* PSA_UPDATE_H */