Standard passage provides for a bloblist to be passed from one firmware
phase to the next. That can be used to pass the devicetree along as well.
Add an option to support this.

Tests for this will be added as part of the Universal Payload work.

Note: This is the correct way to deal with bloblist, since it allows
boards to choose whether they want to use the devicetree from there, or
not.

Link: 
https://patchwork.ozlabs.org/project/uboot/patch/20231226094625.221671-1-...@chromium.org/
Link: 
https://patchwork.ozlabs.org/project/uboot/patch/20231228133654.2356023-1-...@chromium.org/
Link: 
https://patchwork.ozlabs.org/project/uboot/patch/20231228194725.2482268-1-...@chromium.org/
Link: 
https://patchwork.ozlabs.org/project/uboot/patch/20240104014919.413568-1-...@chromium.org/
Link: 
https://patchwork.ozlabs.org/project/uboot/patch/20230921015730.1511373-31-...@chromium.org/
Link: 
https://patchwork.ozlabs.org/project/uboot/patch/20230830180524.315916-31-...@chromium.org/

Signed-off-by: Simon Glass <s...@chromium.org>
---

 common/bloblist.c                  |  1 +
 doc/develop/devicetree/control.rst |  3 ++
 dts/Kconfig                        |  8 ++++++
 include/fdtdec.h                   |  3 +-
 lib/fdtdec.c                       | 44 ++++++++++++++++++++++--------
 5 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/common/bloblist.c b/common/bloblist.c
index ec6ff7a5a93..e8acfc74331 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -56,6 +56,7 @@ static struct tag_name {
        { BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" },
        { BLOBLISTT_SMBIOS_TABLES, "SMBIOS tables for x86" },
        { BLOBLISTT_VBOOT_CTX, "Chrome OS vboot context" },
+       { BLOBLISTT_CONTROL_FDT, "Control FDT" },
 
        /* BLOBLISTT_PROJECT_AREA */
        { BLOBLISTT_U_BOOT_SPL_HANDOFF, "SPL hand-off" },
diff --git a/doc/develop/devicetree/control.rst 
b/doc/develop/devicetree/control.rst
index 2a3b48fa6c7..4180eeb5629 100644
--- a/doc/develop/devicetree/control.rst
+++ b/doc/develop/devicetree/control.rst
@@ -137,6 +137,9 @@ If `OF_BOARD` is selected by Kconfig, a board-specific 
routine will provide the
 devicetree at runtime, for example if an earlier bootloader stage creates
 it and passes it to U-Boot.
 
+If CONFIG_OF_BLOBLIST is defined, the devicetree comes from a bloblist passed
+from a previous stage.
+
 If CONFIG_SANDBOX is defined, then it will be read from a file on
 startup. Use the -d flag to U-Boot to specify the file to read, -D for the
 default and -T for the test devicetree, used to run sandbox unit tests.
diff --git a/dts/Kconfig b/dts/Kconfig
index ffd50c04846..41a758e83a6 100644
--- a/dts/Kconfig
+++ b/dts/Kconfig
@@ -167,6 +167,14 @@ config OF_INITIAL_DTB_READONLY
          If initial DTB for DT control is read-only (e.g. points to
          memory-mapped flash memory), then set this option.
 
+config OF_BLOBLIST
+       bool "DTB is provided by a bloblist"
+       help
+         Select this to read the devicetree from the bloblist. This allows
+         using a bloblist to transfer the devicetree between  U-Boot phases.
+         The devicetree is stored in the bloblist by an early phase so that
+         U-Boot can read it.
+
 config OF_BOARD
        bool "Provided by the board (e.g a previous loader) at runtime"
        default y if SANDBOX || OF_HAS_PRIOR_STAGE
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 8f25e1b7e92..aa7e4b62dbf 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -72,7 +72,7 @@ struct bd_info;
  *     U-Boot is packaged as an ELF file, e.g. for debugging purposes
  * @FDTSRC_ENV: Provided by the fdtcontroladdr environment variable. This 
should
  *     be used for debugging/development only
- * @FDTSRC_NONE: No devicetree at all
+ * @FDTSRC_BLOBLIST: Provided by a bloblist from an earlier phase
  */
 enum fdt_source_t {
        FDTSRC_SEPARATE,
@@ -80,6 +80,7 @@ enum fdt_source_t {
        FDTSRC_BOARD,
        FDTSRC_EMBED,
        FDTSRC_ENV,
+       FDTSRC_BLOBLIST,
 };
 
 /*
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index d36b01bd3f1..9d3afb79d87 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -7,6 +7,10 @@
  */
 
 #ifndef USE_HOSTCC
+
+#define LOG_CATEGORY   LOGC_DT
+
+#include <bloblist.h>
 #include <boot_fit.h>
 #include <display_options.h>
 #include <dm.h>
@@ -86,6 +90,7 @@ static const char *const fdt_src_name[] = {
        [FDTSRC_BOARD] = "board",
        [FDTSRC_EMBED] = "embed",
        [FDTSRC_ENV] = "env",
+       [FDTSRC_BLOBLIST] = "bloblist",
 };
 
 const char *fdtdec_get_srcname(void)
@@ -1664,20 +1669,35 @@ int fdtdec_setup(void)
        int ret;
 
        /* The devicetree is typically appended to U-Boot */
-       if (IS_ENABLED(CONFIG_OF_SEPARATE)) {
-               gd->fdt_blob = fdt_find_separate();
-               gd->fdt_src = FDTSRC_SEPARATE;
-       } else { /* embed dtb in ELF file for testing / development */
-               gd->fdt_blob = dtb_dt_embedded();
-               gd->fdt_src = FDTSRC_EMBED;
-       }
-
-       /* Allow the board to override the fdt address. */
-       if (IS_ENABLED(CONFIG_OF_BOARD)) {
-               gd->fdt_blob = board_fdt_blob_setup(&ret);
+       if (CONFIG_IS_ENABLED(OF_BLOBLIST)) {
+               ret = bloblist_maybe_init();
                if (ret)
                        return ret;
-               gd->fdt_src = FDTSRC_BOARD;
+               gd->fdt_blob = bloblist_find(BLOBLISTT_CONTROL_FDT, 0);
+               if (!gd->fdt_blob) {
+                       printf("Not FDT found in bloblist\n");
+                       bloblist_show_list();
+                       return -ENOENT;
+               }
+               gd->fdt_src = FDTSRC_BLOBLIST;
+               bloblist_show_list();
+               log_debug("Devicetree is in bloblist at %p\n", gd->fdt_blob);
+       } else {
+               if (IS_ENABLED(CONFIG_OF_SEPARATE)) {
+                       gd->fdt_blob = fdt_find_separate();
+                       gd->fdt_src = FDTSRC_SEPARATE;
+               } else { /* embed dtb in ELF file for testing / development */
+                       gd->fdt_blob = dtb_dt_embedded();
+                       gd->fdt_src = FDTSRC_EMBED;
+               }
+
+               /* Allow the board to override the fdt address. */
+               if (IS_ENABLED(CONFIG_OF_BOARD)) {
+                       gd->fdt_blob = board_fdt_blob_setup(&ret);
+                       if (ret)
+                               return ret;
+                       gd->fdt_src = FDTSRC_BOARD;
+               }
        }
 
        /* Allow the early environment to override the fdt address */
-- 
2.43.0

Reply via email to