feat(intel): support version 2 SiP SVC SMC function ID for non-mailbox commands

A separated SMC function ID of non-mailbox command
is introduced for the new format of SMC protocol.

The new format of SMC procotol will be started
using by Zephyr.

Signed-off-by: Siew Chin Lim <elly.siew.chin.lim@intel.com>
Signed-off-by: Sieu Mun Tang <sieu.mun.tang@intel.com>
Change-Id: I01cff2739364b1bda2ebb9507ddbcef6095f5d29
diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c
index 7b3b0e2..211a7b7 100644
--- a/plat/intel/soc/agilex/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex/bl2_plat_setup.c
@@ -84,7 +84,7 @@
 
 	if (!intel_mailbox_is_fpga_not_ready()) {
 		socfpga_bridges_enable(SOC2FPGA_MASK | LWHPS2FPGA_MASK |
-			FPGA2SOC_MASK);
+					FPGA2SOC_MASK);
 	}
 }
 
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index 0e5f911..6fe0be1 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -65,6 +65,7 @@
 		plat/intel/soc/agilex/soc/agilex_clock_manager.c	\
 		plat/intel/soc/common/socfpga_psci.c			\
 		plat/intel/soc/common/socfpga_sip_svc.c			\
+		plat/intel/soc/common/socfpga_sip_svc_v2.c		\
 		plat/intel/soc/common/socfpga_topology.c		\
 		plat/intel/soc/common/sip/socfpga_sip_ecc.c		\
 		plat/intel/soc/common/sip/socfpga_sip_fcs.c		\
diff --git a/plat/intel/soc/common/include/socfpga_reset_manager.h b/plat/intel/soc/common/include/socfpga_reset_manager.h
index 35ee672..cce16ab 100644
--- a/plat/intel/soc/common/include/socfpga_reset_manager.h
+++ b/plat/intel/soc/common/include/socfpga_reset_manager.h
@@ -9,15 +9,15 @@
 
 #include "socfpga_plat_def.h"
 
-#define SOCFPGA_BRIDGE_ENABLE	BIT(0)
-#define SOCFPGA_BRIDGE_HAS_MASK	BIT(1)
+#define SOCFPGA_BRIDGE_ENABLE			BIT(0)
+#define SOCFPGA_BRIDGE_HAS_MASK			BIT(1)
 
-#define SOC2FPGA_MASK		(1<<0)
-#define LWHPS2FPGA_MASK		(1<<1)
-#define FPGA2SOC_MASK		(1<<2)
-#define F2SDRAM0_MASK		(1<<3)
-#define F2SDRAM1_MASK		(1<<4)
-#define F2SDRAM2_MASK		(1<<5)
+#define SOC2FPGA_MASK				(1<<0)
+#define LWHPS2FPGA_MASK				(1<<1)
+#define FPGA2SOC_MASK				(1<<2)
+#define F2SDRAM0_MASK				(1<<3)
+#define F2SDRAM1_MASK				(1<<4)
+#define F2SDRAM2_MASK				(1<<5)
 
 /* Register Mapping */
 
@@ -111,7 +111,7 @@
 /* Macros */
 
 #define SOCFPGA_RSTMGR(_reg)		(SOCFPGA_RSTMGR_REG_BASE \
