Implement SMCCC_ARCH_SOC_ID SMC call

Implemented SMCCC_ARCH_SOC_ID call in order to get below
SOC information:

1. SOC revision
2. SOC version

Implementation done using below SMCCC specification document:
https://developer.arm.com/docs/den0028/c

Signed-off-by: Manish V Badarkhe <Manish.Badarkhe@arm.com>
Change-Id: Ie0595f1c345a6429a6fb4a7f05534a0ca9c9a48b
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index d634d2e..d6572f5 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -1116,6 +1116,35 @@
 the log output. The implementation should be robust to future changes that
 increase the number of log levels.
 
+Function : plat_get_soc_version()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : int32_t
+
+This function returns soc version which mainly consist of below fields
+
+::
+
+    soc_version[30:24] = JEP-106 continuation code for the SiP
+    soc_version[23:16] = JEP-106 identification code with parity bit for the SiP
+
+Function : plat_get_soc_revision()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : int32_t
+
+This function returns soc revision in below format
+
+::
+
+    soc_revision[0:30] = SOC revision of specific SOC
+
 Modifications specific to a Boot Loader stage
 ---------------------------------------------
 
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 6c2925a..a84047a 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -148,6 +148,12 @@
 #define ARM_ROTPK_DEVEL_RSA_ID		2
 #define ARM_ROTPK_DEVEL_ECDSA_ID	3
 
+/* Defines used to retrieve ARM SOC revision */
+#define ARM_SOC_CONTINUATION_CODE	U(0x4)
+#define ARM_SOC_IDENTIFICATION_CODE	U(0x3B)
+#define ARM_SOC_CONTINUATION_SHIFT	U(24)
+#define ARM_SOC_IDENTIFICATION_SHIFT	U(16)
+
 /* IO storage utility functions */
 int arm_io_setup(void);
 
@@ -323,4 +329,7 @@
 void plat_arm_secure_wdt_start(void);
 void plat_arm_secure_wdt_stop(void);
 
+/* Get SOC-ID of ARM platform */
+uint32_t plat_arm_get_soc_id(void);
+
 #endif /* PLAT_ARM_H */
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 5b5ebb9..e4431d2 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -322,4 +322,14 @@
  */
 unsigned int platform_core_pos_helper(unsigned long mpidr);
 
+/*
+ * Optional function to get SOC version
+ */
+int32_t plat_get_soc_version(void);
+
+/*
+ * Optional function to get SOC revision
+ */
+int32_t plat_get_soc_revision(void);
+
 #endif /* PLATFORM_H */
diff --git a/include/services/arm_arch_svc.h b/include/services/arm_arch_svc.h
index 1cb2038..5bbd8bb 100644
--- a/include/services/arm_arch_svc.h
+++ b/include/services/arm_arch_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,7 +9,11 @@
 
 #define SMCCC_VERSION			U(0x80000000)
 #define SMCCC_ARCH_FEATURES		U(0x80000001)
+#define SMCCC_ARCH_SOC_ID		U(0x80000002)
 #define SMCCC_ARCH_WORKAROUND_1		U(0x80008000)
 #define SMCCC_ARCH_WORKAROUND_2		U(0x80007FFF)
 
+#define SMCCC_GET_SOC_VERSION		U(0)
+#define SMCCC_GET_SOC_REVISION		U(1)
+
 #endif /* ARM_ARCH_SVC_H */
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index d1eee08..60c777e 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -25,6 +25,9 @@
  * conflicts with the definition in plat/common. */
 #pragma weak plat_get_syscnt_freq2
 
