Set /chosen/bootsource to the node of the device the BootROM booted
from. Platforms provide the path via bootsource_get_ofpath(). By
default we pass on what a previous boot stage has set in the control
device tree. The property is only set if the device tree has a node
at that path.

Signed-off-by: Wadim Egorov <[email protected]>
---
 boot/fdt_support.c    | 42 ++++++++++++++++++++++++++++++++++++++++++
 include/fdt_support.h | 26 ++++++++++++++++++++++++++
 2 files changed, 68 insertions(+)

diff --git a/boot/fdt_support.c b/boot/fdt_support.c
index 2941df55996..0d04d6f7e9a 100644
--- a/boot/fdt_support.c
+++ b/boot/fdt_support.c
@@ -334,6 +334,46 @@ __weak const char *board_fdt_chosen_bootargs(const struct 
fdt_property *fdt_ba)
        return env_get("bootargs");
 }
 
+/*
+ * By default pass on what a previous boot stage recorded in the control
+ * device tree of this stage.
+ */
+__weak const char *bootsource_get_ofpath(void)
+{
+       if (CONFIG_IS_ENABLED(OF_REAL))
+               return ofnode_read_chosen_string("bootsource");
+
+       return NULL;
+}
+
+int fdt_fixup_bootsource(void *fdt)
+{
+       const char *path;
+       int chosen, err;
+
+       path = bootsource_get_ofpath();
+       if (!path)
+               return 0;
+
+       /* Only record a path this tree has a node at, so it can be resolved */
+       if (fdt_path_offset(fdt, path) < 0) {
+               debug("%s: no node %s, not setting bootsource\n",
+                     __func__, path);
+               return 0;
+       }
+
+       chosen = fdt_find_or_add_subnode(fdt, 0, "chosen");
+       if (chosen < 0)
+               return chosen;
+
+       err = fdt_setprop_string(fdt, chosen, "bootsource", path);
+       if (err < 0)
+               printf("WARNING: could not set bootsource %s.\n",
+                      fdt_strerror(err));
+
+       return err;
+}
+
 int fdt_chosen(void *fdt)
 {
        struct abuf buf = {};
@@ -353,6 +393,8 @@ int fdt_chosen(void *fdt)
        if (nodeoffset < 0)
                return nodeoffset;
 
+       fdt_fixup_bootsource(fdt);
+
        /* if DM_RNG enabled automatically inject kaslr-seed node unless:
         * CONFIG_MEASURED_BOOT enabled: as dt modifications break measured boot
         * CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT enabled: as that implementation 
does not use dm yet
diff --git a/include/fdt_support.h b/include/fdt_support.h
index 47b8b63d13d..72642dc401e 100644
--- a/include/fdt_support.h
+++ b/include/fdt_support.h
@@ -55,6 +55,32 @@ int fdt_root(void *fdt);
  */
 int fdt_chosen(void *fdt);
 
+/**
+ * bootsource_get_ofpath() - get the path of the node of the boot medium the
+ *                           BootROM loaded the first boot stage from
+ *
+ * Platforms implement this so that /chosen/bootsource can be recorded in the
+ * device tree handed to the next boot stage and to the OS. The default
+ * implementation passes on what a previous stage recorded in the control
+ * device tree of the current stage.
+ *
+ * Return: full node path of the boot medium, or NULL if unknown
+ */
+const char *bootsource_get_ofpath(void);
+
+/**
+ * fdt_fixup_bootsource() - record the BootROM boot medium in /chosen
+ *
+ * @fdt: FDT address in memory
+ *
+ * Sets /chosen/bootsource to the path returned by bootsource_get_ofpath(),
+ * if that path is known and @fdt has a node at it. The /chosen node is
+ * created if necessary.
+ *
+ * Return: 0 if ok or nothing to do, or -FDT_ERR_... on error
+ */
+int fdt_fixup_bootsource(void *fdt);
+
 /**
  * fdt_initrd() - add initrd information to the FDT before booting the OS
  *
-- 
2.48.1

Reply via email to