feat(trp): test el3-rmm ide km interface

This patch introduces test functions to the Test Realm Payload (TRP)
for performing basic sanity checks on the RMM-EL3 IDE KM support added
to EL3.

The primary goal of this patch is to only to verify the basic
functionality and ensure the implemented functions return the
correct return values.

The test uses random values for the ecam address, rootport ID,
IDE stream info, keys, and IV values.

Change-Id: Icf47627da9a6a7dd0d6e40e20ac94cc977072177
Signed-off-by: Sona Mathew <sonarebecca.mathew@arm.com>
diff --git a/include/services/trp/platform_trp.h b/include/services/trp/platform_trp.h
index 756e9db..67dfff1 100644
--- a/include/services/trp/platform_trp.h
+++ b/include/services/trp/platform_trp.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,4 +16,8 @@
  ******************************************************************************/
 void trp_early_platform_setup(struct rmm_manifest *manifest);
 
+#if RMMD_ENABLE_IDE_KEY_PROG
+uint64_t trp_get_test_rootport(uint64_t *ecam, uint64_t *rootport);
+#endif /* RMMD_ENABLE_IDE_KEY_PROG */
+
 #endif /* PLATFORM_TRP_H */
diff --git a/include/services/trp/trp_helpers.h b/include/services/trp/trp_helpers.h
index 83ec740..2f36720 100644
--- a/include/services/trp/trp_helpers.h
+++ b/include/services/trp/trp_helpers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,7 +17,11 @@
 #define TRP_ARG5		0x28
 #define TRP_ARG6		0x30
 #define TRP_ARG7		0x38
-#define TRP_ARGS_END		0x40
+#define TRP_ARG8		0x40
+#define TRP_ARG9		0x48
+#define TRP_ARG10		0x50
+#define TRP_ARG11		0x58
+#define TRP_ARGS_END		0x60
 
 #ifndef __ASSEMBLER__
 
@@ -35,7 +39,11 @@
 			 uint64_t arg4,
 			 uint64_t arg5,
 			 uint64_t arg6,
-			 uint64_t arg7);
+			 uint64_t arg7,
+			 uint64_t arg8,
+			 uint64_t arg9,
+			 uint64_t arg10,
+			 uint64_t arg11);
 
 __dead2 void trp_boot_abort(uint64_t err);
 
diff --git a/plat/arm/board/fvp/fvp_ide_keymgmt.c b/plat/arm/board/fvp/fvp_ide_keymgmt.c
index 53ed433..ff05351 100644
--- a/plat/arm/board/fvp/fvp_ide_keymgmt.c
+++ b/plat/arm/board/fvp/fvp_ide_keymgmt.c
@@ -44,6 +44,5 @@
 				   uint64_t *cookie)
 {
 	/* placeholder to add further implementation */
-
 	return E_RMM_UNK;
 }
diff --git a/plat/arm/board/fvp/trp/test_ide_km_interface.c b/plat/arm/board/fvp/trp/test_ide_km_interface.c
new file mode 100644
index 0000000..2a1f0e2
--- /dev/null
+++ b/plat/arm/board/fvp/trp/test_ide_km_interface.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <plat/common/platform.h>
+#include <services/trp/platform_trp.h>
+
+#include <platform_def.h>
+
+/*
+ * Helper function for ecam address and root port ID
+ *
+ */
+uint64_t trp_get_test_rootport(uint64_t *ecam_address, uint64_t *rp_id)
+{
+
+	*ecam_address = 0xE001C000;
+	*rp_id = 0x001C0001;
+
+	return 0;
+}
+
diff --git a/plat/arm/board/fvp/trp/trp-fvp.mk b/plat/arm/board/fvp/trp/trp-fvp.mk
index a450541..3c1b96b 100644
--- a/plat/arm/board/fvp/trp/trp-fvp.mk
+++ b/plat/arm/board/fvp/trp/trp-fvp.mk
@@ -6,7 +6,8 @@
 
 # TRP source files specific to FVP platform
 
-RMM_SOURCES		+=	plat/arm/board/fvp/aarch64/fvp_helpers.S
+RMM_SOURCES		+=	plat/arm/board/fvp/aarch64/fvp_helpers.S	\
+				plat/arm/board/fvp/trp/test_ide_km_interface.c
 
 include plat/arm/common/trp/arm_trp.mk
 
