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 */