Merge "refactor(cm): introduce INIT_UNUSED_NS_EL2 macro" into integration
diff --git a/Makefile b/Makefile
index e0f8426..e80f97c 100644
--- a/Makefile
+++ b/Makefile
@@ -399,10 +399,6 @@
 
 endif #(LD = armlink)
 
-DTC_FLAGS		+=	-I dts -O dtb
-DTC_CPPFLAGS		+=	-P -nostdinc -Iinclude -Ifdts -undef \
-				-x assembler-with-cpp $(DEFINES)
-
 ################################################################################
 # Setup ARCH_MAJOR/MINOR before parsing arch_features.
 ################################################################################
@@ -444,6 +440,10 @@
 				${PLAT_INCLUDES}			\
 				${SPD_INCLUDES}
 
+DTC_FLAGS		+=	-I dts -O dtb
+DTC_CPPFLAGS		+=	-P -nostdinc $(INCLUDES) -Ifdts -undef \
+				-x assembler-with-cpp $(DEFINES)
+
 include common/backtrace/backtrace.mk
 
 ################################################################################
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 3359526..f0776c4 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -27,7 +27,6 @@
 include lib/mpmm/mpmm.mk
 
 ifeq (${SPMC_AT_EL3},1)
-  $(warning "EL3 SPMC is an experimental feature")
   $(info Including EL3 SPMC makefile)
   include services/std_svc/spm/common/spm.mk
   include services/std_svc/spm/el3_spmc/spmc.mk
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index ff69b43..3fce393 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -130,6 +130,12 @@
    -  For other BL3x images, if the firmware configuration file is loaded by
       BL2, then its address is passed in ``arg0`` and if HW_CONFIG is loaded
       then its address is passed in ``arg1``.
+   -  In case SPMC_AT_EL3 is enabled, populate the BL32 image base, size and max
+      limit in the entry point information, since there is no platform function
+      to retrieve these in generic code. We choose ``arg2``, ``arg3`` and
+      ``arg4`` since the generic code uses ``arg1`` for stashing the SP manifest
+      size. The SPMC setup uses these arguments to update SP manifest with
+      actual SP's base address and it size.
    -  In case of the Arm FVP platform, FW_CONFIG address passed in ``arg1`` to
       BL31/SP_MIN, and the SOC_FW_CONFIG and HW_CONFIG details are retrieved
       from FW_CONFIG device tree.
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 4b54829..702070c 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -902,7 +902,7 @@
    Dispatcher option (``SPD=spmd``). When enabled (1) it indicates the SPMC
    component runs at the EL3 exception level. The default value is ``0`` (
    disabled). This configuration supports pre-Armv8.4 platforms (aka not
-   implementing the ``FEAT_SEL2`` extension). This is an experimental feature.
+   implementing the ``FEAT_SEL2`` extension).
 
 -  ``SPMC_AT_EL3_SEL0_SP`` : Boolean option to enable SEL0 SP load support when
    ``SPMC_AT_EL3`` is enabled. The default value if ``0`` (disabled). This
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index c92121f..4d1b1c1 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -80,6 +80,20 @@
 int plat_core_pos_by_mpidr(u_register_t mpidr);
 int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size);
 
+/*******************************************************************************
+ * Simple routine to determine whether a mpidr is valid or not.
+ ******************************************************************************/
+static inline bool is_valid_mpidr(u_register_t mpidr)
+{
+	int pos = plat_core_pos_by_mpidr(mpidr);
+
+	if ((pos < 0) || ((unsigned int)pos >= PLATFORM_CORE_COUNT)) {
+		return false;
+	}
+
+	return true;
+}
+
 #if STACK_PROTECTOR_ENABLED
 /*
  * Return a new value to be used for the stack protection's canary.
diff --git a/lib/pmf/pmf_main.c b/lib/pmf/pmf_main.c
index bf0ad83..b33f49c 100644
--- a/lib/pmf/pmf_main.c
+++ b/lib/pmf/pmf_main.c
@@ -165,7 +165,7 @@
 	/* Search for registered service. */
 	svc_desc = get_service(tid);
 
