fix(intel): support generic mailbox command in SiPSVC V3

Support generic mailbox command in the SiPSVC V3 framework
and add filter to avoid executing FCS related commands in
the generic mailbox format.

Change-Id: I682da2d37c68773ef34194abd6d49c52ddc5c26e
Signed-off-by: Girisha Dengi <girisha.dengi@intel.com>
Signed-off-by: Jit Loon Lim <jit.loon.lim@altera.com>
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index b4978d0..ce70220 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -953,6 +953,58 @@
 	}
 }
 
+static inline bool is_gen_mbox_cmd_allowed(uint32_t cmd)
+{
+	/* Check if the command is allowed to be executed in generic mbox format */
+	bool is_cmd_allowed = false;
+
+	switch (cmd) {
+	case ALTERA_SIP_SMC_ASYNC_FCS_OPEN_CS_SESSION:
+	case ALTERA_SIP_SMC_ASYNC_FCS_CLOSE_CS_SESSION:
+	case ALTERA_SIP_SMC_ASYNC_FCS_IMPORT_CS_KEY:
+	case ALTERA_SIP_SMC_ASYNC_FCS_EXPORT_CS_KEY:
+	case ALTERA_SIP_SMC_ASYNC_FCS_REMOVE_CS_KEY:
+	case ALTERA_SIP_SMC_ASYNC_FCS_GET_CS_KEY_INFO:
+	case ALTERA_SIP_SMC_ASYNC_FCS_CREATE_CS_KEY:
+	case ALTERA_SIP_SMC_ASYNC_FCS_RANDOM_NUMBER_EXT:
+	case ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_INIT:
+	case ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_UPDATE:
+	case ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_FINALIZE:
+	case ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_INIT:
+	case ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_UPDATE:
+	case ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_FINALIZE:
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIGN_INIT:
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIGN_FINALIZE:
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_INIT:
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_UPDATE:
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE:
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_SMMU_UPDATE:
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_SMMU_FINALIZE:
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIG_VERIFY_INIT:
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIG_VERIFY_FINALIZE:
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_INIT:
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_UPDATE:
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_FINALIZE:
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_SMMU_UPDATE:
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_SMMU_FINALIZE:
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_GET_PUBKEY_INIT:
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_GET_PUBKEY_FINALIZE:
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDH_REQUEST_INIT:
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDH_REQUEST_FINALIZE:
+	case ALTERA_SIP_SMC_ASYNC_FCS_HKDF_REQUEST:
+	case ALTERA_SIP_SMC_ASYNC_FCS_CRYPTION_EXT:
+	case ALTERA_SIP_SMC_ASYNC_FCS_CRYPTION:
+		/* These commands are not supported in the generic mailbox format. */
+		break;
+
+	default:
+		is_cmd_allowed = true;
+		break;
+	} /* switch */
+
+	return is_cmd_allowed;
+}
+
 /*
  * This function is responsible for handling all SiP SVC V3 calls from the
  * non-secure world.
@@ -1235,6 +1287,64 @@
 		SMC_RET1(handle, status);
 	}
 
+	case ALTERA_SIP_SMC_ASYNC_GEN_MBOX_CMD:
+	{
+		/* Filter the required commands here. */
+		if (!is_gen_mbox_cmd_allowed(smc_fid)) {
+			status = INTEL_SIP_SMC_STATUS_REJECTED;
+			SMC_RET1(handle, status);
+		}
+
+		/* Collect all the args passed in, and send the mailbox command. */
+		uint32_t mbox_cmd = (uint32_t)x2;
+		uint32_t *cmd_payload_addr = NULL;
+		uint32_t cmd_payload_len = (uint32_t)x4 / MBOX_WORD_BYTE;
+		uint32_t *resp_payload_addr = NULL;
+		uint32_t resp_payload_len = (uint32_t)x6 / MBOX_WORD_BYTE;
+
+		if ((cmd_payload_len > MBOX_GEN_CMD_MAX_WORDS) ||
+		    (resp_payload_len > MBOX_GEN_CMD_MAX_WORDS)) {
+			ERROR("MBOX: 0x%x: Command/Response payload length exceeds max limit\n",
+				smc_fid);
+			status = INTEL_SIP_SMC_STATUS_REJECTED;
+			SMC_RET1(handle, status);
+		}
+
+		/* Make sure we have valid command payload length and buffer */
+		if (cmd_payload_len != 0U) {
+			cmd_payload_addr = (uint32_t *)x3;
+			if (cmd_payload_addr == NULL) {
+				ERROR("MBOX: 0x%x: Command payload address is NULL\n",
+					smc_fid);
+				status = INTEL_SIP_SMC_STATUS_REJECTED;
+				SMC_RET1(handle, status);
+			}
+		}
+
+		/* Make sure we have valid response payload length and buffer */
+		if (resp_payload_len != 0U) {
+			resp_payload_addr = (uint32_t *)x5;
+			if (resp_payload_addr == NULL) {
+				ERROR("MBOX: 0x%x: Response payload address is NULL\n",
+					smc_fid);
+				status = INTEL_SIP_SMC_STATUS_REJECTED;
+				SMC_RET1(handle, status);
+			}
+		}
+
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   mbox_cmd,
+						   (uint32_t *)cmd_payload_addr,
+						   cmd_payload_len,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_ret_nbytes_cb,
+						   (uint32_t *)resp_payload_addr,
+						   resp_payload_len);
+
+		SMC_RET1(handle, status);
+	}
+
 	case ALTERA_SIP_SMC_ASYNC_FCS_RANDOM_NUMBER_EXT:
 	{
 		uint32_t session_id = (uint32_t)x2;