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/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;