PSCI: Validate non secure entrypoint on ARM platforms

This patch implements the platform power managment handler to verify
non secure entrypoint for ARM platforms. The handler ensures that the
entry point specified by the normal world during CPU_SUSPEND, CPU_ON
or SYSTEM_SUSPEND PSCI API is a valid address within the non secure
DRAM.

Change-Id: I4795452df99f67a24682b22f0e0967175c1de429
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 56b5eda..823212c 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -190,6 +190,7 @@
 /* PM utility functions */
 int arm_validate_power_state(unsigned int power_state,
 			    psci_power_state_t *req_state);
+int arm_validate_ns_entrypoint(uintptr_t entrypoint);
 
 /* Topology utility function */
 int arm_check_mpidr(u_register_t mpidr);
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index 8be5105..9d6ab9c 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -304,7 +304,8 @@
 	.pwr_domain_suspend_finish = fvp_pwr_domain_suspend_finish,
 	.system_off = fvp_system_off,
 	.system_reset = fvp_system_reset,
-	.validate_power_state = arm_validate_power_state
+	.validate_power_state = arm_validate_power_state,
+	.validate_ns_entrypoint = arm_validate_ns_entrypoint
 };
 
 /*******************************************************************************
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index 71fbf9f..b225170 100644
--- a/plat/arm/common/arm_pm.c
+++ b/plat/arm/common/arm_pm.c
@@ -29,6 +29,7 @@
  */
 
 #include <arch_helpers.h>
+#include <arm_def.h>
 #include <assert.h>
 #include <errno.h>
 #include <plat_arm.h>
@@ -123,3 +124,23 @@
 	return PSCI_E_SUCCESS;
 }
 #endif /* __ARM_RECOM_STATE_ID_ENC__ */
+
+/*******************************************************************************
+ * ARM standard platform handler called to check the validity of the non secure
+ * entrypoint.
+ ******************************************************************************/
+int arm_validate_ns_entrypoint(uintptr_t entrypoint)
+{
+	/*
+	 * Check if the non secure entrypoint lies within the non
+	 * secure DRAM.
+	 */
+	if ((entrypoint >= ARM_NS_DRAM1_BASE) && (entrypoint <
+			(ARM_NS_DRAM1_BASE + ARM_NS_DRAM1_SIZE)))
+		return PSCI_E_SUCCESS;
+	if ((entrypoint >= ARM_DRAM2_BASE) && (entrypoint <
+			(ARM_DRAM2_BASE + ARM_DRAM2_SIZE)))
+		return PSCI_E_SUCCESS;
+
+	return PSCI_E_INVALID_ADDRESS;
+}
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index 435ed2a..cc64bf8 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -267,7 +267,8 @@
 	.pwr_domain_suspend_finish	= css_pwr_domain_suspend_finish,
 	.system_off		= css_system_off,
 	.system_reset		= css_system_reset,
-	.validate_power_state	= arm_validate_power_state
+	.validate_power_state	= arm_validate_power_state,
+	.validate_ns_entrypoint = arm_validate_ns_entrypoint
 };
 
 /*******************************************************************************