Test: Add Secure Client 2 test partition

Adds the Secure Client 2 test partition, which provides a service to
call test functions by ID within the execution context of this
partition.

This makes it possible to test scenarios involving multiple partitions.

Change-Id: I6183fc1d0f9d6f23c01e638ce9589afdb919eb47
Signed-off-by: Jamie Fox <jamie.fox@arm.com>
diff --git a/test/test_services/CMakeLists.inc b/test/test_services/CMakeLists.inc
index b020a6b..8e9a370 100644
--- a/test/test_services/CMakeLists.inc
+++ b/test/test_services/CMakeLists.inc
@@ -48,7 +48,9 @@
 if (NOT DEFINED TFM_PARTITION_TEST_SECURE_SERVICES)
 	message(FATAL_ERROR "Incomplete build configuration: TFM_PARTITION_TEST_SECURE_SERVICES is undefined. ")
 elseif (TFM_PARTITION_TEST_SECURE_SERVICES)
-	list(APPEND ALL_SRC_C_S "${CORE_TEST_DIR}/tfm_secure_client_service/tfm_secure_client_service.c")
+	list(APPEND ALL_SRC_C_S "${CORE_TEST_DIR}/tfm_secure_client_service/tfm_secure_client_service.c"
+		"${CORE_TEST_DIR}/tfm_secure_client_2/tfm_secure_client_2.c"
+		"${CORE_TEST_DIR}/tfm_secure_client_2/tfm_secure_client_2_api.c")
 
 	list(APPEND ALL_SRC_C_NS "${CORE_TEST_DIR}/tfm_secure_client_service/tfm_secure_client_service_api.c")
 endif()
