build(intel): initial commit for crypto driver

This patch adds driver for Intel FPGA's Crypto Services.
These services are provided by Intel platform
Secure Device Manager(SDM) and are made accessible by
processor components (ie ATF).
Below is the list of enabled features:
- Send SDM certificates
- Efuse provision data dump
- Encryption/decryption service
- Hardware IP random number generator

Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi <muhammad.hadi.asyrafi.abdul.halim@intel.com>
Signed-off-by: Sieu Mun Tang <sieu.mun.tang@intel.com>
Change-Id: If7604cd1cacf27a38a9a29ec6b85b07385e1ea26
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index bf5cc14..f7554c6 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -65,6 +65,7 @@
 		plat/intel/soc/common/socfpga_psci.c			\
 		plat/intel/soc/common/socfpga_sip_svc.c			\
 		plat/intel/soc/common/socfpga_topology.c		\
+		plat/intel/soc/common/sip/socfpga_sip_fcs.c		\
 		plat/intel/soc/common/soc/socfpga_mailbox.c		\
 		plat/intel/soc/common/soc/socfpga_reset_manager.c
 
diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h
new file mode 100644
index 0000000..ff10d36
--- /dev/null
+++ b/plat/intel/soc/common/include/socfpga_fcs.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOCFPGA_FCS_H
+#define SOCFPGA_FCS_H
+
+/* FCS Definitions */
+
+#define FCS_RANDOM_WORD_SIZE		8U
+#define FCS_PROV_DATA_WORD_SIZE		44U
+
+#define FCS_RANDOM_BYTE_SIZE		(FCS_RANDOM_WORD_SIZE * 4U)
+#define FCS_PROV_DATA_BYTE_SIZE		(FCS_PROV_DATA_WORD_SIZE * 4U)
+
+#define FCS_CRYPTION_DATA_0		0x10100
+
+/* FCS Payload Structure */
+
+typedef struct fcs_crypt_payload_t {
+	uint32_t first_word;
+	uint32_t src_addr;
+	uint32_t src_size;
+	uint32_t dst_addr;
+	uint32_t dst_size;
+} fcs_crypt_payload;
+
+/* Functions Definitions */
+
+uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size,
+				uint32_t *mbox_error);
+uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size,
+				uint32_t *send_id);
+uint32_t intel_fcs_get_provision_data(uint32_t *send_id);
+uint32_t intel_fcs_cryption(uint32_t mode, uint32_t src_addr,
+			uint32_t src_size, uint32_t dst_addr,
+			uint32_t dst_size, uint32_t *send_id);
+
+#endif /* SOCFPGA_FCS_H */
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index bc10dd8..6b7e0fc 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -40,6 +40,7 @@
 #define MBOX_CMD_SYNC			0x01
 #define MBOX_CMD_RESTART		0x02
 #define MBOX_CMD_CANCEL			0x03
+#define MBOX_CMD_VAB_SRC_CERT		0x0B
 #define MBOX_CMD_GET_IDCODE		0x10
 #define MBOX_CMD_REBOOT_HPS		0x47
 
@@ -61,6 +62,11 @@
 #define MBOX_RSU_UPDATE			0x5C
 #define MBOX_HPS_STAGE_NOTIFY		0x5D
 
+/* FCS Command */
+#define MBOX_FCS_GET_PROVISION			0x7B
+#define MBOX_FCS_ENCRYPT_REQ			0x7E
+#define MBOX_FCS_DECRYPT_REQ			0x7F
+#define MBOX_FCS_RANDOM_GEN			0x80
 
 /* Mailbox Definitions */
 
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
index 92adfa3..6eca197 100644
--- a/plat/intel/soc/common/include/socfpga_sip_svc.h
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,6 +15,8 @@
 #define INTEL_SIP_SMC_STATUS_ERROR			0x4
 #define INTEL_SIP_SMC_RSU_ERROR				0x7
 
+/* SiP mailbox error code */
+#define GENERIC_RESPONSE_ERROR				0x3FF
 
 /* SMC SiP service function identifier */
 
@@ -35,6 +37,8 @@
 #define INTEL_SIP_SMC_RSU_UPDATE			0xC200000C
 #define INTEL_SIP_SMC_RSU_NOTIFY			0xC200000E
 #define INTEL_SIP_SMC_RSU_RETRY_COUNTER			0xC200000F
+#define INTEL_SIP_SMC_RSU_DCMF_VERSION			0xC2000010
+#define INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION		0xC2000011
 
 /* Send Mailbox Command */
 #define INTEL_SIP_SMC_MBOX_SEND_CMD			0xC200001E
diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
new file mode 100644
index 0000000..fe5461b
--- /dev/null
+++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <lib/mmio.h>
+
+#include "socfpga_fcs.h"
+#include "socfpga_mailbox.h"
+#include "socfpga_sip_svc.h"
+
+uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size,
+					uint32_t *mbox_error)
+{
+	int status;
+	unsigned int i;
+	unsigned int resp_len = FCS_RANDOM_WORD_SIZE;
+	uint32_t random_data[FCS_RANDOM_WORD_SIZE] = {0U};
+
+	if (!is_address_in_ddr_range(addr, FCS_RANDOM_BYTE_SIZE)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_RANDOM_GEN, NULL, 0U,
+			CMD_CASUAL, random_data, &resp_len);
+
+	if (status < 0) {
+		*mbox_error = -status;
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	if (resp_len != FCS_RANDOM_WORD_SIZE) {
+		*mbox_error = GENERIC_RESPONSE_ERROR;
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	*ret_size = FCS_RANDOM_BYTE_SIZE;
+
+	for (i = 0U; i < FCS_RANDOM_WORD_SIZE; i++) {
+		mmio_write_32(addr, random_data[i]);
+		addr += MBOX_WORD_BYTE;
+	}
+
+	flush_dcache_range(addr - *ret_size, *ret_size);
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
+uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size,
+					uint32_t *send_id)
+{
+	int status;
+
+	if (!is_address_in_ddr_range(addr, size)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT,
+				(uint32_t *)addr, size / MBOX_WORD_BYTE,
+				CMD_DIRECT);
+
+	if (status < 0) {
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
+uint32_t intel_fcs_get_provision_data(uint32_t *send_id)
+{
+	int status;
+
+	status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_PROVISION,
+				NULL, 0U, CMD_DIRECT);
+
+	if (status < 0) {
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
+uint32_t intel_fcs_cryption(uint32_t mode, uint32_t src_addr,
+		uint32_t src_size, uint32_t dst_addr,
+		uint32_t dst_size, uint32_t *send_id)
+{
+	int status;
+	uint32_t cmd;
+
+	if (!is_address_in_ddr_range(src_addr, src_size) ||
+		!is_address_in_ddr_range(dst_addr, dst_size)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	fcs_crypt_payload payload = {
+		FCS_CRYPTION_DATA_0,
+		src_addr,
+		src_size,
+		dst_addr,
+		dst_size };
+
+	if (mode != 0U) {
+		cmd = MBOX_FCS_ENCRYPT_REQ;
+	} else {
+		cmd = MBOX_FCS_DECRYPT_REQ;
+	}
+
+	status = mailbox_send_cmd_async(send_id, cmd, (uint32_t *) &payload,
+				sizeof(fcs_crypt_payload) / MBOX_WORD_BYTE,
+				CMD_INDIRECT);
+	inv_dcache_range(dst_addr, dst_size);
+
+	if (status < 0) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index d53e8de..16f8145 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -10,6 +10,7 @@
 #include <lib/mmio.h>
 #include <tools_share/uuid.h>
 
+#include "socfpga_fcs.h"
 #include "socfpga_mailbox.h"
 #include "socfpga_reset_manager.h"
 #include "socfpga_sip_svc.h"
@@ -139,21 +140,23 @@
 		status = mailbox_read_response(job_id,
 				resp, &resp_len);
 
-		if (resp_len < 0)
+		if (status < 0) {
 			break;
+		}
 
 		max_blocks++;
 
 		if (mark_last_buffer_xfer_completed(
-			&completed_addr[*count]) == 0)
+			&completed_addr[*count]) == 0) {
 			*count = *count + 1;
-		else
+		} else {
 			break;
+		}
 	}
 
 	if (*count <= 0) {
-		if (resp_len != MBOX_NO_RESPONSE &&
-			resp_len != MBOX_TIMEOUT && resp_len != 0) {
+		if (status != MBOX_NO_RESPONSE &&
+			status != MBOX_TIMEOUT && resp_len != 0) {
 			mailbox_clear_response();
 			return INTEL_SIP_SMC_STATUS_ERROR;
 		}
@@ -430,9 +433,9 @@
 			 u_register_t flags)
 {
 	uint32_t retval = 0;
-	uint32_t status = INTEL_SIP_SMC_STATUS_OK;
 	uint32_t completed_addr[3];
 	uint64_t rsu_respbuf[9];
+	int status = INTEL_SIP_SMC_STATUS_OK;
 	int mbox_status;
 	unsigned int len_in_resp;
 	u_register_t x5, x6;
diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk
index 8bbd010..d05d2ad 100644
--- a/plat/intel/soc/stratix10/platform.mk
+++ b/plat/intel/soc/stratix10/platform.mk
@@ -63,6 +63,7 @@
 		plat/intel/soc/common/socfpga_psci.c			\
 		plat/intel/soc/common/socfpga_sip_svc.c			\
 		plat/intel/soc/common/socfpga_topology.c		\
+		plat/intel/soc/common/sip/socfpga_sip_fcs.c		\
 		plat/intel/soc/common/soc/socfpga_mailbox.c		\
 		plat/intel/soc/common/soc/socfpga_reset_manager.c