Merge changes from topic "xlnx_fix_plat_ns_entry" into integration

* changes:
  feat(versal2): validate non-secure entry addr
  feat(versal2): parse reserve memory subnodes
diff --git a/plat/amd/common/plat_fdt.c b/plat/amd/common/plat_fdt.c
index 194d538..095527d 100644
--- a/plat/amd/common/plat_fdt.c
+++ b/plat/amd/common/plat_fdt.c
@@ -16,6 +16,9 @@
 
 #define FIT_CONFS_PATH	"/configurations"
 
+static struct reserve_mem_range rsvnodes[MAX_RESERVE_ADDR_INDICES] = {};
+static uint32_t rsv_count;
+
 static bool is_fit_image(void *dtb)
 {
 	int64_t confs_noffset = 0;
@@ -72,3 +75,64 @@
 
 	return (uintptr_t)dtb;
 }
+
+struct reserve_mem_range *get_reserved_entries_fdt(uint32_t *reserve_nodes)
+{
+	struct reserve_mem_range *rsvmr = NULL;
+
+	if ((rsv_count > 0) && (reserve_nodes != NULL)) {
+		rsvmr = &rsvnodes[0];
+		*reserve_nodes = rsv_count;
+	}
+
+	return rsvmr;
+}
+
+/* TODO: Parse TL overlays for updated tf-a and op-tee reserved nodes */
+uint32_t retrieve_reserved_entries(void)
+{
+	uint32_t ret = 1;
+	void *dtb = NULL;
+	int offset, node;
+	uint32_t i = 0;
+	const fdt32_t *reg_prop;
+
+
+	/* Get DT blob address */
+	dtb = (void *)plat_retrieve_dt_addr();
+
+	/* Check if DT is valid */
+	if (is_valid_dtb(dtb) >= 0) {
+		/* Find reserved memory node */
+		offset = fdt_path_offset(dtb, "/reserved-memory");
+		if (offset >= 0) {
+
+			/* Parse subnodes of reserved-memory */
+			fdt_for_each_subnode(node, dtb, offset) {
+				if (fdt_getprop(dtb, node, "no-map", NULL) == NULL) {
+					continue;
+				}
+
+				if (rsv_count == MAX_RESERVE_ADDR_INDICES) {
+					break;
+				}
+
+				reg_prop = fdt_getprop(dtb, node, "reg", NULL);
+				if (reg_prop == NULL) {
+					INFO("No valid reg prop found for subnode\n");
+					continue;
+				}
+
+				rsvnodes[i].base = (((uint64_t)fdt32_to_cpu(reg_prop[0]) << 32) |
+						fdt32_to_cpu(reg_prop[1]));
+				rsvnodes[i].size = (((uint64_t)fdt32_to_cpu(reg_prop[2]) << 32) |
+						fdt32_to_cpu(reg_prop[3]));
+				i++;
+			}
+			ret = 0;
+			rsv_count = i;
+		}
+	}
+
+	return ret;
+}
diff --git a/plat/amd/versal2/bl31_setup.c b/plat/amd/versal2/bl31_setup.c
index 28bcaa1..0726c26 100644
--- a/plat/amd/versal2/bl31_setup.c
+++ b/plat/amd/versal2/bl31_setup.c
@@ -261,6 +261,7 @@
 {
 	uint32_t flags = 0;
 	int32_t rc;
+	uint32_t rre_ret = 0;
 
 	set_interrupt_rm_flag(flags, NON_SECURE);
 	rc = register_interrupt_type_handler(INTR_TYPE_EL3,
@@ -269,6 +270,13 @@
 		panic();
 	}
 
+	/* Instead of calling for each time fill in structure early. */
+	rre_ret = retrieve_reserved_entries();
+
+	if (rre_ret != 0) {
+		INFO("Runtime FDT reserve node retreival failed");
+	}
+
 	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
diff --git a/plat/amd/versal2/plat_psci_pm.c b/plat/amd/versal2/plat_psci_pm.c
index ab71043..97a5997 100644
--- a/plat/amd/versal2/plat_psci_pm.c
+++ b/plat/amd/versal2/plat_psci_pm.c
@@ -14,6 +14,7 @@
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 #include <plat_arm.h>
+#include <plat_fdt.h>
 
 #include "def.h"
 #include <ipi.h>
@@ -186,6 +187,34 @@
 	return;
 }
 
+static int32_t versal2_validate_ns_entrypoint(uint64_t ns_entrypoint)
+{
+	int32_t ret = PSCI_E_SUCCESS;
+	struct reserve_mem_range *rmr;
+	uint32_t index = 0, counter = 0;
+
+	rmr = get_reserved_entries_fdt(&counter);
+
+	VERBOSE("Validate ns_entry point %lx\n", ns_entrypoint);
+
+	if (counter != 0) {
+		while (index < counter) {
+			if ((ns_entrypoint >= rmr[index].base) &&
+				       (ns_entrypoint <= rmr[index].size)) {
+				ret = PSCI_E_INVALID_ADDRESS;
+				break;
+			}
+			index++;
+		}
+	} else {
+		if ((ns_entrypoint >= BL31_BASE) && (ns_entrypoint <= BL31_LIMIT)) {
+			ret = PSCI_E_INVALID_ADDRESS;
+		}
+	}
+
+	return ret;
+}
+
 static void versal2_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
 	(void)target_state;
@@ -312,6 +341,7 @@
 	.pwr_domain_suspend_finish      = versal2_pwr_domain_suspend_finish,
 	.system_off                     = versal2_system_off,
 	.system_reset                   = versal2_system_reset,
+	.validate_ns_entrypoint		= versal2_validate_ns_entrypoint,
 	.validate_power_state           = versal2_validate_power_state,
 	.get_sys_suspend_power_state    = versal2_get_sys_suspend_power_state,
 };
diff --git a/plat/xilinx/common/include/plat_fdt.h b/plat/xilinx/common/include/plat_fdt.h
index 48ffff3..0c2b1df 100644
--- a/plat/xilinx/common/include/plat_fdt.h
+++ b/plat/xilinx/common/include/plat_fdt.h
@@ -11,4 +11,29 @@
 uintptr_t plat_retrieve_dt_addr(void);
 int32_t is_valid_dtb(void *fdt);
 
+#define MAX_RESERVE_ADDR_INDICES 32
+struct reserve_mem_range {
+	uintptr_t base;
+	size_t size;
+};
+
+#if (TRANSFER_LIST == 1)
+uint32_t retrieve_reserved_entries(void);
+struct reserve_mem_range *get_reserved_entries_fdt(uint32_t *reserve_nodes);
+#else
+static inline uint32_t retrieve_reserved_entries(void)
+{
+	return 0;
+}
+
+static inline struct reserve_mem_range *get_reserved_entries_fdt(uint32_t *reserve_nodes)
+{
+	if (reserve_nodes) {
+		*reserve_nodes = 0;
+	}
+
+	return NULL;
+}
+#endif
+
 #endif /* PLAT_FDT_H */