Core: PSA APIs alignment

Update PSA Client and Secure Partition APIs and some related files:
 - Add psa_panic() to indicate an internal fault in a secure partition.
 - Introduce a message type parameter to the psa_call() function which
   is delivered as part of the psa_msg_t data to the RoT Service.
 - Change 'minor version' to 'version'.
 - Add PSA_HANDLE_IS_VALID() and PSA_HANDLE_TO_ERROR() macros.
 - Move the definition of PSA_MAX_IOVEC and PSA_IPC_CALL from
   psa/service.h to psa/client.h.
 - Change the error code returned by psa_get() when the message could
   not be delivered. It now returns PSA_ERROR_DOES_NOT_EXIST.

Change-Id: Ia717f591c80484699f4f491d1ed6dbc4fd7c050f
Signed-off-by: Summer Qin <summer.qin@arm.com>
diff --git a/interface/include/psa/client.h b/interface/include/psa/client.h
index 33e3f2d..d040834 100644
--- a/interface/include/psa/client.h
+++ b/interface/include/psa/client.h
@@ -19,17 +19,44 @@
 
 /*********************** PSA Client Macros and Types *************************/
 
-#define PSA_FRAMEWORK_VERSION  (0x0100)
+/**
+ * The version of the PSA Framework API that is being used to build the calling
+ * firmware.
+ */
+#define PSA_FRAMEWORK_VERSION       (0x0100u)
 
-#define PSA_VERSION_NONE       (0)
+/**
+ * Return value from psa_version() if the requested RoT Service is not present
+ * in the system.
+ */
+#define PSA_VERSION_NONE            (0u)
 
-/* PSA response types */
-#define PSA_CONNECTION_REFUSED (INT32_MIN + 1)
-#define PSA_CONNECTION_BUSY    (INT32_MIN + 2)
-#define PSA_DROP_CONNECTION    (INT32_MIN)
+/**
+ * The zero-value null handle can be assigned to variables used in clients and
+ * RoT Services, indicating that there is no current connection or message.
+ */
+#define PSA_NULL_HANDLE             ((psa_handle_t)0)
 
-/* PSA message handles */
-#define PSA_NULL_HANDLE        ((psa_handle_t)0)
+/**
+ * Tests whether a handle value returned by psa_connect() is valid.
+ */
+#define PSA_HANDLE_IS_VALID(handle) ((psa_handle_t)(handle) > 0)
+
+/**
+ * Converts the handle value returned from a failed call psa_connect() into
+ * an error code.
+ */
+#define PSA_HANDLE_TO_ERROR(handle) ((psa_status_t)(handle))
+
+/**
+ * Maximum number of input and output vectors for a request to psa_call().
+ */
+#define PSA_MAX_IOVEC               (4u)
+
+/**
+ * An IPC message type that indicates a generic client request.
+ */
+#define PSA_IPC_CALL                (0)
 
 typedef int32_t psa_handle_t;
 
@@ -64,15 +91,14 @@
 uint32_t psa_framework_version(void);
 
 /**
- * \brief Retrieve the minor version of an RoT Service or indicate that it is
- *        not present on this system.
+ * \brief Retrieve the version of an RoT Service or indicate that it is not
+ *        present on this system.
  *
  * \param[in] sid               ID of the RoT Service to query.
  *
  * \retval PSA_VERSION_NONE     The RoT Service is not implemented, or the
  *                              caller is not permitted to access the service.
- * \retval > 0                  The minor version of the implemented RoT
- *                              Service.
+ * \retval > 0                  The version of the implemented RoT Service.
  */
 uint32_t psa_version(uint32_t sid);
 
@@ -80,23 +106,28 @@
  * \brief Connect to an RoT Service by its SID.
  *
  * \param[in] sid               ID of the RoT Service to connect to.
- * \param[in] minor_version     Requested version of the RoT Service.
+ * \param[in] version           Requested version of the RoT Service.
  *
  * \retval > 0                  A handle for the connection.
