Build: Split NS and Secure regression tests build

Seperate NS and Secure regressin test builds.

  - TF-M secure build integrates secure regression tests and test
    services via test/secure_regression.
  - Non-secure regression tests are built via test/ns_regression.
  - Pass tf-m-tests test config to TF-M secure build via argument
    CONFIG_TFM_TEST_CONFIG_FILE.
  - Fix issues when no regression test is enabled.

Signed-off-by: David Hu <david.hu@arm.com>
Change-Id: I1e550bf6d6a36a220275743c3312a61f7ae2c78e
diff --git a/tests_reg/utils/regression_flag_parse.cmake b/tests_reg/utils/regression_flag_parse.cmake
new file mode 100644
index 0000000..ee05c45
--- /dev/null
+++ b/tests_reg/utils/regression_flag_parse.cmake
@@ -0,0 +1,59 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Set whether Secure and Non-secure regression tests are selected.
+# If any regression test is selected, set corresponding TFM_S_REG_TEST/TEST_NS_REG_TEST to
+# require TF-M build secure tests and test partitions.
+#
+# cmd_line: the output argument to collect the arguments via command line
+#
+function(parse_regression_flag cmd_line)
+
+    set(TFM_NS_REG_TEST OFF)
+    set(TFM_S_REG_TEST  OFF)
+
+    get_cmake_property(CACHE_VARS CACHE_VARIABLES)
+
+    # By default all non-secure regression tests are disabled.
+    # If TEST_NS or TEST_NS_XXX flag is passed via command line and set to ON,
+    # selected corresponding features to support non-secure regression tests.
+    foreach(CACHE_VAR ${CACHE_VARS})
+        string(REGEX MATCH "^TEST_NS.*" _NS_TEST_FOUND "${CACHE_VAR}")
+        if (_NS_TEST_FOUND AND "${${CACHE_VAR}}")
+            # TFM_NS_REG_TEST is a TF-M internal cmake flag to manage building
+            # tf-m-tests non-secure regression tests related source
+            set(TFM_NS_REG_TEST ON)
+            break()
+        endif()
+    endforeach()
+
+    foreach(CACHE_VAR ${CACHE_VARS})
+        string(REGEX MATCH "^TEST_S.*" _S_TEST_FOUND "${CACHE_VAR}")
+        if (_S_TEST_FOUND AND "${${CACHE_VAR}}")
+            # TFM_S_REG_TEST is a TF-M internal cmake flag to manage building
+            # tf-m-tests secure regression tests related source
+            set(TFM_S_REG_TEST ON)
+            break()
+        endif()
+    endforeach()
+
+    # By default EXTRA_<NS/S>_TEST_SUITES_PATHS is not set, extra test is also an
+    # out-of-tree build regression test, and if they are enabled,
+    # TFM_<NS/S>_REG_TEST will be enabled.
+    if (EXTRA_NS_TEST_SUITE_PATH)
+        set(TFM_NS_REG_TEST ON)
+    endif()
+
+    if (EXTRA_S_TEST_SUITE_PATH)
+        set(TFM_S_REG_TEST ON)
+    endif()
+
+    set(ns_reg_cmd    "-DTFM_NS_REG_TEST:BOOL=${TFM_NS_REG_TEST}")
+    set(s_reg_cmd     "-DTFM_S_REG_TEST:BOOL=${TFM_S_REG_TEST}")
+    set(${cmd_line}   "${${cmd_line}};${ns_reg_cmd};${s_reg_cmd}" PARENT_SCOPE)
+
+endfunction()
diff --git a/tests_reg/utils/test_suite_utils.cmake b/tests_reg/utils/test_suite_utils.cmake
new file mode 100644
index 0000000..e9e6c66
--- /dev/null
+++ b/tests_reg/utils/test_suite_utils.cmake
@@ -0,0 +1,86 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Temporarily unset NS test flags to skip NS test suites during S build.
+# These flags will be recovered in post_secure_suite_build().
+# Their values are kept in temporary local variables.
+macro(pre_secure_suite_build)
+    get_cmake_property(CACHE_VARS CACHE_VARIABLES)
+
+    foreach(CACHE_VAR ${CACHE_VARS})
+        string(REGEX MATCH "^TEST_NS.*" _NS_TEST_FOUND "${CACHE_VAR}")
+        if(_NS_TEST_FOUND AND "${${CACHE_VAR}}")
+            set(TEMP_${CACHE_VAR} ${${CACHE_VAR}})
+            unset(${CACHE_VAR} CACHE)
+        endif()
+    endforeach()
+
+    if(EXTRA_NS_TEST_SUITE_PATH)
+        set(TEMP_EXTRA_NS_TEST_SUITE_PATH ${EXTRA_NS_TEST_SUITE_PATH})
+        unset(EXTRA_NS_TEST_SUITE_PATH CACHE)
+    endif()
+endmacro()
+
+# Recover test flags unset in pre_secure_suite_build().
+# Their values are restored from temporary local variables and written back.
+macro(post_secure_suite_build)
+    get_cmake_property(TEMP_TEST_VARS VARIABLES)
+
+    foreach(TEMP_TEST ${TEMP_TEST_VARS})
+        string(REGEX MATCH "^TEMP_TEST_NS.*" _NS_TEST_FOUND "${TEMP_TEST}")
+        if(_NS_TEST_FOUND AND "${${TEMP_TEST}}")
+            string(REGEX REPLACE "^TEMP_" "" TEST_NAME ${TEMP_TEST})
+            set(${TEST_NAME}    ON    CACHE BOOL "")
+            unset(${TEMP_TEST})
+        endif()
+    endforeach()
+
+    if(TEMP_EXTRA_NS_TEST_SUITE_PATH)
+        set(EXTRA_NS_TEST_SUITE_PATH    ${TEMP_EXTRA_NS_TEST_SUITE_PATH}    CACHE PATH "")
+        unset(TEMP_EXTRA_NS_TEST_SUITE_PATH)
+    endif()
+endmacro()
+
+# Temporarily unset S test flags to skip S test suites during NS build.
+# These flags will be recovered in post_ns_suite_build(). Their values are kept in temporary local
+# variables.
+macro(pre_ns_suite_build)
+    get_cmake_property(CACHE_VARS CACHE_VARIABLES)
+
+    foreach(CACHE_VAR ${CACHE_VARS})
+        string(REGEX MATCH "^TEST_S.*" _S_TEST_FOUND "${CACHE_VAR}")
+        if(_S_TEST_FOUND AND "${${CACHE_VAR}}")
+            set(TEMP_${CACHE_VAR} ${${CACHE_VAR}})
+            unset(${CACHE_VAR} CACHE)
+        endif()
+    endforeach()
+
+    if(EXTRA_S_TEST_SUITE_PATH)
+        set(TEMP_EXTRA_S_TEST_SUITE_PATH ${EXTRA_S_TEST_SUITE_PATH})
+        unset(EXTRA_S_TEST_SUITE_PATH CACHE)
+    endif()
+endmacro()
+
+# Recover test flags unset in pre_ns_suite_build().
+# Their values are restored from temporary local variables and written back.
+macro(post_ns_suite_build)
+    get_cmake_property(TEMP_TEST_VARS VARIABLES)
+
+    foreach(TEMP_TEST ${TEMP_TEST_VARS})
+        string(REGEX MATCH "^TEMP_TEST_S.*" _S_TEST_FOUND "${TEMP_TEST}")
+        if(_S_TEST_FOUND AND "${${TEMP_TEST}}")
+            string(REGEX REPLACE "^TEMP_" "" TEST_NAME ${TEMP_TEST})
+            set(${TEST_NAME}    ON    CACHE BOOL "")
+            unset(${TEMP_TEST})
+        endif()
+    endforeach()
+
+    if(TEMP_EXTRA_S_TEST_SUITE_PATH)
+        set(EXTRA_S_TEST_SUITE_PATH    ${TEMP_EXTRA_S_TEST_SUITE_PATH}    CACHE PATH "")
+        unset(TEMP_EXTRA_S_TEST_SUITE_PATH)
+    endif()
+endmacro()