-						+ (SOCFPGA_RSTMGR_##_reg))
+					+ (SOCFPGA_RSTMGR_##_reg))
 #define RSTMGR_FIELD(_reg, _field)	(RSTMGR_##_reg##MODRST_##_field)
 
 /* Function Declarations */
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
index 9591983..cc44db5 100644
--- a/plat/intel/soc/common/include/socfpga_sip_svc.h
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -19,7 +19,12 @@
 /* SiP mailbox error code */
 #define GENERIC_RESPONSE_ERROR					0x3FF
 
-/* SMC SiP service function identifier */
+/* SiP V2 command code range */
+#define INTEL_SIP_SMC_CMD_MASK					0xFFFF
+#define INTEL_SIP_SMC_CMD_V2_RANGE_BEGIN			0x400
+#define INTEL_SIP_SMC_CMD_V2_RANGE_END				0x4FF
+
+/* SMC SiP service function identifier for version 1 */
 
 /* FPGA Reconfig */
 #define INTEL_SIP_SMC_FPGA_CONFIG_START				0xC2000001
@@ -126,6 +131,18 @@
 /* Non-mailbox SMC Call */
 #define INTEL_SIP_SMC_SVC_VERSION				0xC2000200
 
+/**
+ * SMC SiP service function identifier for version 2
+ * Command code from 0x400 ~ 0x4FF
+ */
+
+/* V2: Non-mailbox function identifier */
+#define INTEL_SIP_SMC_V2_GET_SVC_VERSION			0xC2000400
+#define INTEL_SIP_SMC_V2_REG_READ				0xC2000401
+#define INTEL_SIP_SMC_V2_REG_WRITE				0xC2000402
+#define INTEL_SIP_SMC_V2_REG_UPDATE				0xC2000403
+#define INTEL_SIP_SMC_V2_HPS_SET_BRIDGES			0xC2000404
+
 /* SMC function IDs for SiP Service queries */
 #define SIP_SVC_CALL_COUNT					0x8200ff00
 #define SIP_SVC_UID						0x8200ff01
@@ -154,7 +171,24 @@
 bool cold_reset_for_ecc_dbe(void);
 uint32_t intel_ecc_dbe_notification(uint64_t dbe_value);
 
+/* Secure register access */
+uint32_t intel_secure_reg_read(uint64_t reg_addr, uint32_t *retval);
+uint32_t intel_secure_reg_write(uint64_t reg_addr, uint32_t val,
+				uint32_t *retval);
+uint32_t intel_secure_reg_update(uint64_t reg_addr, uint32_t mask,
+				 uint32_t val, uint32_t *retval);
+
 /* Miscellaneous HPS services */
 uint32_t intel_hps_set_bridges(uint64_t enable, uint64_t mask);
 
+/* SiP Service handler for version 2 */
+uintptr_t sip_smc_handler_v2(uint32_t smc_fid,
+			 u_register_t x1,
+			 u_register_t x2,
+			 u_register_t x3,
+			 u_register_t x4,
+			 void *cookie,
+			 void *handle,
+			 u_register_t flags);
+
 #endif /* SOCFPGA_SIP_SVC_H */
diff --git a/plat/intel/soc/common/soc/socfpga_reset_manager.c b/plat/intel/soc/common/soc/socfpga_reset_manager.c
index c2d5535..bb4efab 100644
--- a/plat/intel/soc/common/soc/socfpga_reset_manager.c
+++ b/plat/intel/soc/common/soc/socfpga_reset_manager.c
@@ -4,9 +4,9 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <errno.h>
 #include <common/debug.h>
 #include <drivers/delay_timer.h>
-#include <errno.h>
 #include <lib/mmio.h>
 
 #include "socfpga_f2sdram_manager.h"
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index f1f4a5a..e7344cb 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -593,14 +593,14 @@
 {
 	int status = 0;
 
-	if (enable & SOCFPGA_BRIDGE_ENABLE) {
-		if ((enable & SOCFPGA_BRIDGE_HAS_MASK) != 0) {
+	if ((enable & SOCFPGA_BRIDGE_ENABLE) != 0U) {
+		if ((enable & SOCFPGA_BRIDGE_HAS_MASK) != 0U) {
 			status = socfpga_bridges_enable((uint32_t)mask);
 		} else {
 			status = socfpga_bridges_enable(~0);
 		}
 	} else {
-		if ((enable & SOCFPGA_BRIDGE_HAS_MASK) != 0) {
+		if ((enable & SOCFPGA_BRIDGE_HAS_MASK) != 0U) {
 			status = socfpga_bridges_disable((uint32_t)mask);
 		} else {
 			status = socfpga_bridges_disable(~0);
@@ -618,7 +618,7 @@
  * This function is responsible for handling all SiP calls from the NS world
  */
 
-uintptr_t sip_smc_handler(uint32_t smc_fid,
+uintptr_t sip_smc_handler_v1(uint32_t smc_fid,
 			 u_register_t x1,
 			 u_register_t x2,
 			 u_register_t x3,
@@ -835,6 +835,14 @@
 		status = intel_hps_set_bridges(x1, x2);
 		SMC_RET1(handle, status);
 
+	case INTEL_SIP_SMC_HWMON_READTEMP:
+		status = intel_hwmon_readtemp(x1, &retval);
+		SMC_RET2(handle, status, retval);
+
+	case INTEL_SIP_SMC_HWMON_READVOLT:
+		status = intel_hwmon_readvolt(x1, &retval);
+		SMC_RET2(handle, status, retval);
+
 	case INTEL_SIP_SMC_FCS_PSGSIGMA_TEARDOWN:
 		status = intel_fcs_sigma_teardown(x1, &mbox_error);
 		SMC_RET2(handle, status, mbox_error);
@@ -1016,20 +1024,33 @@
 					SIP_SVC_VERSION_MAJOR,
 					SIP_SVC_VERSION_MINOR);
 
-	case INTEL_SIP_SMC_HWMON_READTEMP:
-		status = intel_hwmon_readtemp(x1, &retval);
-		SMC_RET2(handle, status, retval);
-
-	case INTEL_SIP_SMC_HWMON_READVOLT:
-		status = intel_hwmon_readvolt(x1, &retval);
-		SMC_RET2(handle, status, retval);
-
 	default:
 		return socfpga_sip_handler(smc_fid, x1, x2, x3, x4,
 			cookie, handle, flags);
 	}
 }
 
+uintptr_t sip_smc_handler(uint32_t smc_fid,
+			 u_register_t x1,
+			 u_register_t x2,
+			 u_register_t x3,
+			 u_register_t x4,
+			 void *cookie,
+			 void *handle,
+			 u_register_t flags)
+{
+	uint32_t cmd = smc_fid & INTEL_SIP_SMC_CMD_MASK;
+
+	if (cmd >= INTEL_SIP_SMC_CMD_V2_RANGE_BEGIN &&
+	    cmd <= INTEL_SIP_SMC_CMD_V2_RANGE_END) {
+		return sip_smc_handler_v2(smc_fid, x1, x2, x3, x4,
+			cookie, handle, flags);
+	} else {
+		return sip_smc_handler_v1(smc_fid, x1, x2, x3, x4,
+			cookie, handle, flags);
+	}
+}
+
 DECLARE_RT_SVC(
 	socfpga_sip_svc,
 	OEN_SIP_START,
diff --git a/plat/intel/soc/common/socfpga_sip_svc_v2.c b/plat/intel/soc/common/socfpga_sip_svc_v2.c
new file mode 100644
index 0000000..d1d1992
--- /dev/null
+++ b/plat/intel/soc/common/socfpga_sip_svc_v2.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2022, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/mmio.h>
+
+#include "socfpga_sip_svc.h"
+
+uintptr_t sip_smc_handler_v2(uint32_t smc_fid,
+				u_register_t x1,
+				u_register_t x2,
+				u_register_t x3,
+				u_register_t x4,
+				void *cookie,
+				void *handle,
+				u_register_t flags)
+{
+	uint32_t retval = 0;
+	int status = INTEL_SIP_SMC_STATUS_OK;
+
+	switch (smc_fid) {
+	case INTEL_SIP_SMC_V2_GET_SVC_VERSION:
+		SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, x1,
+				SIP_SVC_VERSION_MAJOR,
+				SIP_SVC_VERSION_MINOR);
+
+	case INTEL_SIP_SMC_V2_REG_READ:
+		status = intel_secure_reg_read(x2, &retval);
+		SMC_RET4(handle, status, x1, retval, x2);
+
+	case INTEL_SIP_SMC_V2_REG_WRITE:
+		status = intel_secure_reg_write(x2, (uint32_t)x3, &retval);
+		SMC_RET4(handle, status, x1, retval, x2);
+
+	case INTEL_SIP_SMC_V2_REG_UPDATE:
+		status = intel_secure_reg_update(x2, (uint32_t)x3,
+				(uint32_t)x4, &retval);
+		SMC_RET4(handle, status, x1, retval, x2);
+
+	case INTEL_SIP_SMC_V2_HPS_SET_BRIDGES:
+		status = intel_hps_set_bridges(x2, x3);
+		SMC_RET2(handle, status, x1);
+
+	default:
+		ERROR("%s: unhandled SMC V2 (0x%x)\n", __func__, smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+}
diff --git a/plat/intel/soc/n5x/platform.mk b/plat/intel/soc/n5x/platform.mk
index b72bcc4..953bf0c 100644
--- a/plat/intel/soc/n5x/platform.mk
+++ b/plat/intel/soc/n5x/platform.mk
@@ -38,6 +38,7 @@
 		plat/intel/soc/n5x/bl31_plat_setup.c			\
 		plat/intel/soc/common/socfpga_psci.c			\
 		plat/intel/soc/common/socfpga_sip_svc.c			\
+		plat/intel/soc/common/socfpga_sip_svc_v2.c		\
 		plat/intel/soc/common/socfpga_topology.c		\
 		plat/intel/soc/common/sip/socfpga_sip_ecc.c             \
 		plat/intel/soc/common/sip/socfpga_sip_fcs.c		\
diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c
index 92d827a..73e3216 100644
--- a/plat/intel/soc/stratix10/bl2_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl2_plat_setup.c
@@ -82,8 +82,8 @@
 
 	if (!intel_mailbox_is_fpga_not_ready()) {
 		socfpga_bridges_enable(SOC2FPGA_MASK | LWHPS2FPGA_MASK |
-				FPGA2SOC_MASK | F2SDRAM0_MASK | F2SDRAM1_MASK |
-				F2SDRAM2_MASK);
+					FPGA2SOC_MASK | F2SDRAM0_MASK | F2SDRAM1_MASK |
+					F2SDRAM2_MASK);
 	}
 }
 
diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk
index 273b975..8b39b6f 100644
--- a/plat/intel/soc/stratix10/platform.mk
+++ b/plat/intel/soc/stratix10/platform.mk
@@ -64,6 +64,7 @@
 		plat/intel/soc/stratix10/bl31_plat_setup.c	 	\
 		plat/intel/soc/common/socfpga_psci.c			\
 		plat/intel/soc/common/socfpga_sip_svc.c			\
+		plat/intel/soc/common/socfpga_sip_svc_v2.c		\
 		plat/intel/soc/common/socfpga_topology.c		\
 		plat/intel/soc/common/sip/socfpga_sip_ecc.c		\
 		plat/intel/soc/common/sip/socfpga_sip_fcs.c		\