- * \retval PSA_CONNECTION_REFUSED The SPM or RoT Service has refused the
+ * \retval PSA_ERROR_CONNECTION_REFUSED The SPM or RoT Service has refused the
  *                              connection.
- * \retval PSA_CONNECTION_BUSY  The SPM or RoT Service cannot make the
+ * \retval PSA_ERROR_CONNECTION_BUSY The SPM or RoT Service cannot make the
  *                              connection at the moment.
- * \retval "Does not return"    The RoT Service ID and version are not
- *                              supported, or the caller is not permitted to
- *                              access the service.
+ * \retval "PROGRAMMER ERROR"   The call is a PROGRAMMER ERROR if one or more
+ *                              of the following are true:
+ * \arg                           The RoT Service ID is not present.
+ * \arg                           The RoT Service version is not supported.
+ * \arg                           The caller is not allowed to access the RoT
+ *                                service.
  */
-psa_handle_t psa_connect(uint32_t sid, uint32_t minor_version);
+psa_handle_t psa_connect(uint32_t sid, uint32_t version);
 
 /**
  * \brief Call an RoT Service on an established connection.
  *
  * \param[in] handle            A handle to an established connection.
+ * \param[in] type              The reuqest type.
+ *                              Must be zero( \ ref PSA_IPC_CALL) or positive.
  * \param[in] in_vec            Array of input \ref psa_invec structures.
  * \param[in] in_len            Number of input \ref psa_invec structures.
  * \param[in/out] out_vec       Array of output \ref psa_outvec structures.
@@ -104,19 +135,18 @@
  *
  * \retval >=0                  RoT Service-specific status value.
  * \retval <0                   RoT Service-specific error code.
- * \retval PSA_DROP_CONNECTION  The connection has been dropped by the RoT
- *                              Service. This indicates that either this or
- *                              a previous message was invalid.
- * \retval "Does not return"    The call is invalid, one or more of the
- *                              following are true:
+ * \retval PSA_ERROR_PROGRAMMER_ERROR The connection has been terminated by the
+ *                              RoT Service. The call is a PROGRAMMER ERROR if
+ *                              one or more of the following are true:
  * \arg                           An invalid handle was passed.
  * \arg                           The connection is already handling a request.
+ * \arg                           type < 0.
  * \arg                           An invalid memory reference was provided.
  * \arg                           in_len + out_len > PSA_MAX_IOVEC.
  * \arg                           The message is unrecognized by the RoT
  *                                Service or incorrectly formatted.
  */
