Profiler: Add profiling cases for PSA client API

In SPE, the secure prof case is triggered by secure_client_partition.

The implementation of profiler data collection is based on Data
Watchpoint and Trace (DWT) unit.

Signed-off-by: Jianliang Shen <jianliang.shen@arm.com>
Change-Id: I546b7dc0a34570cc0e6829585d93dc0b50c20d30
diff --git a/profiling/export/platform/tfm_hal_dwt_prof.c b/profiling/export/platform/tfm_hal_dwt_prof.c
new file mode 100644
index 0000000..4f81100
--- /dev/null
+++ b/profiling/export/platform/tfm_hal_dwt_prof.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "cmsis.h"
+
+/* Initialize the timer/cycle counter hardware for profiling */
+void prof_hal_init(void)
+{
+    CoreDebug->DEMCR = CoreDebug_DEMCR_TRCENA_Msk; /* Enable DWT. */
+    DWT->CTRL        = DWT_CTRL_CYCCNTENA_Msk;     /* Enable CYCCNT. */
+    DWT->CYCCNT      = 0x0;                        /* Reset the processor cycle counter. */
+}
+
+/* Interface for retrieving the timer/cycle count */
+uint32_t prof_hal_get_count(void)
+{
+    return (uint32_t)DWT->CYCCNT;
+}
diff --git a/profiling/profiling_cases/config.cmake b/profiling/profiling_cases/config.cmake
new file mode 100644
index 0000000..8ab125b
--- /dev/null
+++ b/profiling/profiling_cases/config.cmake
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+################################ Profiling configs #############################
+
+# Profiling PSA Client API specific variables
+set(PROF_PSA_CLIENT_API_SP_PATH "${TFM_PROF_PATH}/profiling_cases/prof_psa_client_api/partitions")
+set(PROF_PSA_CLIENT_API_CASE_PATH "${TFM_PROF_PATH}/profiling_cases/prof_psa_client_api/cases")
+
+################################ TF-M configs ##################################
+
+# Secure profiling case runs in secure profiling client partition. The Profiling
+# Log api is implemented by secure patition log interfaces in library tfm_sprt.
+# As CMAKE_BUILD_TYPE has already determined the secure partition log level and
+# the normal build type Release uses SILENCE. Here use 'FORCE' to replace it.
+set(TFM_PARTITION_LOG_LEVEL TFM_PARTITION_LOG_LEVEL_INFO CACHE STRING "Set default Secure Partition log level as INFO level" FORCE)
+
+# Out-of-tree partition configurations
+list(APPEND TFM_EXTRA_PARTITION_PATHS
+    ${PROF_PSA_CLIENT_API_SP_PATH}/prof_server_partition
+    ${PROF_PSA_CLIENT_API_SP_PATH}/prof_client_partition
+)
+
+list(APPEND TFM_EXTRA_MANIFEST_LIST_FILES
+    ${PROF_PSA_CLIENT_API_SP_PATH}/prof_psa_client_api_manifest_list.yaml
+)
diff --git a/profiling/profiling_cases/prof_psa_client_api/cases/prof_psa_client_api_common.h b/profiling/profiling_cases/prof_psa_client_api/cases/prof_psa_client_api_common.h
new file mode 100644
index 0000000..784b9b5
--- /dev/null
+++ b/profiling/profiling_cases/prof_psa_client_api/cases/prof_psa_client_api_common.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __PROF_PSA_CLIENT_API_COMMON_H__
+#define __PROF_PSA_CLIENT_API_COMMON_H__
+
+#include "tfm_psa_call_pack.h"
+#include "psa/client.h"
+#include "psa_manifest/sid.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TEST_LOOP_CNT               20
+
+#define PSA_API_TOPIC               0
+
+#define CONNECT_CP_START            0
+#define CONNECT_CP_END              1
+#define CALL_CP_START               2
+#define CALL_CP_END                 3
+#define CLOSE_CP_START              5
+#define CLOSE_CP_END                6
+#define STATELESS_CALL_CP_START     7
+#define STATELESS_CALL_CP_END       8
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PROF_PSA_CLIENT_API_COMMON_H__ */
diff --git a/profiling/profiling_cases/prof_psa_client_api/cases/secure/CMakeLists.txt b/profiling/profiling_cases/prof_psa_client_api/cases/secure/CMakeLists.txt
new file mode 100644
index 0000000..7f44aea
--- /dev/null
+++ b/profiling/profiling_cases/prof_psa_client_api/cases/secure/CMakeLists.txt
@@ -0,0 +1,35 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+cmake_policy(SET CMP0079 NEW)
+
+add_library(secure_prof_psa_client_api INTERFACE)
+
+target_sources(secure_prof_psa_client_api
+    INTERFACE
+        secure_prof_psa_client_api.c
+        ${TFM_PROF_PATH}/profiler/profiler.c
+        ${TFM_PROF_PATH}/export/platform/tfm_hal_dwt_prof.c
+)
+
+target_include_directories(secure_prof_psa_client_api
+    INTERFACE
+        ${PROF_PSA_CLIENT_API_CASE_PATH}/secure
+        ${PROF_PSA_CLIENT_API_CASE_PATH}/
+        ${TFM_PROF_PATH}/export
+        ${TFM_PROF_PATH}/profiler
+)
+
+target_link_libraries(secure_prof_psa_client_api
+    INTERFACE
+        tfm_sprt
+)
+
+target_compile_definitions(secure_prof_psa_client_api
+    INTERFACE
+        CONFIG_TFM_ENALBE_PROFILING
+)
diff --git a/profiling/profiling_cases/prof_psa_client_api/cases/secure/secure_prof_psa_client_api.c b/profiling/profiling_cases/prof_psa_client_api/cases/secure/secure_prof_psa_client_api.c
new file mode 100644
index 0000000..3dbbe55
--- /dev/null
+++ b/profiling/profiling_cases/prof_psa_client_api/cases/secure/secure_prof_psa_client_api.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "secure_prof_psa_client_api.h"
+#include "tfm_sp_log.h"
+#include "prof_intf_s.h"
+
+#define PROFILING_AVERAGE_DIFF(psa_api_name, cp_start, cp_end) \
+        LOG_INFFMT("secure %s average is %d CPU cycles\r\n", psa_api_name, \
+                   PROF_DATA_DIFF_AVG(cp_start, PSA_API_TOPIC, cp_end, PSA_API_TOPIC))
+
+void secure_prof_psa_client_api()
+{
+    psa_handle_t handle;
+    psa_status_t status;
+    uint16_t i = 0;
+
+    for (i = 0; i < TEST_LOOP_CNT; i++) {
+        PROF_TIMING_LOG(CONNECT_CP_START, PSA_API_TOPIC);
+        handle = psa_connect(PROFILING_SERVICE_SID, PROFILING_SERVICE_VERSION);
+        PROF_TIMING_LOG(CONNECT_CP_END, PSA_API_TOPIC);
+
+        if (!PSA_HANDLE_IS_VALID(handle)) {
+            LOG_ERRFMT("PSA connect fail!");
+            return;
+        }
+
+        PROF_TIMING_LOG(CALL_CP_START, PSA_API_TOPIC);
+        status = psa_call(handle, PSA_IPC_CALL, NULL, 0, NULL, 0);
+        PROF_TIMING_LOG(CALL_CP_END, PSA_API_TOPIC);
+
+        if (status != PSA_SUCCESS) {
+            LOG_ERRFMT("PSA call fail!");
+            return;
+        }
+
+        PROF_TIMING_LOG(CLOSE_CP_START, PSA_API_TOPIC);
+        psa_close(handle);
+        PROF_TIMING_LOG(CLOSE_CP_END, PSA_API_TOPIC);
+
+        /* Test stateless PSA call interface. */
+        PROF_TIMING_LOG(STATELESS_CALL_CP_START, PSA_API_TOPIC);
+        status = psa_call(PROFILING_STATELESS_SERVICE_HANDLE, PSA_IPC_CALL, NULL, 0, NULL, 0);
+        PROF_TIMING_LOG(STATELESS_CALL_CP_END, PSA_API_TOPIC);
+
+        if (status != PSA_SUCCESS) {
+            LOG_ERRFMT("PSA stateless call fail!");
+            return;
+        }
+    }
+
+    PROFILING_AVERAGE_DIFF("psa_connect", CONNECT_CP_START, CONNECT_CP_END);
+    PROFILING_AVERAGE_DIFF("psa_call", CALL_CP_START, CALL_CP_END);
+    PROFILING_AVERAGE_DIFF("psa_close", CLOSE_CP_START, CLOSE_CP_END);
+    PROFILING_AVERAGE_DIFF("psa_call stateless", STATELESS_CALL_CP_START, STATELESS_CALL_CP_END);
+}
diff --git a/profiling/profiling_cases/prof_psa_client_api/cases/secure/secure_prof_psa_client_api.h b/profiling/profiling_cases/prof_psa_client_api/cases/secure/secure_prof_psa_client_api.h
new file mode 100644
index 0000000..b760df1
--- /dev/null
+++ b/profiling/profiling_cases/prof_psa_client_api/cases/secure/secure_prof_psa_client_api.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+
+#ifndef __SECURE_PROF_PSA_CLIENT_API_H__
+#define __SECURE_PROF_PSA_CLIENT_API_H__
+
+#include "prof_psa_client_api_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void secure_prof_psa_client_api();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SECURE_PROF_PSA_CLIENT_API_H__ */
diff --git a/profiling/profiling_cases/prof_psa_client_api/partitions/prof_client_partition/CMakeLists.txt b/profiling/profiling_cases/prof_psa_client_api/partitions/prof_client_partition/CMakeLists.txt
new file mode 100644
index 0000000..9294706
--- /dev/null
+++ b/profiling/profiling_cases/prof_psa_client_api/partitions/prof_client_partition/CMakeLists.txt
@@ -0,0 +1,57 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+cmake_policy(SET CMP0079 NEW)
+
+############################ Secure profiling case #############################
+
+add_subdirectory(${PROF_PSA_CLIENT_API_CASE_PATH}/secure ${CMAKE_CURRENT_BINARY_DIR}/prof_psa_client_api/cases/secure)
+
+############################ Secure profiling client partition #################
+
+add_library(tfm_app_rot_partition_prof_client_partition STATIC)
+
+target_sources(tfm_app_rot_partition_prof_client_partition
+    PRIVATE
+        prof_client_partition.c
+)
+
+# The generated sources
+target_sources(tfm_app_rot_partition_prof_client_partition
+    PRIVATE
+        ${CMAKE_BINARY_DIR}/generated/secure_fw/partitions/prof_client_partition/auto_generated/intermedia_prof_client_partition.c
+)
+
+target_sources(tfm_partitions
+    INTERFACE
+        ${CMAKE_BINARY_DIR}/generated/secure_fw/partitions/prof_client_partition/auto_generated/load_info_prof_client_partition.c
+)
+
+# Set include directory
+target_include_directories(tfm_app_rot_partition_prof_client_partition
+    PRIVATE
+        ${CMAKE_BINARY_DIR}/generated/secure_fw/partitions/prof_client_partition
+)
+
+target_include_directories(tfm_partitions
+    INTERFACE
+        ${CMAKE_BINARY_DIR}/generated/secure_fw/partitions/prof_client_partition
+)
+
+target_link_libraries(tfm_app_rot_partition_prof_client_partition
+    PUBLIC
+        secure_prof_psa_client_api
+    PRIVATE
+        tfm_sprt
+)
+
+############################ Partition Defs ####################################
+
+target_link_libraries(tfm_partitions
+    INTERFACE
+        tfm_app_rot_partition_prof_client_partition
+)
diff --git a/profiling/profiling_cases/prof_psa_client_api/partitions/prof_client_partition/prof_client_partition.c b/profiling/profiling_cases/prof_psa_client_api/partitions/prof_client_partition/prof_client_partition.c
new file mode 100644
index 0000000..d31f003
--- /dev/null
+++ b/profiling/profiling_cases/prof_psa_client_api/partitions/prof_client_partition/prof_client_partition.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "secure_prof_psa_client_api.h"
+#include "psa/service.h"
+#include "psa_manifest/prof_client_partition.h"
+
+int32_t prof_client_init(void)
+{
+    secure_prof_psa_client_api();
+    return 0;
+}
+
+psa_status_t secure_client_dummy_sfn(const psa_msg_t *msg)
+{
+    /* Not expected to be called by anyone */
+    psa_panic();
+
+    return 0;
+}
diff --git a/profiling/profiling_cases/prof_psa_client_api/partitions/prof_client_partition/prof_client_partition.yaml b/profiling/profiling_cases/prof_psa_client_api/partitions/prof_client_partition/prof_client_partition.yaml
new file mode 100644
index 0000000..9ca2120
--- /dev/null
+++ b/profiling/profiling_cases/prof_psa_client_api/partitions/prof_client_partition/prof_client_partition.yaml
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+{
+  "psa_framework_version": 1.1,
+  "name": "PROFILING_CLIENT_PARTITION",
+  "type": "PSA-ROT",
+  "model": "SFN",
+  "priority": "LOW",
+  "entry_init": "prof_client_init",
+  "stack_size": "0x0400",
+  "services": [
+    {
+      "name": "SECURE_CLIENT_DUMMY",
+      "sid": "0x0000F150",
+      "connection_based": true,
+      "non_secure_clients": false,
+      "version": 1,
+      "version_policy": "STRICT"
+    }
+  ],
+  "dependencies": [
+    "PROFILING_SERVICE",
+    "PROFILING_STATELESS_SERVICE",
+  ]
+}
diff --git a/profiling/profiling_cases/prof_psa_client_api/partitions/prof_psa_client_api_manifest_list.yaml b/profiling/profiling_cases/prof_psa_client_api/partitions/prof_psa_client_api_manifest_list.yaml
index a5f0054..c11c581 100644
--- a/profiling/profiling_cases/prof_psa_client_api/partitions/prof_psa_client_api_manifest_list.yaml
+++ b/profiling/profiling_cases/prof_psa_client_api/partitions/prof_psa_client_api_manifest_list.yaml
@@ -17,5 +17,15 @@
          ]
       }
     },
+    {
+      "description": "Profiling Client Partition",
+      "manifest": "prof_client_partition/prof_client_partition.yaml",
+      "output_path": "secure_fw/partitions/prof_client_partition",
+      "linker_pattern": {
+        "library_list": [
+           "*tfm_*prof_client_partition.*"
+         ]
+      }
+    },
   ]
 }