-	if ((svc_desc == NULL) || (plat_core_pos_by_mpidr(mpidr) < 0)) {
+	if (svc_desc == NULL) {
 		*ts_value = 0;
 		return -EINVAL;
 	} else {
diff --git a/lib/pmf/pmf_smc.c b/lib/pmf/pmf_smc.c
index 71486df..f3dd112 100644
--- a/lib/pmf/pmf_smc.c
+++ b/lib/pmf/pmf_smc.c
@@ -26,6 +26,10 @@
 	int rc;
 	unsigned long long ts_value;
 
+	/* Determine if the cpu exists of not */
+	if (!is_valid_mpidr(x2))
+		return PSCI_E_INVALID_PARAMS;
+
 	if (((smc_fid >> FUNCID_CC_SHIFT) & FUNCID_CC_MASK) == SMC_32) {
 
 		x1 = (uint32_t)x1;
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index 70bf77e..f9de432 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -818,20 +818,6 @@
 }
 
 /*******************************************************************************
- * Simple routine to determine whether a mpidr is valid or not.
- ******************************************************************************/
-int psci_validate_mpidr(u_register_t mpidr)
-{
-	int pos = plat_core_pos_by_mpidr(mpidr);
-
-	if ((pos < 0) || ((unsigned int)pos >= PLATFORM_CORE_COUNT)) {
-		return PSCI_E_INVALID_PARAMS;
-	}
-
-	return PSCI_E_SUCCESS;
-}
-
-/*******************************************************************************
  * This function determines the full entrypoint information for the requested
  * PSCI entrypoint on power on/resume and returns it.
  ******************************************************************************/
diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c
index 326f125..a015531 100644
--- a/lib/psci/psci_main.c
+++ b/lib/psci/psci_main.c
@@ -29,9 +29,8 @@
 	int rc;
 	entry_point_info_t ep;
 
-	/* Determine if the cpu exists of not */
-	rc = psci_validate_mpidr(target_cpu);
-	if (rc != PSCI_E_SUCCESS)
+	/* Validate the target CPU */
+	if (!is_valid_mpidr(target_cpu))
 		return PSCI_E_INVALID_PARAMS;
 
 	/* Validate the entry point and get the entry_point_info */
@@ -245,19 +244,18 @@
 int psci_affinity_info(u_register_t target_affinity,
 		       unsigned int lowest_affinity_level)
 {
-	int ret;
 	unsigned int target_idx;
 
+	/* Validate the target affinity */
+	if (!is_valid_mpidr(target_affinity))
+		return PSCI_E_INVALID_PARAMS;
+
 	/* We dont support level higher than PSCI_CPU_PWR_LVL */
 	if (lowest_affinity_level > PSCI_CPU_PWR_LVL)
 		return PSCI_E_INVALID_PARAMS;
 
 	/* Calculate the cpu index of the target */
-	ret = plat_core_pos_by_mpidr(target_affinity);
-	if (ret == -1) {
-		return PSCI_E_INVALID_PARAMS;
-	}
-	target_idx = (unsigned int)ret;
+	target_idx = (unsigned int) plat_core_pos_by_mpidr(target_affinity);
 
 	/*
 	 * Generic management:
@@ -285,6 +283,10 @@
 	int rc;
 	u_register_t resident_cpu_mpidr;
 
+	/* Validate the target cpu */
+	if (!is_valid_mpidr(target_cpu))
+		return PSCI_E_INVALID_PARAMS;
+
 	rc = psci_spd_migrate_info(&resident_cpu_mpidr);
 	if (rc != PSCI_TOS_UP_MIG_CAP)
 		return (rc == PSCI_TOS_NOT_UP_MIG_CAP) ?
@@ -298,8 +300,7 @@
 		return PSCI_E_NOT_PRESENT;
 
 	/* Check the validity of the specified target cpu */
-	rc = psci_validate_mpidr(target_cpu);
-	if (rc != PSCI_E_SUCCESS)
+	if (!is_valid_mpidr(target_cpu))
 		return PSCI_E_INVALID_PARAMS;
 
 	assert((psci_spd_pm != NULL) && (psci_spd_pm->svc_migrate != NULL));
@@ -339,8 +340,7 @@
 	int rc;
 
 	/* Validate target_cpu */
-	rc = psci_validate_mpidr(target_cpu);
-	if (rc != PSCI_E_SUCCESS)
+	if (!is_valid_mpidr(target_cpu))
 		return PSCI_E_INVALID_PARAMS;
 
 	/* Validate power_level against PLAT_MAX_PWR_LVL */
diff --git a/lib/psci/psci_on.c b/lib/psci/psci_on.c
index 31875ff..b279774 100644
--- a/lib/psci/psci_on.c
+++ b/lib/psci/psci_on.c
@@ -61,15 +61,7 @@
 {
 	int rc;
 	aff_info_state_t target_aff_state;
-	int ret = plat_core_pos_by_mpidr(target_cpu);
-	unsigned int target_idx;
-
-	/* Calling function must supply valid input arguments */
-	assert(ret >= 0);
-	assert((unsigned int)ret < PLATFORM_CORE_COUNT);
-	assert(ep != NULL);
-
-	target_idx = (unsigned int)ret;
+	unsigned int target_idx = (unsigned int)plat_core_pos_by_mpidr(target_cpu);
 
 	/*
 	 * This function must only be called on platforms where the
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index 04f93bd..2eb4a9b 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -286,7 +286,6 @@
 int psci_validate_power_state(unsigned int power_state,
 			      psci_power_state_t *state_info);
 void psci_query_sys_suspend_pwrstate(psci_power_state_t *state_info);
-int psci_validate_mpidr(u_register_t mpidr);
 void psci_init_req_local_pwr_states(void);
 #if PSCI_OS_INIT_MODE
 void psci_update_req_local_pwr_states(unsigned int end_pwrlvl,
diff --git a/lib/psci/psci_stat.c b/lib/psci/psci_stat.c
index ad88d07..bedb816 100644
--- a/lib/psci/psci_stat.c
+++ b/lib/psci/psci_stat.c
@@ -181,10 +181,8 @@
 	psci_power_state_t state_info = { {PSCI_LOCAL_STATE_RUN} };
 	plat_local_state_t local_state;
 
-	/* Validate the target_cpu parameter and determine the cpu index */
+	/* Determine the cpu index */
 	target_idx = (unsigned int) plat_core_pos_by_mpidr(target_cpu);
-	if (target_idx == (unsigned int) -1)
-		return PSCI_E_INVALID_PARAMS;
 
 	/* Validate the power_state parameter */
 	if (psci_plat_pm_ops->translate_power_state_by_mpidr == NULL)
@@ -228,6 +226,11 @@
 		unsigned int power_state)
 {
 	psci_stat_t psci_stat;
+
+	/* Validate the target cpu */
+	if (!is_valid_mpidr(target_cpu))
+		return 0;
+
 	int rc = psci_get_stat(target_cpu, power_state, &psci_stat);
 
 	if (rc == PSCI_E_SUCCESS)
@@ -241,6 +244,11 @@
 	unsigned int power_state)
 {
 	psci_stat_t psci_stat;
+
+	/* Validate the target cpu */
+	if (!is_valid_mpidr(target_cpu))
+		return 0;
+
 	int rc = psci_get_stat(target_cpu, power_state, &psci_stat);
 
 	if (rc == PSCI_E_SUCCESS)
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index f47bc3e..03e6889 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -198,6 +198,24 @@
 	while (bl_params != NULL) {
 		if (bl_params->image_id == BL32_IMAGE_ID) {
 			bl32_image_ep_info = *bl_params->ep_info;
+#if defined(SPMC_AT_EL3)
+			/*
+			 * Populate the BL32 image base, size and max limit in
+			 * the entry point information, since there is no
+			 * platform function to retrieve them in generic
+			 * code. We choose arg2, arg3 and arg4 since the generic
+			 * code uses arg1 for stashing the SP manifest size. The
+			 * SPMC setup uses these arguments to update SP manifest
+			 * with actual SP's base address and it size.
+			 */
+			bl32_image_ep_info.args.arg2 =
+				bl_params->image_info->image_base;
+			bl32_image_ep_info.args.arg3 =
+				bl_params->image_info->image_size;
+			bl32_image_ep_info.args.arg4 =
+				bl_params->image_info->image_base +
+				bl_params->image_info->image_max_size;
+#endif
 		}
 #if ENABLE_RME
 		else if (bl_params->image_id == RMM_IMAGE_ID) {
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
index 9dfe040..610f1fc 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -34,10 +34,10 @@
  */
 #if defined(IMAGE_BL31)
 # if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
-#  define PLAT_ARM_MMAP_ENTRIES		(9  + ((CSS_SGI_CHIP_COUNT - 1) * 3))
-#  define MAX_XLAT_TABLES		(7  + ((CSS_SGI_CHIP_COUNT - 1) * 3))
-#  define PLAT_SP_IMAGE_MMAP_REGIONS	10
-#  define PLAT_SP_IMAGE_MAX_XLAT_TABLES	12
+#  define PLAT_ARM_MMAP_ENTRIES		(10  + ((CSS_SGI_CHIP_COUNT - 1) * 3))
+#  define MAX_XLAT_TABLES		(8  + ((CSS_SGI_CHIP_COUNT - 1) * 3))
+#  define PLAT_SP_IMAGE_MMAP_REGIONS	12
+#  define PLAT_SP_IMAGE_MAX_XLAT_TABLES	14
 # else
 #  define PLAT_ARM_MMAP_ENTRIES		(5 + ((CSS_SGI_CHIP_COUNT - 1) * 3))
 #  define MAX_XLAT_TABLES		(6 + ((CSS_SGI_CHIP_COUNT - 1) * 3))
diff --git a/services/std_svc/sdei/sdei_main.c b/services/std_svc/sdei/sdei_main.c
index 0fd3c1d..59a1673 100644
--- a/services/std_svc/sdei/sdei_main.c
+++ b/services/std_svc/sdei/sdei_main.c
@@ -35,8 +35,6 @@
 
 #define LOWEST_INTR_PRIORITY		0xff
 
-#define is_valid_affinity(_mpidr)	(plat_core_pos_by_mpidr(_mpidr) >= 0)
-
 CASSERT(PLAT_SDEI_CRITICAL_PRI < PLAT_SDEI_NORMAL_PRI,
 		sdei_critical_must_have_higher_priority);
 
@@ -262,7 +260,7 @@
 	/* Validate flags */
 	switch (flags) {
 	case SDEI_REGF_RM_PE:
-		if (!is_valid_affinity(mpidr))
+		if (!is_valid_mpidr(mpidr))
 			return SDEI_EINVAL;
 		break;
 	case SDEI_REGF_RM_ANY:
@@ -926,7 +924,7 @@
 		return SDEI_EINVAL;
 
 	/* Validate target */
-	if (plat_core_pos_by_mpidr(target_pe) < 0)
+	if (!is_valid_mpidr(target_pe))
 		return SDEI_EINVAL;
 
 	/* Raise SGI. Platform will validate target_pe */