ARM platforms: Provide SDEI entry point validation

Provide a strong definition for plat_sdei_validate_sdei_entrypoint()
which translates client address to Physical Address, and then validating
the address to be present in DRAM.

Change-Id: Ib93eb66b413d638aa5524d1b3de36aa16d38ea11
Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index 1905c0b..bf63973 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -204,3 +204,51 @@
 }
 
 #endif /* ARM_SYS_CNTCTL_BASE */
+
+#if SDEI_SUPPORT
+/*
+ * Translate SDEI entry point to PA, and perform standard ARM entry point
+ * validation on it.
+ */
+int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode)
+{
+	uint64_t par, pa;
+	uint32_t scr_el3;
+
+	/* Doing Non-secure address translation requires SCR_EL3.NS set */
+	scr_el3 = read_scr_el3();
+	write_scr_el3(scr_el3 | SCR_NS_BIT);
+	isb();
+
+	assert((client_mode == MODE_EL2) || (client_mode == MODE_EL1));
+	if (client_mode == MODE_EL2) {
+		/*
+		 * Translate entry point to Physical Address using the EL2
+		 * translation regime.
+		 */
+		ats1e2r(ep);
+	} else {
+		/*
+		 * Translate entry point to Physical Address using the EL1&0
+		 * translation regime, including stage 2.
+		 */
+		ats12e1r(ep);
+	}
+	isb();
+	par = read_par_el1();
+
+	/* Restore original SCRL_EL3 */
+	write_scr_el3(scr_el3);
+	isb();
+
+	/* If the translation resulted in fault, return failure */
+	if ((par & PAR_F_MASK) != 0)
+		return -1;
+
+	/* Extract Physical Address from PAR */
+	pa = (par & (PAR_ADDR_MASK << PAR_ADDR_SHIFT));
+
+	/* Perform NS entry point validation on the physical address */
+	return arm_validate_ns_entrypoint(pa);
+}
+#endif