diff --git a/services/std_svc/rmmd/trp/trp_entry.S b/services/std_svc/rmmd/trp/trp_entry.S
index 3e1d8c9..a2fd6a0 100644
--- a/services/std_svc/rmmd/trp/trp_entry.S
+++ b/services/std_svc/rmmd/trp/trp_entry.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,6 +21,8 @@
 	 * ---------------------------------------------
 	 */
 	.macro restore_args_call_smc
+	ldp	x10, x11, [x0, #TRP_ARG10]
+	ldp	x8, x9, [x0, #TRP_ARG8]
 	ldp	x6, x7, [x0, #TRP_ARG6]
 	ldp	x4, x5, [x0, #TRP_ARG4]
 	ldp	x2, x3, [x0, #TRP_ARG2]
diff --git a/services/std_svc/rmmd/trp/trp_helpers.c b/services/std_svc/rmmd/trp/trp_helpers.c
index 159f3a5..0607864 100644
--- a/services/std_svc/rmmd/trp/trp_helpers.c
+++ b/services/std_svc/rmmd/trp/trp_helpers.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,7 +25,11 @@
 			uint64_t arg4,
 			uint64_t arg5,
 			uint64_t arg6,
-			uint64_t arg7)
+			uint64_t arg7,
+			uint64_t arg8,
+			uint64_t arg9,
+			uint64_t arg10,
+			uint64_t arg11)
 {
 	uint32_t linear_id;
 	trp_args_t *pcpu_smc_args;
@@ -44,6 +48,10 @@
 	write_trp_arg(pcpu_smc_args, TRP_ARG5, arg5);
 	write_trp_arg(pcpu_smc_args, TRP_ARG6, arg6);
 	write_trp_arg(pcpu_smc_args, TRP_ARG7, arg7);
+	write_trp_arg(pcpu_smc_args, TRP_ARG8, arg8);
+	write_trp_arg(pcpu_smc_args, TRP_ARG9, arg9);
+	write_trp_arg(pcpu_smc_args, TRP_ARG10, arg10);
+	write_trp_arg(pcpu_smc_args, TRP_ARG11, arg11);
 
 	return pcpu_smc_args;
 }
@@ -53,6 +61,6 @@
  */
 __dead2 void trp_boot_abort(uint64_t err)
 {
-	(void)trp_smc(set_smc_args(RMM_BOOT_COMPLETE, err, 0, 0, 0, 0, 0, 0));
+	(void)trp_smc(set_smc_args(RMM_BOOT_COMPLETE, err, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
 	panic();
 }
diff --git a/services/std_svc/rmmd/trp/trp_main.c b/services/std_svc/rmmd/trp/trp_main.c
index b75483c..a82966e 100644
--- a/services/std_svc/rmmd/trp/trp_main.c
+++ b/services/std_svc/rmmd/trp/trp_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,6 +15,27 @@
 
 #include <platform_def.h>
 
+#define RMI_ERROR_REALM			2U
+#define RMI_ERROR_NOT_SUPPORTED		6U
+
+#define DIR_BIT_SHIFT			0x8
+#define KEYSET_SHIFT			0xC
+#define	STREAM_ID_MASK			0xFF
+#define STREAM_ID_SHIFT			0x0
+#define SUBSTREAM_MASK			0x7
+#define SUBSTREAM_SHIFT			0x8
+
+#define KEY_SET				0x0
+#define	DIR_VAL				0x0
+#define	SUBSTREAM_VAL			0x1
+#define	STREAM_ID			0x1
+
+#define ENCODE_STREAM_INFO(key, dir, substream, stream_id)			\
+		(((key & 0x1) << KEYSET_SHIFT) |				\
+		((dir & 0x1) << DIR_BIT_SHIFT) |				\
+		((substream && SUBSTREAM_MASK) << SUBSTREAM_SHIFT) |		\
+		((stream_id && STREAM_ID_MASK) << STREAM_ID_SHIFT))
+
 /* Parameters received from the previous image */
 static unsigned int trp_boot_abi_version;
 static uintptr_t trp_shared_region_start;
@@ -129,7 +150,7 @@
 {
 	VERBOSE("Delegating granule 0x%llx\n", x1);
 	smc_ret->x[0] = trp_smc(set_smc_args(RMM_GTSI_DELEGATE, x1,
-						0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
+				0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
 
 	if (smc_ret->x[0] != 0ULL) {
 		ERROR("Granule transition from NON-SECURE type to REALM type "
@@ -145,7 +166,7 @@
 {
 	VERBOSE("Undelegating granule 0x%llx\n", x1);
 	smc_ret->x[0] = trp_smc(set_smc_args(RMM_GTSI_UNDELEGATE, x1,
-						0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
+				0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
 
 	if (smc_ret->x[0] != 0ULL) {
 		ERROR("Granule transition from REALM type to NON-SECURE type "
@@ -154,6 +175,62 @@
 }
 
 /*******************************************************************************
+ * Test the IDE Key management interface
+ ******************************************************************************/
+static void trp_ide_keymgmt_interface_fn(unsigned long long x1, unsigned long long x2,
+					struct trp_smc_result *smc_ret)
+{
+	uint64_t ecam_address = 0U, rp_id = 0U, ide_stream_info;
+	uint64_t keyqw0, keyqw1, keyqw2, keyqw3;
+	uint64_t ifvqw0, ifvqw1;
+	int return_value;
+
+#if RMMD_ENABLE_IDE_KEY_PROG
+	trp_get_test_rootport(&ecam_address, &rp_id);
+#endif /* RMMD_ENABLE_IDE_KEY_PROG */
+	/*
+	 * Dummy values for testing:
+	 * Key set = 0x0
+	 * Dir = 0x0
+	 * Substream = 0x1
+	 * Stream ID = 0x1
+	 */
+	ide_stream_info  = ENCODE_STREAM_INFO(KEY_SET, DIR_VAL, SUBSTREAM_VAL, STREAM_ID);
+
+	/* Dummy key and IV values for testing */
+	keyqw0 = 0xA1B2C3D4E5F60708;
+	keyqw1 = 0x1122334455667788;
+	keyqw2 = 0xDEADBEEFCAFEBABE;
+	keyqw3 = 0x1234567890ABCDEF;
+	ifvqw0 = 0xABCDEF0123456789;
+	ifvqw1 = 0x9876543210FEDCBA;
+
+	return_value = trp_smc(set_smc_args(RMM_IDE_KEY_PROG, ecam_address, rp_id,
+				ide_stream_info, keyqw0, keyqw1, keyqw2, keyqw3, ifvqw0,
+				ifvqw1, 0UL, 0UL));
+
+	INFO("return value from RMM_IDE_KEY_PROG = %d\n", return_value);
+
+	return_value = trp_smc(set_smc_args(RMM_IDE_KEY_SET_GO, ecam_address, rp_id,
+				ide_stream_info, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
+
+	INFO("return value from RMM_IDE_KEY_SET_GO = %d\n", return_value);
+
+	return_value = trp_smc(set_smc_args(RMM_IDE_KEY_SET_STOP, ecam_address, rp_id,
+				ide_stream_info, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
+
+	INFO("return value from RMM_IDE_KEY_SET_STOP = %d\n", return_value);
+
+	return_value = trp_smc(set_smc_args(RMM_IDE_KM_PULL_RESPONSE, ecam_address, rp_id,
+				0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
+
+	INFO("return value from RMM_IDE_KEY_SET_STOP = %d\n", return_value);
+
+	smc_ret->x[0] = RMI_ERROR_NOT_SUPPORTED;
+
+}
+
+/*******************************************************************************
  * Main RMI SMC handler function
  ******************************************************************************/
 void trp_rmi_handler(unsigned long fid,
@@ -179,6 +256,9 @@
 	case RMI_RMM_GRANULE_UNDELEGATE:
 		trp_asc_mark_nonsecure(x1, smc_ret);
 		break;
+	case RMI_RMM_PDEV_CREATE:
+		trp_ide_keymgmt_interface_fn(x1, x2, smc_ret);
+		break;
 	default:
 		ERROR("Invalid SMC code to %s, FID %lx\n", __func__, fid);
 		smc_ret->x[0] = SMC_UNK;
diff --git a/services/std_svc/rmmd/trp/trp_private.h b/services/std_svc/rmmd/trp/trp_private.h
index d8c6960..16edc5e 100644
--- a/services/std_svc/rmmd/trp/trp_private.h
+++ b/services/std_svc/rmmd/trp/trp_private.h
@@ -28,6 +28,7 @@
 #define RMI_RMM_REQ_VERSION		SMC64_RMI_FID(U(0))
 #define RMI_RMM_GRANULE_DELEGATE	SMC64_RMI_FID(U(1))
 #define RMI_RMM_GRANULE_UNDELEGATE	SMC64_RMI_FID(U(2))
+#define RMI_RMM_PDEV_CREATE		SMC64_RMI_FID(U(0x26))
 
 /* Definitions for RMI VERSION */
 #define RMI_ABI_VERSION_MAJOR		U(0x0)