feat(spmd): add FFA_MSG_SEND_DIR_REQ2

Add handling for FF-A 1.2 FFA_MSG_SEND_DIR_REQ2 interface.
Handler validates security states of sender/receiver pairs
and forwards the call to other world if necessary.

Signed-off-by: Kathleen Capella <kathleen.capella@arm.com>
Change-Id: I02a60362d8d9a50fcc0b6a84753cba274ba5eb1b
diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h
index c5f6000..75f1ef8 100644
--- a/include/services/ffa_svc.h
+++ b/include/services/ffa_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,7 +24,7 @@
 
 /* The macros below are used to identify FFA calls from the SMC function ID */
 #define FFA_FNUM_MIN_VALUE	U(0x60)
-#define FFA_FNUM_MAX_VALUE	U(0x8C)
+#define FFA_FNUM_MAX_VALUE	U(0x8D)
 #define is_ffa_fid(fid) __extension__ ({		\
 	__typeof__(fid) _fid = (fid);			\
 	((GET_SMC_NUM(_fid) >= FFA_FNUM_MIN_VALUE) &&	\
@@ -123,6 +123,7 @@
 /* FF-A v1.2 */
 #define FFA_FNUM_PARTITION_INFO_GET_REGS	U(0x8B)
 #define FFA_FNUM_EL3_INTR_HANDLE		U(0x8C)
+#define FFA_FNUM_MSG_SEND_DIRECT_REQ2		U(0x8D)
 
 #define FFA_FNUM_CONSOLE_LOG			U(0x8A)
 
@@ -195,6 +196,8 @@
 #define FFA_PARTITION_INFO_GET_REGS_SMC64 \
 	FFA_FID(SMC_64, FFA_FNUM_PARTITION_INFO_GET_REGS)
 #define FFA_CONSOLE_LOG_SMC64 FFA_FID(SMC_64, FFA_FNUM_CONSOLE_LOG)
+#define FFA_MSG_SEND_DIRECT_REQ2_SMC64 \
+	FFA_FID(SMC_64, FFA_FNUM_MSG_SEND_DIRECT_REQ2)
 
 /*
  * FF-A partition properties values.
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 1d0bd00..67909b6 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -1151,6 +1151,25 @@
 		}
 		break; /* Not reached */
 
+	case FFA_MSG_SEND_DIRECT_REQ2_SMC64:
+		if (!secure_origin) {
+			/* Validate source endpoint is non-secure for non-secure caller. */
+			if (ffa_is_secure_world_id(ffa_endpoint_source(x1))) {
+				return spmd_ffa_error_return(handle,
+						FFA_ERROR_INVALID_PARAMETER);
+			}
+		}
+		/* FFA_MSG_SEND_DIRECT_REQ2 not used for framework messages. */
+		if (secure_origin && spmd_is_spmc_message(x1)) {
+			return spmd_ffa_error_return(handle, FFA_ERROR_INVALID_PARAMETER);
+		} else {
+			/* Forward direct message to the other world */
+			return spmd_smc_forward(smc_fid, secure_origin,
+						x1, x2, x3, x4, cookie,
+						handle, flags);
+		}
+		break; /* Not reached */
+
 	case FFA_MSG_SEND_DIRECT_RESP_SMC32:
 	case FFA_MSG_SEND_DIRECT_RESP_SMC64:
 		if (secure_origin && (spmd_is_spmc_message(x1) ||