[PATCH 2/4] bootmeth: efi: source the devicetree from a firmware partition
Carlo Caione
ccaione at baylibre.com
Mon Jul 6 17:06:43 CEST 2026
When a firmware-owned devicetree source is configured (EBBR / Arm
SystemReady IR), assemble the devicetree from the FIT manifest on
the firmware partition instead of reading a DTB from the EFI System
Partition, and hand it to the EFI application through the normal
bflow->fdt_addr path (efi_install_fdt()).
Signed-off-by: Carlo Caione <ccaione at baylibre.com>
---
boot/bootmeth_efi.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
diff --git a/boot/bootmeth_efi.c b/boot/bootmeth_efi.c
index e187dc39912..ae3f1c9b91e 100644
--- a/boot/bootmeth_efi.c
+++ b/boot/bootmeth_efi.c
@@ -17,6 +17,7 @@
#include <efi_loader.h>
#include <env.h>
#include <extension_board.h>
+#include <firmware_fdt.h>
#include <fs.h>
#include <malloc.h>
#include <mapmem.h>
@@ -73,6 +74,61 @@ static int efiload_read_file(struct bootflow *bflow, ulong addr)
return 0;
}
+/**
+ * distro_efi_firmware_fdt() - try to stage the firmware-owned devicetree
+ *
+ * Prefer a firmware-owned devicetree if one is configured: assemble it
+ * from the FIT manifest on the firmware partition, stage it at 'fdt_addr_r'
+ * and fill the bootflow, so it reaches the EFI app through the normal
+ * bflow->fdt_addr path (efi_install_fdt()).
+ *
+ * The semantics are fail closed: only -ENOENT (no firmware-FDT source
+ * configured) lets the caller fall back to its normal devicetree source, so
+ * a missing or broken firmware devicetree is never silently replaced.
+ *
+ * @bflow: bootflow to update
+ * Return: 0 if the firmware devicetree was staged (the bootflow devicetree
+ * fields are set), -ENOENT if no source is configured, other -ve error if a
+ * configured source failed to assemble (the bootflow must fail)
+ */
+static int distro_efi_firmware_fdt(struct bootflow *bflow)
+{
+ struct firmware_fdt fw;
+ ulong fdt_addr;
+ int ret;
+
+ if (!CONFIG_IS_ENABLED(BOOTSTD_FIRMWARE_FDT))
+ return -ENOENT;
+
+ ret = firmware_fdt_load(&fw);
+ if (ret) {
+ if (ret != -ENOENT)
+ log_err("Failed to assemble the firmware devicetree (err %d)\n",
+ ret);
+ return ret;
+ }
+
+ /* stage it at fdt_addr_r, like any other devicetree */
+ fdt_addr = env_get_hex("fdt_addr_r", 0);
+ if (!fdt_addr || fw.size > SZ_4M) {
+ firmware_fdt_free(&fw);
+ return log_msg_ret("fwa", -EINVAL);
+ }
+
+ memcpy(map_sysmem(fdt_addr, fw.size), fw.fdt, fw.size);
+
+ bflow->fdt_fname = strdup(fw.name);
+ bflow->fdt_size = fw.size;
+ bflow->fdt_addr = fdt_addr;
+ firmware_fdt_free(&fw);
+ if (!bflow->fdt_fname)
+ return log_msg_ret("fwn", -ENOMEM);
+
+ log_debug("Using firmware-owned devicetree\n");
+
+ return 0;
+}
+
static int distro_efi_check(struct udevice *dev, struct bootflow_iter *iter)
{
/* This only works on block and network devices */
@@ -130,6 +186,18 @@ static int distro_efi_try_bootflow_files(struct udevice *dev,
fdt_addr = env_get_hex("fdt_addr_r", 0);
+ /*
+ * A staged firmware-owned devicetree is complete and authoritative,
+ * so return without considering any other devicetree source. The
+ * extension overlays below are deliberately not applied on top:
+ * such combinations belong in the manifest as configurations.
+ */
+ ret = distro_efi_firmware_fdt(bflow);
+ if (!ret)
+ return 0;
+ if (ret != -ENOENT)
+ return log_msg_ret("fwf", ret);
+
/* try the various available names */
ret = -ENOENT;
*fname = '\0';
@@ -268,6 +336,19 @@ static int distro_efi_read_bootflow_net(struct bootflow *bflow)
if (!bflow->fname)
return log_msg_ret("fi0", -ENOMEM);
+ /*
+ * A configured firmware-owned devicetree outranks the network-provided
+ * one (and the prior-stage / built-in devicetree below): a DHCP/TFTP
+ * server must not be able to replace it.
+ */
+ ret = distro_efi_firmware_fdt(bflow);
+ if (!ret) {
+ bflow->state = BOOTFLOWST_READY;
+ return 0;
+ }
+ if (ret != -ENOENT)
+ return log_msg_ret("fwf", ret);
+
/* read the DT file also */
ret = efi_get_distro_fdt_name(fname, sizeof(fname), 0);
if (ret == -EALREADY) {
--
2.55.0
More information about the U-Boot
mailing list