test(nop): add "nop" test case
This is intended for use in conjunction with Trusted Firmware eXplorer
(TFX). The dummy test case exists only to provide a symbol with a
well-known name ("debug_hook"), at which TFX can set a breakpoint and
therefore marshall all PEs on entry to Non-secure state.
The "nop" test case is not built by default, and therefore must be
explicitly included, e.g.
make TESTS=nop
Signed-off-by: Gareth Stockwell <gareth.stockwell@arm.com>
Change-Id: I1d0f95714e5f662ca0f2d90db32020be15b43aed
diff --git a/tftf/tests/misc_tests/test_nop.c b/tftf/tests/misc_tests/test_nop.c
new file mode 100644
index 0000000..d3c4386
--- /dev/null
+++ b/tftf/tests/misc_tests/test_nop.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <power_management.h>
+#include <test_helpers.h>
+
+__attribute__((noinline))
+static void debug_hook_func(void)
+{
+ __asm__ volatile(
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "debug_hook:\n"
+ ".global debug_hook\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ );
+
+ return;
+}
+
+static test_result_t secondary_cpu(void)
+{
+ debug_hook_func();
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * This is intended for use in conjunction with Trusted Firmware eXplorer
+ * (TFX).
+ *
+ * 1. Power up all secondary CPUs and execute test_nop.
+ * 2. TFX is expected to set a breakpoint on debug_hook. When this is hit,
+ * TFX takes over control and starts injecting test code.
+ * 3. Once the test is complete, TFX powers down all CPUs.
+ */
+test_result_t test_nop(void)
+{
+ u_register_t lead_mpid, target_mpid;
+ int cpu_node;
+ long long ret;
+
+ lead_mpid = read_mpidr_el1() & MPID_MASK;
+
+ /* Start all other CPUs */
+ for_each_cpu(cpu_node) {
+ target_mpid = tftf_get_mpidr_from_node(cpu_node) & MPID_MASK;
+
+ if (lead_mpid == target_mpid) {
+ continue;
+ }
+
+ ret = tftf_cpu_on(target_mpid, (uintptr_t)secondary_cpu, 0);
+ if (ret != PSCI_E_SUCCESS) {
+ ERROR("CPU ON failed for 0x0x%llx\n", (unsigned long long)target_mpid);
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ /* Do the actual work */
+ debug_hook_func();
+
+ /* Wait for other CPUs to complete */
+ for_each_cpu(cpu_node) {
+ target_mpid = tftf_get_mpidr_from_node(cpu_node) & MPID_MASK;
+
+ if (lead_mpid == target_mpid) {
+ continue;
+ }
+
+ while (tftf_psci_affinity_info(target_mpid, MPIDR_AFFLVL0) != PSCI_STATE_OFF) {
+ continue;
+ }
+ }
+
+ return TEST_RESULT_SUCCESS;
+}