test(realm): add test for multi rec planes

Test exercises SMC_PSCI_CPU_ON from aux plane.
Request is first routed to P0 and then to Host.
Host enters P0 and then P1 on all CPUs.

Change-Id: I7e34a0070ffa7305b97a0d93de62b64042771a18
Signed-off-by: Shruti Gupta <shruti.gupta@arm.com>
diff --git a/include/runtime_services/host_realm_managment/host_realm_helper.h b/include/runtime_services/host_realm_managment/host_realm_helper.h
index e27cfd5..af8f834 100644
--- a/include/runtime_services/host_realm_managment/host_realm_helper.h
+++ b/include/runtime_services/host_realm_managment/host_realm_helper.h
@@ -61,8 +61,29 @@
  * This functions sets the shared data args needed for entering aux plane,
  * using REALM_ENTER_PLANE_N_CMD
  */
-void host_realm_set_aux_plane_args(struct realm *realm_ptr, unsigned int plane_num);
+void host_realm_set_aux_plane_args(struct realm *realm_ptr,
+		unsigned int plane_num, unsigned int rec_num);
 
+
+/* Function to check if Planes feature is supoprted */
+static inline bool are_planes_supported(void)
+{
+	u_register_t feature_flag;
+
+	/* Read Realm Feature Reg 0 */
+	if (host_rmi_features(0UL, &feature_flag) != REALM_SUCCESS) {
+		ERROR("%s() failed\n", "host_rmi_features");
+		return false;
+	}
+
+	if (EXTRACT(RMI_FEATURE_REGISTER_0_MAX_NUM_AUX_PLANES, feature_flag) > 0UL) {
+		return true;
+	}
+
+	return false;
+}
+
+/* Function to check if S2POE feature/ Single RTT is supported for multiple planes */
 static inline bool is_single_rtt_supported(void)
 {
 	u_register_t feature_flag;
diff --git a/include/runtime_services/host_realm_managment/host_shared_data.h b/include/runtime_services/host_realm_managment/host_shared_data.h
index 3eefd25..2e8a3f5 100644
--- a/include/runtime_services/host_realm_managment/host_shared_data.h
+++ b/include/runtime_services/host_realm_managment/host_shared_data.h
@@ -50,6 +50,7 @@
 	REALM_MPAM_PRESENT,
 	REALM_MULTIPLE_REC_PSCI_DENIED_CMD,
 	REALM_MULTIPLE_REC_MULTIPLE_CPU_CMD,
+	REALM_PLANES_MULTIPLE_REC_MULTIPLE_CPU_CMD,
 	REALM_GET_RSI_VERSION,
 	REALM_INSTR_FETCH_CMD,
 	REALM_DATA_ACCESS_CMD,
diff --git a/realm/include/realm_tests.h b/realm/include/realm_tests.h
index 6c1e6c3..6f457e5 100644
--- a/realm/include/realm_tests.h
+++ b/realm/include/realm_tests.h
@@ -25,6 +25,7 @@
 bool test_realm_sve_undef_abort(void);
 bool test_realm_multiple_rec_psci_denied_cmd(void);
 bool test_realm_multiple_rec_multiple_cpu_cmd(void);
+bool test_realm_multiple_plane_multiple_rec_multiple_cpu_cmd(void);
 bool test_realm_sme_read_id_registers(void);
 bool test_realm_sme_undef_abort(void);
 bool test_realm_sctlr2_ease(void);
diff --git a/realm/realm_multiple_rec.c b/realm/realm_multiple_rec.c
index c584cd4..95bb6f1 100644
--- a/realm/realm_multiple_rec.c
+++ b/realm/realm_multiple_rec.c
@@ -15,18 +15,26 @@
 #include <host_shared_data.h>
 #include <psci.h>
 #include "realm_def.h"
+#include <realm_helpers.h>
+#include <realm_psi.h>
 #include <realm_rsi.h>
 #include <realm_tests.h>
 #include <realm_psci.h>
 #include <tftf_lib.h>
 
-#define CXT_ID_MAGIC 0x100
+#define CXT_ID_MAGIC	0x100
+#define P1_CXT_ID_MAGIC	0x200
+
 static uint64_t is_secondary_cpu_booted;
 static spinlock_t lock;
+static rsi_plane_run run[MAX_REC_COUNT] __aligned(PAGE_SIZE);
+static u_register_t base, plane_index, perm_index;
 
-static void rec1_handler(u_register_t cxt_id)
+static void plane0_recn_handler(u_register_t cxt_id)
 {
-	realm_printf("running on CPU = 0x%lx cxt_id= 0x%lx\n",
+	uint64_t rec = 0U;
+
+	realm_printf("running on Rec= 0x%lx cxt_id= 0x%lx\n",
 			read_mpidr_el1() & MPID_MASK, cxt_id);
 	if (cxt_id < CXT_ID_MAGIC || cxt_id > CXT_ID_MAGIC + MAX_REC_COUNT) {
 		realm_printf("Wrong cxt_id\n");
@@ -34,6 +42,35 @@
 	}
 	spin_lock(&lock);
 	is_secondary_cpu_booted++;
+	rec =  read_mpidr_el1() & MPID_MASK;
+	spin_unlock(&lock);
+
+	/* enter plane */
+	u_register_t flags = 0U;
+
+	/* Use Base adr, plane_index, perm_index programmed by P0 rec0 */
+	run[rec].enter.pc = base;
+	realm_printf("Entering plane %ld, ep=0x%lx rec=0x%lx\n", plane_index, base, rec);
+	realm_plane_enter(plane_index, perm_index, base, flags, &run[rec]);
+
+	if (run[rec].exit.gprs[0] == SMC_PSCI_CPU_OFF) {
+		realm_printf("Plane N did not request CPU OFF\n");
+		rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
+	}
+	realm_cpu_off();
+}
+
+static void recn_handler(u_register_t cxt_id)
+{
+	realm_printf("running on Rec= 0x%lx cxt_id= 0x%lx\n",
+			read_mpidr_el1() & MPID_MASK, cxt_id);
+
+	if (cxt_id < P1_CXT_ID_MAGIC || cxt_id > P1_CXT_ID_MAGIC + MAX_REC_COUNT) {
+		realm_printf("Wrong cxt_id\n");
+		rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
+	}
+	spin_lock(&lock);
+	is_secondary_cpu_booted++;
 	spin_unlock(&lock);
 	realm_cpu_off();
 }
@@ -48,7 +85,7 @@
 	u_register_t ret;
 
 	is_secondary_cpu_booted = 0U;
-	ret = realm_cpu_on(1U, (uintptr_t)rec1_handler, 0x100);
+	ret = realm_cpu_on(1U, (uintptr_t)recn_handler, 0x100);
 	if (ret != PSCI_E_DENIED) {
 		return false;
 	}
@@ -71,12 +108,106 @@
 	return true;
 }
 
+/*
+ * All Planes enter this test function.
+ * P0 Rec0 Enters Plane N
+ * Plane N rec 0 requests CPU ON for all other rec
+ * P0 Rec0 requests CPU ON to host
+ * Host enters P0 RecN from different CPU
+ * P0 RecN enters PlaneN RecN
+ * Rec N requests CPU OFF, exits to P0
+ * P0 requests CPU OFF to host.
+ * P0 verifies all other CPU are off.
+ */
+bool test_realm_multiple_plane_multiple_rec_multiple_cpu_cmd(void)
+{
+	unsigned int i = 1U, rec_count;
+	u_register_t ret;
+	bool ret1;
+
+	realm_printf("Realm: running on Rec= 0x%lx\n", read_mpidr_el1() & MPID_MASK);
+	rec_count = realm_shared_data_get_my_host_val(HOST_ARG3_INDEX);
+
+	/* Check CPU_ON is supported */
+	ret = realm_psci_features(SMC_PSCI_CPU_ON);
+	if (ret != PSCI_E_SUCCESS) {
+		realm_printf("SMC_PSCI_CPU_ON not supported\n");
+		return false;
+	}
+
+	if (realm_is_plane0()) {
+		/* Plane 0 all rec */
+		u_register_t flags = 0U;
+
+		plane_index = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
+		base = realm_shared_data_get_my_host_val(HOST_ARG2_INDEX);
+		perm_index = plane_index + 1U;
+
+		plane_common_init(plane_index, perm_index, base, &run[0U]);
+
+		ret1 = realm_plane_enter(plane_index, perm_index, base, flags, &run[0U]);
+		while (ret1 && run->exit.gprs[0] == SMC_PSCI_CPU_ON_AARCH64) {
+			realm_printf("Plane N requested CPU on Rec=0x%lx\n", run[0].exit.gprs[1]);
+
+			/* Pass context tp RecN - CXT + rec idx */
+			run[0].enter.gprs[0] = realm_cpu_on(run[0].exit.gprs[1],
+						(uintptr_t)plane0_recn_handler,
+						CXT_ID_MAGIC + run[0].exit.gprs[1]);
+
+			/* re-enter plane N 1 to complete cpu on */
+			ret1 = realm_plane_enter(plane_index, perm_index, base, flags, &run[0U]);
+			if (!ret1) {
+				realm_printf("PlaneN CPU on complete failed\n");
+				rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
+			}
+		}
+
+		/* wait for all CPUs to come up */
+		while (is_secondary_cpu_booted != rec_count - 1U) {
+			waitms(200);
+		}
+
+		/* wait for all CPUs to turn off */
+		while (i < rec_count) {
+			ret = realm_psci_affinity_info(i, MPIDR_AFFLVL0);
+			if (ret != PSCI_STATE_OFF) {
+				/* wait and query again */
+				realm_printf(" CPU %d is not off\n", i);
+				waitms(200);
+				continue;
+			}
+			i++;
+		}
+		realm_printf("All CPU are off\n");
+		return true;
+	} else {
+		/* Plane 1 Rec 0 */
+		for (unsigned int j = 1U; j < rec_count; j++) {
+			realm_printf("CPU ON Rec=%u\n", j);
+			ret = realm_cpu_on(j, (uintptr_t)recn_handler, P1_CXT_ID_MAGIC + j);
+			if (ret != PSCI_E_SUCCESS) {
+				realm_printf("SMC_PSCI_CPU_ON failed %d.\n", j);
+				return false;
+			}
+		}
+		/* Exit to Host to allow host to run all CPUs */
+		rsi_exit_to_host(HOST_CALL_EXIT_SUCCESS_CMD);
+
+		/* wait for all CPUs to come up */
+		while (is_secondary_cpu_booted != rec_count - 1U) {
+			waitms(200);
+		}
+		return true;
+	}
+	return true;
+}
+
 bool test_realm_multiple_rec_multiple_cpu_cmd(void)
 {
 	unsigned int i = 1U, rec_count;
 	u_register_t ret;
 
-	realm_printf("Realm: running on CPU = 0x%lx\n", read_mpidr_el1() & MPID_MASK);
+	realm_printf("Realm: running on Rec= 0x%lx\n", read_mpidr_el1() & MPID_MASK);
 	rec_count = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
 
 	/* Check CPU_ON is supported */
@@ -87,7 +218,7 @@
 	}
 
 	for (unsigned int j = 1U; j < rec_count; j++) {
-		ret = realm_cpu_on(j, (uintptr_t)rec1_handler, CXT_ID_MAGIC + j);
+		ret = realm_cpu_on(j, (uintptr_t)recn_handler, P1_CXT_ID_MAGIC + j);
 		if (ret != PSCI_E_SUCCESS) {
 			realm_printf("SMC_PSCI_CPU_ON failed %d.\n", j);
 			return false;
diff --git a/realm/realm_payload_main.c b/realm/realm_payload_main.c
index be555fa..ad98841 100644
--- a/realm/realm_payload_main.c
+++ b/realm/realm_payload_main.c
@@ -418,6 +418,9 @@
 		case REALM_MULTIPLE_REC_MULTIPLE_CPU_CMD:
 			test_succeed = test_realm_multiple_rec_multiple_cpu_cmd();
 			break;
+		case REALM_PLANES_MULTIPLE_REC_MULTIPLE_CPU_CMD:
+			test_succeed = test_realm_multiple_plane_multiple_rec_multiple_cpu_cmd();
+			break;
 		case REALM_FEAT_DOUBLEFAULT2_TEST:
 			test_realm_feat_doublefault2();
 			test_succeed = true;
diff --git a/realm/realm_plane.c b/realm/realm_plane.c
index c7225ed..3b79aff 100644
--- a/realm/realm_plane.c
+++ b/realm/realm_plane.c
@@ -11,6 +11,8 @@
 #include <debug.h>
 
 #include <host_realm_helper.h>
+#include <psci.h>
+#include <realm_psci.h>
 #include <realm_psi.h>
 #include <realm_rsi.h>
 #include <sync.h>
@@ -102,10 +104,30 @@
 
 	/* Disallow SMC from Plane N */
 	if (ec == EC_AARCH64_SMC) {
-		/* TODO Support PSCI in future */
+		u_register_t smc_id = run->exit.gprs[0];
+
 		restore_plane_context(run);
-		run->enter.gprs[0] = RSI_ERROR_STATE;
-		return PSI_RETURN_TO_PN;
+		switch (smc_id) {
+		case SMC_PSCI_CPU_ON_AARCH64:
+			assert(run->exit.gprs[1] < MAX_REC_COUNT);
+			assert(run->exit.gprs[1] != 0U);
+			/* Let P0 handle CPU ON */
+			return PSI_RETURN_TO_P0;
+		case SMC_PSCI_CPU_OFF:
+			realm_cpu_off();
+			/* Does not return. */
+			return PSI_RETURN_TO_PN;
+		case SMC_PSCI_FEATURES:
+			run->enter.gprs[0] = realm_psci_features(run->exit.gprs[1U]);
+			return PSI_RETURN_TO_PN;
+		case SMC_PSCI_AFFINITY_INFO:
+			run->enter.gprs[0] = realm_psci_affinity_info(run->exit.gprs[1U],
+					run->exit.gprs[2U]);
+			return PSI_RETURN_TO_PN;
+		default:
+			run->enter.gprs[0] = RSI_ERROR_STATE;
+			return PSI_RETURN_TO_PN;
+		}
 	}
 
 	/* Handle PSI HVC call from Plane N */
diff --git a/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c b/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c
index 7d1a246..8ca1957 100644
--- a/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c
+++ b/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c
@@ -503,12 +503,13 @@
  * Entrypoint for aux plane = realm.par_base + (plane_num * realm..par_size)
  */
 void host_realm_set_aux_plane_args(struct realm *realm_ptr,
-		unsigned int plane_num)
+		unsigned int plane_num, unsigned int rec_num)
 {
 	/* Plane Index */
-	host_shared_data_set_host_val(realm_ptr, PRIMARY_PLANE_ID, 0U, HOST_ARG1_INDEX, plane_num);
+	host_shared_data_set_host_val(realm_ptr, PRIMARY_PLANE_ID, rec_num,
+			HOST_ARG1_INDEX, plane_num);
 
 	/* Plane entrypoint */
-	host_shared_data_set_host_val(realm_ptr, PRIMARY_PLANE_ID, 0U, HOST_ARG2_INDEX,
+	host_shared_data_set_host_val(realm_ptr, PRIMARY_PLANE_ID, rec_num, HOST_ARG2_INDEX,
 			realm_ptr->par_base + (plane_num * realm_ptr->par_size));
 }
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_payload_multiple_rec_tests.c b/tftf/tests/runtime_services/realm_payload/host_realm_payload_multiple_rec_tests.c
index e6a9cd5..951a1f6 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_payload_multiple_rec_tests.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_payload_multiple_rec_tests.c
@@ -301,6 +301,206 @@
 	return host_cmp_result();
 }
 
+static test_result_t plane_cpu_on_handler(void)
+{
+	bool ret;
+	struct rmi_rec_run *run;
+	unsigned int i;
+
+	spin_lock(&secondary_cpu_lock);
+	i = ++is_secondary_cpu_on;
+	spin_unlock(&secondary_cpu_lock);
+
+	/* Args for plane 0 to enter plane 1 on rec i */
+	host_realm_set_aux_plane_args(&realm, 1U, i);
+
+	/* CMD for Plane 1 Rec i */
+	host_shared_data_set_realm_cmd(&realm, REALM_PLANES_MULTIPLE_REC_MULTIPLE_CPU_CMD, 1U, i);
+
+	run = (struct rmi_rec_run *)realm.run[i];
+
+	/* Enter P0 and then P1 */
+	ret = host_enter_realm_execute(&realm, REALM_PLANES_MULTIPLE_REC_MULTIPLE_CPU_CMD,
+			RMI_EXIT_PSCI, i);
+	if (ret) {
+		if (run->exit.gprs[0] == SMC_PSCI_CPU_OFF) {
+			return TEST_RESULT_SUCCESS;
+		}
+	}
+	ERROR("Rec %d failed", i);
+	return TEST_RESULT_FAIL;
+}
+
+/*
+ * The test creates a realm with 2 planes and MAX recs
+ * Host enters P0 and then PN
+ * P1 issues PSCI_CPU_ON SMC, returns back to P0
+ * P0 forwards PSCI_CPU_ON to Host
+ * On receiving PSCI_CPU_ON call from P0 REC0 for all other recs,
+ * the test completes the PSCI call and re-enters P0 REC0 - followed by P1 REC0.
+ * Turn ON secondary CPUs upto a max of MAX_REC_COUNT.
+ * Each of the secondary then enters Realm (P0 followed by P1) with a different REC
+ * It is expected that the REC will exit with PSCI_CPU_OFF as the exit reason.
+ * P0 REC0 checks if all other CPUs are off, via PSCI_AFFINITY_INFO.
+ * Host completes the PSCI requests.
+ */
+test_result_t host_realm_multi_planes_multi_rec_multiple_cpu(void)
+{
+	bool ret1, ret2;
+	test_result_t ret3 = TEST_RESULT_FAIL;
+	int ret = RMI_ERROR_INPUT;
+	u_register_t rec_num;
+	u_register_t other_mpidr, my_mpidr;
+	struct rmi_rec_run *run;
+	unsigned int host_call_result, i;
+	u_register_t rec_flag[MAX_REC_COUNT] = {RMI_RUNNABLE};
+	u_register_t exit_reason;
+	unsigned int cpu_node, rec_count, num_aux_planes = 1U;
+	u_register_t feature_flag0 = 0U, feature_flag1 = 0U;
+	long sl = RTT_MIN_LEVEL;
+
+	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
+
+	rec_count = tftf_get_total_cpus_count();
+	assert(rec_count <= MAX_REC_COUNT);
+
+	if (is_feat_52b_on_4k_2_supported()) {
+		feature_flag0 = RMI_FEATURE_REGISTER_0_LPA2;
+		sl = RTT_MIN_LEVEL_LPA2;
+	}
+
+	if (!are_planes_supported()) {
+		return TEST_RESULT_SKIPPED;
+	}
+
+	if (is_single_rtt_supported()) {
+		/* Use single RTT with S2AP Indirect */
+		feature_flag0 |= INPLACE(RMI_FEATURE_REGISTER_0_PLANE_RTT,
+				RMI_PLANE_RTT_SINGLE);
+		feature_flag1 = RMI_REALM_FLAGS1_RTT_S2AP_ENCODING_INDIRECT;
+	}
+
+	for (i = 1U; i < rec_count; i++) {
+		rec_flag[i] = RMI_NOT_RUNNABLE;
+	}
+
+	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
+			feature_flag0, feature_flag1, sl, rec_flag, rec_count, num_aux_planes)) {
+		return TEST_RESULT_FAIL;
+	}
+
+	is_secondary_cpu_on = 0U;
+	init_spinlock(&secondary_cpu_lock);
+	my_mpidr = read_mpidr_el1() & MPID_MASK;
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 0U, HOST_ARG3_INDEX, rec_count);
+	host_shared_data_set_host_val(&realm, 1U, 0U, HOST_ARG3_INDEX, rec_count);
+
+	/* Set args for entering Plane 1 Rec0 */
+	host_realm_set_aux_plane_args(&realm, 1U, 0U);
+
+	/* CMD for Plane 1 */
+	host_shared_data_set_realm_cmd(&realm, REALM_PLANES_MULTIPLE_REC_MULTIPLE_CPU_CMD, 1U, 0U);
+
+	/* Enter P0, and then PN */
+	ret1 = host_enter_realm_execute(&realm, REALM_PLANES_MULTIPLE_REC_MULTIPLE_CPU_CMD,
+			RMI_EXIT_PSCI, 0U);
+
+	if (!ret1) {
+		ERROR("Host did not receive CPU ON request\n");
+
+		goto destroy_realm;
+	}
+	while (true) {
+		run = (struct rmi_rec_run *)realm.run[0];
+		if (run->exit.gprs[0] != SMC_PSCI_CPU_ON_AARCH64) {
+			ERROR("Host did not receive CPU ON request\n");
+			goto destroy_realm;
+		}
+		rec_num = host_realm_find_rec_by_mpidr(run->exit.gprs[1], &realm);
+		if (rec_num >= MAX_REC_COUNT) {
+			ERROR("Invalid mpidr requested\n");
+			goto destroy_realm;
+		}
+		ret = host_rmi_psci_complete(realm.rec[0], realm.rec[rec_num],
+				(unsigned long)PSCI_E_SUCCESS);
+		if (ret == RMI_SUCCESS) {
+			/* Re-enter REC0 complete CPU_ON */
+			ret = host_realm_rec_enter(&realm, &exit_reason,
+				&host_call_result, 0U);
+			if (ret != RMI_SUCCESS || exit_reason != RMI_EXIT_PSCI) {
+				break;
+			}
+		} else {
+			ERROR("host_rmi_psci_complete failed\n");
+			goto destroy_realm;
+		}
+	}
+	if (exit_reason != RMI_EXIT_HOST_CALL || host_call_result != TEST_RESULT_SUCCESS) {
+		ERROR("Realm failed\n");
+		goto destroy_realm;
+	}
+
+	i = 0U;
+
+	/* Turn on all CPUs */
+	for_each_cpu(cpu_node) {
+		if (i == (rec_count - 1U)) {
+			break;
+		}
+		other_mpidr = tftf_get_mpidr_from_node(cpu_node);
+		if (other_mpidr == my_mpidr) {
+			continue;
+		}
+
+		/* Power on the other CPU */
+		ret = tftf_try_cpu_on(other_mpidr, (uintptr_t)plane_cpu_on_handler, 0);
+		if (ret != PSCI_E_SUCCESS) {
+			ERROR("TFTF CPU ON failed\n");
+			goto destroy_realm;
+		}
+		i++;
+	}
+
+	while (true) {
+		/* Re-enter REC0 complete PSCI_AFFINITY_INFO */
+		ret = host_realm_rec_enter(&realm, &exit_reason, &host_call_result, 0U);
+		if (ret != RMI_SUCCESS) {
+			ERROR("Rec0 re-enter failed\n");
+			goto destroy_realm;
+		}
+		if (run->exit.gprs[0] != SMC_PSCI_AFFINITY_INFO_AARCH64) {
+			break;
+		}
+		rec_num = host_realm_find_rec_by_mpidr(run->exit.gprs[1], &realm);
+		if (rec_num >= rec_count) {
+			ERROR("Invalid mpidr requested\n");
+			goto destroy_realm;
+		}
+		ret = host_rmi_psci_complete(realm.rec[0], realm.rec[rec_num],
+				(unsigned long)PSCI_E_SUCCESS);
+
+		if (ret != RMI_SUCCESS) {
+			ERROR("host_rmi_psci_complete failed\n");
+			goto destroy_realm;
+		}
+	}
+
+	if (ret == RMI_SUCCESS && exit_reason == RMI_EXIT_HOST_CALL) {
+		ret3 = host_call_result;
+	}
+destroy_realm:
+	waitms(100U);
+	ret2 = host_destroy_realm(&realm);
+
+	if ((ret != RMI_SUCCESS) || !ret2) {
+		ERROR("%s(): enter=%d destroy=%d\n",
+		__func__, ret, ret2);
+		return TEST_RESULT_FAIL;
+	}
+
+	return ret3;
+}
+
 static test_result_t cpu_on_handler(void)
 {
 	bool ret;
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c b/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
index 8038fb4..3117460 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
@@ -39,23 +39,6 @@
 static uint128_t pauth_keys_after[NUM_KEYS];
 #endif
 
-bool are_planes_supported(void)
-{
-	u_register_t feature_flag;
-
-	/* Read Realm Feature Reg 0 */
-	if (host_rmi_features(0UL, &feature_flag) != REALM_SUCCESS) {
-		ERROR("%s() failed\n", "host_rmi_features");
-		return false;
-	}
-
-	if (EXTRACT(RMI_FEATURE_REGISTER_0_MAX_NUM_AUX_PLANES, feature_flag) > 0UL) {
-		return true;
-	}
-
-	return false;
-}
-
 /*
  * @Test_Aim@ Test RSI_PLANE_REG_READ/WRITE
  */
@@ -93,7 +76,7 @@
 
 	run = (struct rmi_rec_run *)realm.run[0U];
 
-	host_realm_set_aux_plane_args(&realm, 1U);
+	host_realm_set_aux_plane_args(&realm, 1U, 0U);
 	ret1 = host_enter_realm_execute(&realm, REALM_PLANE_N_REG_RW_CMD,
 			RMI_EXIT_HOST_CALL, 0U);
 
@@ -172,7 +155,7 @@
 	for (unsigned int j = 1U; j <= MAX_AUX_PLANE_COUNT; j++) {
 		run = (struct rmi_rec_run *)realm.run[0U];
 
-		host_realm_set_aux_plane_args(&realm, j);
+		host_realm_set_aux_plane_args(&realm, j, 0U);
 		ret1 = host_enter_realm_execute(&realm, REALM_ENTER_PLANE_N_CMD,
 				RMI_EXIT_HOST_CALL, 0U);
 
@@ -272,7 +255,7 @@
 	for (unsigned int j = 1U; j <= MAX_AUX_PLANE_COUNT; j++) {
 		run = (struct rmi_rec_run *)realm.run[0U];
 
-		host_realm_set_aux_plane_args(&realm, j);
+		host_realm_set_aux_plane_args(&realm, j, 0U);
 		ret1 = host_enter_realm_execute(&realm, REALM_ENTER_PLANE_N_CMD,
 				RMI_EXIT_HOST_CALL, 0U);
 
diff --git a/tftf/tests/tests-realm-payload.xml b/tftf/tests/tests-realm-payload.xml
index 277e6db..92eaf5a 100644
--- a/tftf/tests/tests-realm-payload.xml
+++ b/tftf/tests/tests-realm-payload.xml
@@ -14,6 +14,8 @@
 	  function="host_test_realm_create_planes_enter_single_rtt" />
 	  <testcase name="Realm Planes register read/write test"
 	  function="host_test_realm_create_planes_register_rw" />
+	  <testcase name="Realm payload Planes multi rec multiple cpu"
+	  function="host_realm_multi_planes_multi_rec_multiple_cpu" />
 	  <testcase name="Realm EL1 creation and execution test"
 	  function="host_test_realm_create_enter" />
 	  <testcase name="Realm RTT fold unfold test Unassigned Empty"