-psa_status_t psa_call(psa_handle_t handle,
+psa_status_t psa_call(psa_handle_t handle, int32_t type,
                       const psa_invec *in_vec,
                       size_t in_len,
                       psa_outvec *out_vec,
@@ -129,11 +159,12 @@
  *                              null handle.
  *
  * \retval void                 Success.
- * \retval "Does not return"    The call is invalid, one or more of the
- *                              following are true:
+ * \retval "PROGRAMMER ERROR"   The call is a PROGRAMMER ERROR if one or more
+ *                              of the following are true:
  * \arg                           An invalid handle was provided that is not
  *                                the null handle.
- * \arg                           The connection is handling a request.
+ * \arg                           The connection is currently handling a
+ *                                request.
  */
 void psa_close(psa_handle_t handle);
 
diff --git a/interface/include/psa/service.h b/interface/include/psa/service.h
index 9af3f67..94eb082 100644
--- a/interface/include/psa/service.h
+++ b/interface/include/psa/service.h
@@ -20,26 +20,31 @@
 
 /********************** PSA Secure Partition Macros and Types ****************/
 
-/* PSA wait timeouts */
+/**
+ * A timeout value that requests a polling wait operation.
+ */
 #define PSA_POLL                (0x00000000u)
+
+/**
+ * A timeout value that requests a blocking wait operation.
+ */
 #define PSA_BLOCK               (0x80000000u)
 
-/* A mask value that includes all Secure Partition signals */
-#define PSA_WAIT_ANY            (~0u)
+/**
+ * A mask value that includes all Secure Partition signals.
+ */
+#define PSA_WAIT_ANY            (0xFFFFFFFFu)
 
-/* Doorbell signal */
+/**
+ * The signal number for the Secure Partition doorbell.
+ */
 #define PSA_DOORBELL            (0x00000008u)
 
 /* PSA message types */
-#define PSA_IPC_CONNECT         (1)
-#define PSA_IPC_CALL            (2)
-#define PSA_IPC_DISCONNECT      (3)
-
-/* Maximum number of input and output vectors */
-#define PSA_MAX_IOVEC           (4)
-
-/* Return code from psa_get() */
-#define PSA_ERR_NOMSG           (INT32_MIN + 3)
+/* An IPC message type that indicates a new connection. */
+#define PSA_IPC_CONNECT         (-1)
+/* An IPC message type that indicates the end of a connection. */
+#define PSA_IPC_DISCONNECT      (-2)
 
 /* Store a set of one or more Secure Partition signals */
 typedef uint32_t psa_signal_t;
@@ -48,9 +53,9 @@
  * Describe a message received by an RoT Service after calling \ref psa_get().
  */
 typedef struct psa_msg_t {
-    uint32_t type;              /* One of the following values:
+    int32_t type;              /* One of the following values:
                                  * \ref PSA_IPC_CONNECT
-                                 * \ref PSA_IPC_CALL
+                                 * >= 0
                                  * \ref PSA_IPC_DISCONNECT
                                  */
     psa_handle_t handle;        /* A reference generated by the SPM to the
@@ -97,8 +102,8 @@
  *
  * \retval PSA_SUCCESS          Success, *msg will contain the delivered
  *                              message.
- * \retval PSA_ERR_NOMSG        Message could not be delivered.
- * \retval "Does not return"    The call is invalid because one or more of the
+ * \retval PSA_ERROR_DOES_NOT_EXIST Message could not be delivered.
+ * \retval "PROGRAMMER ERROR"   The call is invalid because one or more of the
  *                              following are true:
  * \arg                           signal has more than a single bit set.
  * \arg                           signal does not correspond to an RoT Service.
@@ -118,7 +123,7 @@
  * \retval void                 Success, rhandle will be provided with all
  *                              subsequent messages delivered on this
  *                              connection.
- * \retval "Does not return"    msg_handle is invalid.
+ * \retval "PROGRAMMER ERROR"   msg_handle is invalid.
  */
 void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle);
 
@@ -137,7 +142,7 @@
  * \retval >0                   Number of bytes copied.
  * \retval 0                    There was no remaining data in this input
  *                              vector.
- * \retval "Does not return"    The call is invalid, one or more of the
+ * \retval "PROGRAMMER ERROR"   The call is invalid, one or more of the
  *                              following are true:
  * \arg                           msg_handle is invalid.
  * \arg                           msg_handle does not refer to a
@@ -162,11 +167,11 @@
  * \retval >0                   Number of bytes skipped.
  * \retval 0                    There was no remaining data in this input
  *                              vector.
- * \retval "Does not return"    The call is invalid, one or more of the
+ * \retval "PROGRAMMER ERROR"   The call is invalid, one or more of the
  *                              following are true:
  * \arg                           msg_handle is invalid.
- * \arg                           msg_handle does not refer to a
- *                                \ref PSA_IPC_CALL message.
+ * \arg                           msg_handle does not refer to a request
+ *                                message.
  * \arg                           invec_idx is equal to or greater than
  *                                \ref PSA_MAX_IOVEC.
  */
@@ -183,11 +188,11 @@
  *                              vector.
  *
  * \retval void                 Success
- * \retval "Does not return"    The call is invalid, one or more of the
+ * \retval "PROGRAMMER ERROR"   The call is invalid, one or more of the
  *                              following are true:
  * \arg                           msg_handle is invalid.
- * \arg                           msg_handle does not refer to a
- *                                \ref PSA_IPC_CALL message.
+ * \arg                           msg_handle does not refer to a request
+ *                                message.
  * \arg                           outvec_idx is equal to or greater than
  *                                \ref PSA_MAX_IOVEC.
  * \arg                           The memory reference for buffer is invalid.
@@ -205,7 +210,7 @@
  *                              client.
  *
  * \retval void                 Success.
- * \retval "Does not return"    The call is invalid, one or more of the
+ * \retval "PROGRAMMER ERROR"   The call is invalid, one or more of the
  *                              following are true:
  * \arg                         msg_handle is invalid.
  * \arg                         An invalid status code is specified for the
@@ -219,7 +224,7 @@
  * \param[in] partition_id      Secure Partition ID of the target partition.
  *
  * \retval void                 Success.
- * \retval "Does not return"    partition_id does not correspond to a Secure
+ * \retval "PROGRAMMER ERROR"   partition_id does not correspond to a Secure
  *                              Partition.
  */
 void psa_notify(int32_t partition_id);
@@ -228,7 +233,7 @@
  * \brief Clear the PSA_DOORBELL signal.
  *
  * \retval void                 Success.
- * \retval "Does not return"    The Secure Partition's doorbell signal is not
+ * \retval "PROGRAMMER ERROR"   The Secure Partition's doorbell signal is not
  *                              currently asserted.
  */
 void psa_clear(void);
@@ -239,7 +244,7 @@
  * \param[in] irq_signal        The interrupt signal that has been processed.
  *
  * \retval void                 Success.
- * \retval "Does not return"    The call is invalid, one or more of the
+ * \retval "PROGRAMMER ERROR"   The call is invalid, one or more of the
  *                              following are true:
  * \arg                           irq_signal is not an interrupt signal.
  * \arg                           irq_signal indicates more than one signal.
@@ -247,6 +252,14 @@
  */
 void psa_eoi(psa_signal_t irq_signal);
 
+/**
+ * \brief Terminate execution within the calling Secure Partition and will not
+ *        return.
+ *
+ * \retval "Does not return"
+ */
+void psa_panic(void);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/interface/include/tfm_api.h b/interface/include/tfm_api.h
index 5a56ec7..650fe52 100644
--- a/interface/include/tfm_api.h
+++ b/interface/include/tfm_api.h
@@ -35,9 +35,6 @@
  */
 #define TFM_CLIENT_ID_IS_NS(client_id) ((client_id)<0)
 
-/* Maximum number of input and output vectors */
-#define PSA_MAX_IOVEC    (4)
-
 /* The mask used for timeout values */
 #define PSA_TIMEOUT_MASK        PSA_BLOCK
 
@@ -102,22 +99,24 @@
  * \brief Connect to secure function
  *
  * \param[in]  sid              ID of secure service
- * \param[in]  minor_version    Minor version of SF requested by client
+ * \param[in]  version          Version of SF requested by client
  *
  * \return Returns handle to connection
  */
-psa_handle_t tfm_psa_connect_veneer(uint32_t sid, uint32_t minor_version);
+psa_handle_t tfm_psa_connect_veneer(uint32_t sid, uint32_t version);
 
 /**
  * \brief Call a secure function referenced by a connection handle
  *
  * \param[in]  handle   Handle to connection
+ * \param[in]  type     The reuqest type. Must be zero(PSA_IPC_CALL) or
+ *                      positive.
  * \param[in]  in_vecs  invec containing pointer/count of input vectors
  * \param[in]  out_vecs invec containing pointer/count of output vectors
  *
  * \return Returns \ref psa_status_t status code
  */
-psa_status_t tfm_psa_call_veneer(psa_handle_t handle,
+psa_status_t tfm_psa_call_veneer(psa_handle_t handle, int32_t type,
                                  const psa_invec *in_vecs,
                                  const psa_invec *out_vecs);
 
diff --git a/interface/src/tfm_crypto_api.c b/interface/src/tfm_crypto_api.c
index 400e123..554cdb5 100644
--- a/interface/src/tfm_crypto_api.c
+++ b/interface/src/tfm_crypto_api.c
@@ -32,12 +32,12 @@
 #define PSA_CLOSE() psa_close(ipc_handle)
 
 #define API_DISPATCH(sfn_name, sfn_id)                          \
-    psa_call(ipc_handle, /*PSA_IPC_CALL,*/                      \
+    psa_call(ipc_handle, PSA_IPC_CALL,                          \
         in_vec, ARRAY_SIZE(in_vec),                             \
         out_vec, ARRAY_SIZE(out_vec))
 
 #define API_DISPATCH_NO_OUTVEC(sfn_name, sfn_id)                \
-    psa_call(ipc_handle, /*PSA_IPC_CALL,*/                      \
+    psa_call(ipc_handle, PSA_IPC_CALL,                          \
         in_vec, ARRAY_SIZE(in_vec),                             \
         (psa_outvec *)NULL, 0)
 #else
@@ -1061,7 +1061,7 @@
     if (additional_data == NULL) {
         in_len--;
     }
-    status = psa_call(ipc_handle, in_vec, in_len,
+    status = psa_call(ipc_handle, PSA_IPC_CALL, in_vec, in_len,
                       out_vec, ARRAY_SIZE(out_vec));
 #else
     status = API_DISPATCH(tfm_crypto_aead_encrypt,
@@ -1131,7 +1131,7 @@
     if (additional_data == NULL) {
         in_len--;
     }
-    status = psa_call(ipc_handle, in_vec, in_len,
+    status = psa_call(ipc_handle, PSA_IPC_CALL, in_vec, in_len,
                       out_vec, ARRAY_SIZE(out_vec));
 #else
     status = API_DISPATCH(tfm_crypto_aead_decrypt,
@@ -1260,7 +1260,7 @@
     if (salt == NULL) {
         in_len--;
     }
-    status = psa_call(ipc_handle, in_vec, in_len,
+    status = psa_call(ipc_handle, PSA_IPC_CALL, in_vec, in_len,
                       out_vec, ARRAY_SIZE(out_vec));
 #else
     status = API_DISPATCH(tfm_crypto_asymmetric_encrypt,
@@ -1317,7 +1317,7 @@
     if (salt == NULL) {
         in_len--;
     }
-    status = psa_call(ipc_handle, in_vec, in_len,
+    status = psa_call(ipc_handle, PSA_IPC_CALL, in_vec, in_len,
                       out_vec, ARRAY_SIZE(out_vec));
 #else
     status = API_DISPATCH(tfm_crypto_asymmetric_decrypt,
@@ -1503,7 +1503,7 @@
             in_len--;
         }
     }
-    status = psa_call(ipc_handle, in_vec, in_len,
+    status = psa_call(ipc_handle, PSA_IPC_CALL, in_vec, in_len,
                       out_vec, ARRAY_SIZE(out_vec));
 #else
     status = API_DISPATCH(tfm_crypto_key_derivation,
@@ -1622,7 +1622,7 @@
         in_len--;
     }
 
-    status = psa_call(ipc_handle, in_vec, in_len, NULL, 0);
+    status = psa_call(ipc_handle, PSA_IPC_CALL, in_vec, in_len, NULL, 0);
 #else
     status = API_DISPATCH_NO_OUTVEC(tfm_crypto_generate_key,
                                     TFM_CRYPTO_GENERATE_KEY);
diff --git a/interface/src/tfm_initial_attestation_api.c b/interface/src/tfm_initial_attestation_api.c
index 0f6377e..1bcce05 100644
--- a/interface/src/tfm_initial_attestation_api.c
+++ b/interface/src/tfm_initial_attestation_api.c
@@ -41,7 +41,7 @@
         return PSA_ATTEST_ERR_GENERAL;
     }
 
-    status = psa_call(handle,
+    status = psa_call(handle, PSA_IPC_CALL,
                       in_vec, IOVEC_LEN(in_vec),
                       out_vec, IOVEC_LEN(out_vec));
     psa_close(handle);
@@ -91,7 +91,7 @@
         return PSA_ATTEST_ERR_GENERAL;
     }
 
-    status = psa_call(handle,
+    status = psa_call(handle, PSA_IPC_CALL,
                       in_vec, IOVEC_LEN(in_vec),
                       out_vec, IOVEC_LEN(out_vec));
     psa_close(handle);
diff --git a/interface/src/tfm_psa_ns_api.c b/interface/src/tfm_psa_ns_api.c
index 1c83084..5fb5de3 100644
--- a/interface/src/tfm_psa_ns_api.c
+++ b/interface/src/tfm_psa_ns_api.c
@@ -31,17 +31,17 @@
                                 0);
 }
 
-psa_handle_t psa_connect(uint32_t sid, uint32_t minor_version)
+psa_handle_t psa_connect(uint32_t sid, uint32_t version)
 {
     return tfm_ns_interface_dispatch(
                                 (veneer_fn)tfm_psa_connect_veneer,
                                 sid,
-                                minor_version,
+                                version,
                                 0,
                                 0);
 }
 
-psa_status_t psa_call(psa_handle_t handle,
+psa_status_t psa_call(psa_handle_t handle, int32_t type,
                       const psa_invec *in_vec,
                       size_t in_len,
                       psa_outvec *out_vec,
@@ -63,9 +63,9 @@
     return tfm_ns_interface_dispatch(
                                 (veneer_fn)tfm_psa_call_veneer,
                                 (uint32_t)handle,
+                                (uint32_t)type,
                                 (uint32_t)&in_vecs,
-                                (uint32_t)&out_vecs,
-                                0);
+                                (uint32_t)&out_vecs);
 }
 
 void psa_close(psa_handle_t handle)
diff --git a/interface/src/tfm_sst_api.c b/interface/src/tfm_sst_api.c
index 2722c67..c7796d0 100644
--- a/interface/src/tfm_sst_api.c
+++ b/interface/src/tfm_sst_api.c
@@ -44,7 +44,7 @@
         return PSA_PS_ERROR_OPERATION_FAILED;
     }
 
-    status = psa_call(handle, in_vec, IOVEC_LEN(in_vec), out_vec,
+    status = psa_call(handle, PSA_IPC_CALL, in_vec, IOVEC_LEN(in_vec), out_vec,
                       IOVEC_LEN(out_vec));
 
     psa_close(handle);
@@ -92,7 +92,7 @@
         return PSA_PS_ERROR_OPERATION_FAILED;
     }
 
-    status = psa_call(handle, in_vec, IOVEC_LEN(in_vec), out_vec,
+    status = psa_call(handle, PSA_IPC_CALL, in_vec, IOVEC_LEN(in_vec), out_vec,
                       IOVEC_LEN(out_vec));
 
     psa_close(handle);
@@ -137,7 +137,7 @@
         return PSA_PS_ERROR_OPERATION_FAILED;
     }
 
-    status = psa_call(handle, in_vec, IOVEC_LEN(in_vec), out_vec,
+    status = psa_call(handle, PSA_IPC_CALL, in_vec, IOVEC_LEN(in_vec), out_vec,
                       IOVEC_LEN(out_vec));
 
     psa_close(handle);
@@ -181,7 +181,7 @@
         return PSA_PS_ERROR_OPERATION_FAILED;
     }
 
-    status = psa_call(handle, in_vec, IOVEC_LEN(in_vec), out_vec,
+    status = psa_call(handle, PSA_IPC_CALL, in_vec, IOVEC_LEN(in_vec), out_vec,
                       IOVEC_LEN(out_vec));
 
     psa_close(handle);
@@ -247,7 +247,7 @@
         return support_flags;
     }
 
-    (void)psa_call(handle, NULL, 0, out_vec, IOVEC_LEN(out_vec));
+    (void)psa_call(handle, PSA_IPC_CALL, NULL, 0, out_vec, IOVEC_LEN(out_vec));
 
     psa_close(handle);
 #else