feat(lfa): add multi-CPU test for LFA of RMM
Add LFA testing on multiple CPUs. Executed full LFA
test for RMM live activation.
Signed-off-by: Manish V Badarkhe <Manish.Badarkhe@arm.com>
Change-Id: I22f9ec7185adddc91b8f5c5ebae9128f31ef0e2a
diff --git a/tftf/tests/runtime_services/lfa/test_lfa_multi_cpu.c b/tftf/tests/runtime_services/lfa/test_lfa_multi_cpu.c
new file mode 100644
index 0000000..59fe81f
--- /dev/null
+++ b/tftf/tests/runtime_services/lfa/test_lfa_multi_cpu.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <events.h>
+#include <lfa.h>
+#include <plat_topology.h>
+#include <platform.h>
+#include <power_management.h>
+#include <psci.h>
+#include <spinlock.h>
+#include <test_helpers.h>
+#include <tftf_lib.h>
+
+#define RMM_X1 UL(0x564bf212a662076c)
+#define RMM_X2 UL(0xd90636638fbacb92)
+
+static uint64_t fw_id;
+
+/*
+ * Test entry point function for non-lead CPUs.
+ * Specified by the lead CPU when bringing up other CPUs.
+ */
+static test_result_t non_lead_cpu_fn(void)
+{
+ smc_args args = { .fid = LFA_ACTIVATE, .arg1 = fw_id };
+ smc_ret_values ret;
+
+ ret = tftf_smc(&args);
+ if (ret.ret0 != SMC_OK) {
+ tftf_testcase_printf("%s: LFA_ACTIVATE error: 0x%08lx\n",
+ __func__, ret.ret0);
+ return TEST_RESULT_FAIL;
+ }
+ return TEST_RESULT_SUCCESS;
+}
+
+static test_result_t test_lfa_activate_flow(uint64_t uuid1, uint64_t uuid2)
+{
+ unsigned int lead_mpid;
+ unsigned int cpu_mpid, cpu_node;
+ int psci_ret;
+
+ lead_mpid = read_mpidr_el1() & MPID_MASK;
+
+ SKIP_TEST_IF_LESS_THAN_N_CPUS(2);
+
+ smc_args args = { .fid = LFA_GET_INFO, .arg1 = 0 };
+ smc_ret_values ret;
+ uint64_t i, j;
+ bool found = false;
+
+ ret = tftf_smc(&args);
+ if (ret.ret0 != SMC_OK) {
+ tftf_testcase_printf("%s: LFA_GET_INFO error: 0x%08lx\n",
+ __func__, ret.ret0);
+ return TEST_RESULT_FAIL;
+ }
+ j = ret.ret1;
+
+ for (i = 0U; i < j; i++) {
+ args.fid = LFA_GET_INVENTORY;
+ args.arg1 = i;
+ ret = tftf_smc(&args);
+ if (ret.ret0 != 0) {
+ tftf_testcase_printf("%s: LFA_GET_INVENTORY error: 0x%08lx\n",
+ __func__, ret.ret0);
+ return TEST_RESULT_FAIL;
+ }
+ tftf_testcase_printf("ID %lld: 0x%16lx 0x%16lx - capable: %s, pending: %s\n",
+ i, ret.ret1, ret.ret2,
+ (ret.ret4 & 0x1) ? "yes" : "no",
+ (ret.ret4 & 0x2) ? "yes" : "no");
+
+ if ((ret.ret1 == uuid1) && (ret.ret2 == uuid2)) {
+ found = true;
+ fw_id = i;
+ }
+ }
+
+ if (found == false) {
+ tftf_testcase_printf("%s: Firmware not found\n", __func__);
+ return TEST_RESULT_SKIPPED;
+ }
+
+ args.fid = LFA_PRIME;
+ args.arg1 = fw_id;
+ ret = tftf_smc(&args);
+ if (ret.ret0 != SMC_OK) {
+ tftf_testcase_printf("%s: LFA_PRIME error: 0x%08lx\n",
+ __func__, ret.ret0);
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Power on all CPUs */
+ for_each_cpu(cpu_node) {
+ cpu_mpid = tftf_get_mpidr_from_node(cpu_node);
+ /* Skip lead CPU as it is already powered on */
+ if (cpu_mpid == lead_mpid)
+ continue;
+
+ psci_ret = tftf_cpu_on(cpu_mpid, (uintptr_t) non_lead_cpu_fn, 0);
+ if (psci_ret != PSCI_E_SUCCESS) {
+ tftf_testcase_printf(
+ "Failed to power on CPU 0x%x (%d)\n",
+ cpu_mpid, psci_ret);
+ return TEST_RESULT_SKIPPED;
+ }
+ }
+
+ args.fid = LFA_ACTIVATE;
+ args.arg1 = fw_id;
+ ret = tftf_smc(&args);
+ if (ret.ret0 != SMC_OK) {
+ tftf_testcase_printf("%s: LFA_ACTIVATE error: 0x%08lx\n", __func__, ret.ret0);
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * @Test_Aim@ Test RMM Live activation.
+ */
+test_result_t test_lfa_activate_rmm(void)
+{
+ return test_lfa_activate_flow(RMM_X1, RMM_X2);
+}
diff --git a/tftf/tests/tests-lfa.mk b/tftf/tests/tests-lfa.mk
index a66dd53..1b42bf5 100644
--- a/tftf/tests/tests-lfa.mk
+++ b/tftf/tests/tests-lfa.mk
@@ -5,5 +5,6 @@
#
TESTS_SOURCES += $(addprefix tftf/tests/runtime_services/lfa/, \
- test_lfa_single_cpu.c \
+ test_lfa_single_cpu.c \
+ test_lfa_multi_cpu.c \
)
diff --git a/tftf/tests/tests-lfa.xml b/tftf/tests/tests-lfa.xml
index 77222c7..4b584c7 100644
--- a/tftf/tests/tests-lfa.xml
+++ b/tftf/tests/tests-lfa.xml
@@ -15,5 +15,6 @@
<testcase name="Prime" function="test_lfa_prime" />
<testcase name="Activate" function="test_lfa_activate" />
<testcase name="Cancel" function="test_lfa_cancel" />
+ <testcase name="RMM Live Activation" function="test_lfa_activate_rmm" />
</testsuite>
</testsuites>