+/* Get ARM SOC-ID */
+#pragma weak plat_arm_get_soc_id
+
 /*******************************************************************************
  * Changes the memory attributes for the region of mapped memory where the BL
  * image's translation tables are located such that the tables will have
@@ -231,3 +234,22 @@
 	return arm_validate_ns_entrypoint(pa);
 }
 #endif
+
+/*
+ * Weak function to get ARM platform SOC-ID, Always return SOC-ID=0
+ * ToDo: Get proper SOC-ID for every ARM platform and define this
+ *       function separately for every ARM platform.
+ */
+uint32_t plat_arm_get_soc_id(void)
+{
+	return 0U;
+}
+
+/* Get SOC version */
+int32_t plat_get_soc_version(void)
+{
+	return (int32_t)
+		((ARM_SOC_IDENTIFICATION_CODE << ARM_SOC_IDENTIFICATION_SHIFT)
+		 | (ARM_SOC_CONTINUATION_CODE << ARM_SOC_CONTINUATION_SHIFT)
+		 | plat_arm_get_soc_id());
+}
diff --git a/plat/common/plat_bl_common.c b/plat/common/plat_bl_common.c
index de6c1d1..d38fc6f 100644
--- a/plat/common/plat_bl_common.c
+++ b/plat/common/plat_bl_common.c
@@ -11,6 +11,7 @@
 #include <common/debug.h>
 #include <lib/xlat_tables/xlat_tables_compat.h>
 #include <plat/common/platform.h>
+#include <smccc_helpers.h>
 #include <tools_share/firmware_encrypted.h>
 
 /*
@@ -24,6 +25,18 @@
 #pragma weak bl2_plat_handle_post_image_load
 #pragma weak plat_try_next_boot_source
 #pragma weak plat_get_enc_key_info
+#pragma weak plat_get_soc_version
+#pragma weak plat_get_soc_revision
+
+int32_t plat_get_soc_version(void)
+{
+	return SMC_ARCH_CALL_NOT_SUPPORTED;
+}
+
+int32_t plat_get_soc_revision(void)
+{
+	return SMC_ARCH_CALL_NOT_SUPPORTED;
+}
 
 void bl2_el3_plat_prepare_exit(void)
 {
diff --git a/services/arm_arch_svc/arm_arch_svc_setup.c b/services/arm_arch_svc/arm_arch_svc_setup.c
index 6dac56e..ba53930 100644
--- a/services/arm_arch_svc/arm_arch_svc_setup.c
+++ b/services/arm_arch_svc/arm_arch_svc_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,18 +12,27 @@
 #include <lib/smccc.h>
 #include <services/arm_arch_svc.h>
 #include <smccc_helpers.h>
+#include <plat/common/platform.h>
 
 static int32_t smccc_version(void)
 {
 	return MAKE_SMCCC_VERSION(SMCCC_MAJOR_VERSION, SMCCC_MINOR_VERSION);
 }
 
-static int32_t smccc_arch_features(u_register_t arg)
+static int32_t smccc_arch_features(u_register_t arg1, u_register_t arg2)
 {
-	switch (arg) {
+	switch (arg1) {
 	case SMCCC_VERSION:
 	case SMCCC_ARCH_FEATURES:
 		return SMC_OK;
+	case SMCCC_ARCH_SOC_ID:
+		if (arg2 == SMCCC_GET_SOC_REVISION) {
+			return plat_get_soc_revision();
+		}
+		if (arg2 == SMCCC_GET_SOC_VERSION) {
+			return plat_get_soc_version();
+		}
+		return SMC_ARCH_CALL_INVAL_PARAM;
 #if WORKAROUND_CVE_2017_5715
 	case SMCCC_ARCH_WORKAROUND_1:
 		if (check_wa_cve_2017_5715() == ERRATA_NOT_APPLIES)
@@ -94,7 +103,7 @@
 	case SMCCC_VERSION:
 		SMC_RET1(handle, smccc_version());
 	case SMCCC_ARCH_FEATURES:
-		SMC_RET1(handle, smccc_arch_features(x1));
+		SMC_RET1(handle, smccc_arch_features(x1, x2));
 #if WORKAROUND_CVE_2017_5715
 	case SMCCC_ARCH_WORKAROUND_1:
 		/*