diff --git a/test/test_services/tfm_secure_client_2/psa_manifest/tfm_secure_client_2.h b/test/test_services/tfm_secure_client_2/psa_manifest/tfm_secure_client_2.h
new file mode 100644
index 0000000..a8b1f2f
--- /dev/null
+++ b/test/test_services/tfm_secure_client_2/psa_manifest/tfm_secure_client_2.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/*********** WARNING: This is an auto-generated file. Do not edit! ***********/
+
+#ifndef __PSA_MANIFEST_TFM_SECURE_CLIENT_2_H__
+#define __PSA_MANIFEST_TFM_SECURE_CLIENT_2_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TFM_SECURE_CLIENT_2_SIGNAL                              (1U << (0 + 4))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PSA_MANIFEST_TFM_SECURE_CLIENT_2_H__ */
diff --git a/test/test_services/tfm_secure_client_2/tfm_secure_client_2.c b/test/test_services/tfm_secure_client_2/tfm_secure_client_2.c
new file mode 100644
index 0000000..48323d3
--- /dev/null
+++ b/test/test_services/tfm_secure_client_2/tfm_secure_client_2.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifdef TFM_PSA_API
+#include "psa/service.h"
+#include "psa_manifest/tfm_secure_client_2.h"
+#else
+#include "psa/client.h"
+#endif
+
+static psa_status_t secure_client_2_dispatch(int32_t id, const void *arg,
+                                             size_t arg_len)
+{
+    switch (id) {
+    default:
+        return PSA_ERROR_PROGRAMMER_ERROR;
+    }
+}
+
+#ifdef TFM_PSA_API
+#define SECURE_CLIENT_2_MAX_ARG_LEN 8U
+
+void tfm_secure_client_2_init(void)
+{
+    psa_msg_t msg;
+    size_t len;
+    char arg[SECURE_CLIENT_2_MAX_ARG_LEN] __attribute__((__aligned__(8)));
+
+    while (1) {
+        (void)psa_wait(TFM_SECURE_CLIENT_2_SIGNAL, PSA_BLOCK);
+        if (psa_get(TFM_SECURE_CLIENT_2_SIGNAL, &msg) != PSA_SUCCESS) {
+            continue;
+        }
+        switch (msg.type) {
+        case PSA_IPC_CONNECT:
+        case PSA_IPC_DISCONNECT:
+            psa_reply(msg.handle, PSA_SUCCESS);
+            break;
+        default:
+            len = psa_read(msg.handle, 0, arg, SECURE_CLIENT_2_MAX_ARG_LEN);
+            psa_reply(msg.handle, secure_client_2_dispatch(msg.type, arg, len));
+            break;
+        }
+    }
+}
+#else /* TFM_PSA_API */
+psa_status_t tfm_secure_client_2_init(void)
+{
+    return PSA_SUCCESS;
+}
+
+psa_status_t tfm_secure_client_2_call(psa_invec *in_vec, size_t in_len,
+                                      psa_outvec *out_vec, size_t out_len)
+{
+    int32_t id;
+
+    (void)out_vec;
+
+    if (in_len != 2 || out_len != 0 || in_vec[0].len != sizeof(id)) {
+        return PSA_ERROR_PROGRAMMER_ERROR;
+    }
+
+    id = *((int32_t *)in_vec[0].base);
+
+    return secure_client_2_dispatch(id, in_vec[1].base, in_vec[1].len);
+}
+#endif /* TFM_PSA_API */
diff --git a/test/test_services/tfm_secure_client_2/tfm_secure_client_2.yaml b/test/test_services/tfm_secure_client_2/tfm_secure_client_2.yaml
new file mode 100644
index 0000000..98020b7
--- /dev/null
+++ b/test/test_services/tfm_secure_client_2/tfm_secure_client_2.yaml
@@ -0,0 +1,40 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+{
+  "psa_framework_version": 1.0,
+  "name": "TFM_SP_SECURE_CLIENT_2",
+  "type": "APPLICATION-ROT",
+  "priority": "NORMAL",
+  "entry_point": "tfm_secure_client_2_init",
+  "stack_size": "0x180",
+  "secure_functions": [
+    {
+      "name": "TFM_SECURE_CLIENT_2_CALL",
+      "signal": "TFM_SECURE_CLIENT_2_CALL",
+      "non_secure_clients": false,
+      "version": 1,
+      "version_policy": "STRICT"
+    },
+  ],
+  "services": [
+    {
+      "name": "TFM_SECURE_CLIENT_2",
+      "sid": "0x0000F0E0",
+      "non_secure_clients": false,
+      "version": 1,
+      "version_policy": "STRICT"
+    }
+  ],
+  "dependencies": [
+  ],
+  "linker_pattern": {
+    "object_list": [
+      "*tfm_secure_client_2.*"
+    ]
+  }
+}
diff --git a/test/test_services/tfm_secure_client_2/tfm_secure_client_2_api.c b/test/test_services/tfm_secure_client_2/tfm_secure_client_2_api.c
new file mode 100644
index 0000000..b5beb9a
--- /dev/null
+++ b/test/test_services/tfm_secure_client_2/tfm_secure_client_2_api.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "tfm_secure_client_2_api.h"
+#include "psa/client.h"
+
+#ifdef TFM_PSA_API
+#include "psa_manifest/sid.h"
+#else
+#include "tfm_veneers.h"
+#endif
+
+__attribute__((section("SFN")))
+psa_status_t tfm_secure_client_2_call_test(int32_t id, const void *arg,
+                                           size_t arg_len)
+{
+#ifdef TFM_PSA_API
+    psa_handle_t handle;
+    psa_status_t status;
+    psa_invec in_vec[] = {
+        { .base = arg, .len = arg_len },
+    };
+
+    handle = psa_connect(TFM_SECURE_CLIENT_2_SID, TFM_SECURE_CLIENT_2_VERSION);
+    if (!PSA_HANDLE_IS_VALID(handle)) {
+        return PSA_ERROR_GENERIC_ERROR;
+    }
+
+    /* Pass the ID through the type parameter of psa_call() */
+    status = psa_call(handle, id, in_vec, 1, NULL, 0);
+    psa_close(handle);
+
+    return status;
+#else
+    /* Pack the ID in the invec */
+    psa_invec in_vec[] = {
+        { .base = &id, .len = sizeof(id) },
+        { .base = arg, .len = arg_len },
+    };
+
+    return tfm_tfm_secure_client_2_call_veneer(in_vec, 2, NULL, 0);
+#endif
+}
diff --git a/test/test_services/tfm_secure_client_2/tfm_secure_client_2_api.h b/test/test_services/tfm_secure_client_2/tfm_secure_client_2_api.h
new file mode 100644
index 0000000..b155026
--- /dev/null
+++ b/test/test_services/tfm_secure_client_2/tfm_secure_client_2_api.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_SECURE_CLIENT_2_API_H__
+#define __TFM_SECURE_CLIENT_2_API_H__
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "psa/error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Calls the test function with the supplied ID within the execution
+ *        context of the Secure Client 2 partition and returns the resulting
+ *        status.
+ *
+ * \param[in] id       The ID of the test function
+ * \param[in] arg      Pointer to argument to pass to test function
+ * \param[in] arg_len  Length of argument in bytes
+ *
+ * \return Returns error code as specified in \ref psa_status_t
+ */
+psa_status_t tfm_secure_client_2_call_test(int32_t id, const void *arg,
+                                           size_t arg_len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_SECURE_CLIENT_2_API_H__ */
diff --git a/test/test_services/tfm_secure_client_service/tfm_test_client_service.yaml b/test/test_services/tfm_secure_client_service/tfm_test_client_service.yaml
index b47e31f..24bbdc2 100644
--- a/test/test_services/tfm_secure_client_service/tfm_test_client_service.yaml
+++ b/test/test_services/tfm_secure_client_service/tfm_test_client_service.yaml
@@ -37,6 +37,7 @@
     }
   ],
   "dependencies": [
+    "TFM_SECURE_CLIENT_2",
     "TFM_CRYPTO",
     "TFM_SST_SET",
     "TFM_SST_GET",