feat(rmmd): add RMM_MECID_KEY_UPDATE call

With this addition, TF-A now has an SMC call to handle the
update of MEC keys associated to MECIDs.

The behavior of this newly added call is empty for now until an
implementation for the MPE (Memory Protection Engine) driver is
available. Only parameter sanitization has been implemented.

Signed-off-by: Tushar Khandelwal <tushar.khandelwal@arm.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Signed-off-by: Juan Pablo Conde <juanpablo.conde@arm.com>
Change-Id: I2a969310b47e8c6da1817a79be0cd56158c6efc3
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index 10a2c42..3ebae13 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_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
  */
@@ -470,6 +470,33 @@
 	return E_RMM_OK;
 }
 
+/*
+ * Update encryption key associated with @mecid.
+ */
+static int rmmd_mecid_key_update(uint64_t mecid)
+{
+	uint64_t mecid_width, mecid_width_mask;
+	int ret;
+
+	/*
+	 * Check whether the mecid parameter is at most MECIDR_EL2.MECIDWidthm1 + 1
+	 * in length.
+	 */
+	mecid_width = ((read_mecidr_el2() >> MECIDR_EL2_MECIDWidthm1_SHIFT) &
+		MECIDR_EL2_MECIDWidthm1_MASK) + 1;
+	mecid_width_mask = ((1 << mecid_width) - 1);
+	if ((mecid & ~mecid_width_mask) != 0U) {
+		return E_RMM_INVAL;
+	}
+
+	ret = plat_rmmd_mecid_key_update(mecid);
+
+	if (ret != 0) {
+		return E_RMM_UNK;
+	}
+	return E_RMM_OK;
+}
+
 /*******************************************************************************
  * This function handles RMM-EL3 interface SMCs
  ******************************************************************************/
@@ -519,6 +546,9 @@
 		VERBOSE("RMMD: running rmmd_rmm_sync_exit\n");
 		rmmd_rmm_sync_exit(x1);
 
+	case RMM_MECID_KEY_UPDATE:
+		ret = rmmd_mecid_key_update(x1);
+		SMC_RET1(handle, ret);
 	default:
 		WARN("RMMD: Unsupported RMM-EL3 call 0x%08x\n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);