Test: Allow CPU to enter low-power mode after tests

Changes the test thread functions to exit at the end instead of busy
looping. Changes the CMSIS idle thread to call WFE instead of busy
waiting. In combination, this allows the CPU to enter the idle thread
and then go into low power state once the tests finish.

As well as reducing power on real HW, this significantly improves FVP
performance where multiple CPUs are being simulated, since time is not
wasted simulating an idle CPU.

Change-Id: I405013b31deb211aba3e965a83550abef47bb8fd
Signed-off-by: Jamie Fox <jamie.fox@arm.com>
diff --git a/app_broker/CMakeLists.txt b/app_broker/CMakeLists.txt
index 15c0191..b5bd5ec 100644
--- a/app_broker/CMakeLists.txt
+++ b/app_broker/CMakeLists.txt
@@ -73,10 +73,12 @@
         $<$<BOOL:${TEST_NS_MANAGE_NSID}>:TEST_NS_MANAGE_NSID>
 )
 
-# Provide TZ context management stub to RTOS if protected by Trustzone
 target_sources(RTX_OS
     INTERFACE
+        # Provide TZ context management stub to RTOS if protected by Trustzone
         $<$<BOOL:${CONFIG_TFM_USE_TRUSTZONE}>:${APP_LIB_DIR}/nsid_manager/tz_shim_layer.c>
+        # Provide CMSIS-RTX config implementation
+        os_config_cmsis_rtx.c
 )
 
 target_link_libraries(RTX_OS
diff --git a/app_broker/os_config_cmsis_rtx.c b/app_broker/os_config_cmsis_rtx.c
new file mode 100644
index 0000000..440cd14
--- /dev/null
+++ b/app_broker/os_config_cmsis_rtx.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "cmsis_compiler.h"
+#include "rtx_os.h"
+
+/* This is an example OS configuration implementation for CMSIS-RTX */
+
+/* OS Idle Thread implemented to put the CPU into low-power state until an event
+ * occurs. The regular SysTick will still wake the CPU.
+ */
+__NO_RETURN void osRtxIdleThread(void *argument)
+{
+    (void)argument;
+
+    for (;;) {
+        __WFE();
+    }
+}
diff --git a/lib/os_wrapper/thread.h b/lib/os_wrapper/thread.h
index 83633a6..7d23024 100644
--- a/lib/os_wrapper/thread.h
+++ b/lib/os_wrapper/thread.h
@@ -56,7 +56,7 @@
 /**
  * \brief Exits the calling thread
  */
-void os_wrapper_thread_exit(void);
+__attribute__((noreturn)) void os_wrapper_thread_exit(void);
 
 /**
  * \brief Set the event flags for synchronizing a thread specified by handle.
diff --git a/tests_psa_arch/CMakeLists.txt b/tests_psa_arch/CMakeLists.txt
index 948df86..13c3241 100644
--- a/tests_psa_arch/CMakeLists.txt
+++ b/tests_psa_arch/CMakeLists.txt
@@ -120,6 +120,7 @@
 
 target_link_libraries(tfm_ns
     PRIVATE
+        os_wrapper
         tfm_test_broker
         val_nspe
         pal_nspe
diff --git a/tests_psa_arch/test_app.c b/tests_psa_arch/test_app.c
index 80190bd..74f98ec 100644
--- a/tests_psa_arch/test_app.c
+++ b/tests_psa_arch/test_app.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -7,6 +7,7 @@
 
 #include "test_app.h"
 #include "tfm_log.h"
+#include "os_wrapper/thread.h"
 
 /**
  * \brief This symbol is the entry point provided by the PSA API compliance
@@ -29,6 +30,5 @@
     LOG_MSG("\x04");
 
     /* End of test */
-    for (;;) {
-    }
+    os_wrapper_thread_exit();
 }
diff --git a/tests_reg/CMakeLists.txt b/tests_reg/CMakeLists.txt
index 3df3034..619cea9 100644
--- a/tests_reg/CMakeLists.txt
+++ b/tests_reg/CMakeLists.txt
@@ -75,6 +75,7 @@
 
 target_link_libraries(tfm_ns
     PRIVATE
+        os_wrapper
         tfm_test_broker
         $<$<BOOL:${TFM_NS_REG_TEST}>:tfm_ns_tests>
 )
diff --git a/tests_reg/test_app.c b/tests_reg/test_app.c
index 35b07d3..2d2df21 100644
--- a/tests_reg/test_app.c
+++ b/tests_reg/test_app.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -10,6 +10,7 @@
 #ifdef TFM_NS_REG_TEST
 #include "non_secure_suites.h"
 #endif
+#include "os_wrapper/thread.h"
 
 /**
  * \brief Services test thread
@@ -28,6 +29,5 @@
     LOG_MSG("\x04");
 
     /* End of test */
-    for (;;) {
-    }
+    os_wrapper_thread_exit();
 }