feat(versal2): retrieve DT address from transfer list
On versal2 platform, unlike current static DT address passing
mechanism, DT address is retrieved from transfer list dynamically.
Change-Id: I44b9a0753809652f26bc1b7e061f5364229ba352
Signed-off-by: Maheedhar Bollapalli <maheedharsai.bollapalli@amd.com>
diff --git a/plat/amd/common/include/plat_xfer_list.h b/plat/amd/common/include/plat_xfer_list.h
index bf9f458..24a9c0c 100644
--- a/plat/amd/common/include/plat_xfer_list.h
+++ b/plat/amd/common/include/plat_xfer_list.h
@@ -12,4 +12,7 @@
int32_t transfer_list_populate_ep_info(entry_point_info_t *bl32,
entry_point_info_t *bl33);
+void *transfer_list_retrieve_dt_address(void);
+bool populate_data_from_xfer_list(void);
+
#endif /* PLAT_XFER_LIST_H */
diff --git a/plat/amd/common/plat_fdt.c b/plat/amd/common/plat_fdt.c
new file mode 100644
index 0000000..e72c0dd
--- /dev/null
+++ b/plat/amd/common/plat_fdt.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <common/debug.h>
+#include <common/fdt_fixup.h>
+#include <common/fdt_wrappers.h>
+#include <libfdt.h>
+#include <platform_def.h>
+
+#include <plat_fdt.h>
+#include <plat_xfer_list.h>
+
+#define FIT_CONFS_PATH "/configurations"
+
+static bool is_fit_image(void *dtb)
+{
+ int64_t confs_noffset = 0;
+ bool status = true;
+
+ confs_noffset = fdt_path_offset(dtb, FIT_CONFS_PATH);
+
+ /* confs_noffset is only present on FIT image */
+ if (confs_noffset < 0) {
+ status = false;
+ }
+
+ return status;
+}
+
+int32_t is_valid_dtb(void *fdt)
+{
+ int32_t ret = 0;
+
+ ret = fdt_check_header(fdt);
+ if (ret != 0) {
+ ERROR("Can't read DT at %p\n", fdt);
+ goto error;
+ }
+
+ ret = fdt_open_into(fdt, fdt, XILINX_OF_BOARD_DTB_MAX_SIZE);
+ if (ret < 0) {
+ ERROR("Invalid Device Tree at %p: error %d\n", fdt, ret);
+ goto error;
+ }
+
+ if (is_fit_image(fdt)) {
+ WARN("FIT image detected, TF-A will not update DTB for DDR address space\n");
+ ret = -FDT_ERR_NOTFOUND;
+ }
+error:
+ return ret;
+}
+
+/* TODO: Reserve TFA memory in DT through custom TL entry */
+void prepare_dtb(void)
+{
+
+}
+
+uintptr_t plat_retrieve_dt_addr(void)
+{
+ void *dtb = NULL;
+
+ dtb = transfer_list_retrieve_dt_address();
+ if (dtb == NULL) {
+ WARN("TL header or DT entry is invalid\n");
+ }
+
+ return (uintptr_t)dtb;
+}
diff --git a/plat/amd/common/plat_xfer_list.c b/plat/amd/common/plat_xfer_list.c
index 07829c2..36c87ca 100644
--- a/plat/amd/common/plat_xfer_list.c
+++ b/plat/amd/common/plat_xfer_list.c
@@ -7,26 +7,34 @@
#include <arch_helpers.h>
#include <common/debug.h>
#include <lib/transfer_list.h>
+#include <platform_def.h>
-/*
- * FIXME: This address should come from firmware before TF-A runs
- * Having this to make sure the transfer list functionality works
- */
-#define FW_HANDOFF_BASE U(0x1200000)
-#define FW_HANDOFF_SIZE U(0x600000)
static struct transfer_list_header *tl_hdr;
+static int32_t tl_ops_holder;
+
+bool populate_data_from_xfer_list(void)
+{
+ bool ret = true;
+
+ tl_hdr = (struct transfer_list_header *)FW_HANDOFF_BASE;
+ tl_ops_holder = transfer_list_check_header(tl_hdr);
+
+ if ((tl_ops_holder != TL_OPS_ALL) && (tl_ops_holder != TL_OPS_RO)) {
+ ret = false;
+ }
+
+ return ret;
+}
int32_t transfer_list_populate_ep_info(entry_point_info_t *bl32,
entry_point_info_t *bl33)
{
+ int32_t ret = tl_ops_holder;
struct transfer_list_entry *te = NULL;
- struct entry_point_info *ep;
- int32_t ret;
+ struct entry_point_info *ep = NULL;
- tl_hdr = (struct transfer_list_header *)FW_HANDOFF_BASE;
- ret = transfer_list_check_header(tl_hdr);
- if ((ret == TL_OPS_ALL) || (ret == TL_OPS_RO)) {
+ if ((tl_ops_holder == TL_OPS_ALL) || (tl_ops_holder == TL_OPS_RO)) {
transfer_list_dump(tl_hdr);
while ((te = transfer_list_next(tl_hdr, te)) != NULL) {
ep = transfer_list_entry_data(te);
@@ -46,5 +54,21 @@
}
}
}
+
return ret;
}
+
+void *transfer_list_retrieve_dt_address(void)
+{
+ void *dtb = NULL;
+ struct transfer_list_entry *te = NULL;
+
+ if ((tl_ops_holder == TL_OPS_ALL) || (tl_ops_holder == TL_OPS_RO)) {
+ te = transfer_list_find(tl_hdr, TL_TAG_FDT);
+ if (te != NULL) {
+ dtb = transfer_list_entry_data(te);
+ }
+ }
+
+ return dtb;
+}
diff --git a/plat/amd/versal2/bl31_setup.c b/plat/amd/versal2/bl31_setup.c
index 1914830..8f0ffb9 100644
--- a/plat/amd/versal2/bl31_setup.c
+++ b/plat/amd/versal2/bl31_setup.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -81,7 +81,10 @@
(void)arg2;
(void)arg3;
uint32_t uart_clock;
+#if (TRANSFER_LIST == 1)
int32_t rc;
+ bool tl_status = false;
+#endif
board_detection();
@@ -124,6 +127,12 @@
default:
panic();
}
+#if (TRANSFER_LIST == 1)
+ tl_status = populate_data_from_xfer_list();
+ if (tl_status != true) {
+ WARN("Invalid transfer list\n");
+ }
+#endif
uart_clock = get_uart_clk();
@@ -152,11 +161,15 @@
SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+#if (TRANSFER_LIST == 1)
rc = transfer_list_populate_ep_info(&bl32_image_ep_info, &bl33_image_ep_info);
if (rc == TL_OPS_NON || rc == TL_OPS_CUS) {
NOTICE("BL31: TL not found, using default config\n");
bl31_set_default_config();
}
+#else
+ bl31_set_default_config();
+#endif
long rev_var = cpu_get_rev_var();
diff --git a/plat/amd/versal2/platform.mk b/plat/amd/versal2/platform.mk
index 18f03d8..04d3c97 100644
--- a/plat/amd/versal2/platform.mk
+++ b/plat/amd/versal2/platform.mk
@@ -129,11 +129,8 @@
drivers/scmi-msg/reset_domain.c \
${PLAT_PATH}/scmi.c
-BL31_SOURCES += ${PLAT_PATH}/plat_psci.c
-
-BL31_SOURCES += plat/xilinx/common/plat_fdt.c \
+BL31_SOURCES += ${PLAT_PATH}/plat_psci.c \
common/fdt_wrappers.c \
- plat/xilinx/common/plat_fdt.c \
plat/xilinx/common/plat_console.c \
plat/xilinx/common/plat_startup.c \
plat/xilinx/common/ipi.c \
@@ -156,5 +153,10 @@
# Enable Handoff protocol using transfer lists
TRANSFER_LIST ?= 0
+ifeq (${TRANSFER_LIST},1)
include lib/transfer_list/transfer_list.mk
-BL31_SOURCES += plat/amd/common/plat_xfer_list.c
+BL31_SOURCES += plat/amd/common/plat_fdt.c
+BL31_SOURCES += plat/amd/common/plat_xfer_list.c
+else
+BL31_SOURCES += plat/xilinx/common/plat_fdt.c
+endif