
From: Simon Glass sjg@chromium.org
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. If CONFIG_OF_BOARD is defined, a board custom routine will provide a bloblist or a specified memory address to retrieve the devicetree at runtime. A devicetree from a bloblist is prioritized than the one from specified memory region.
Tests for this will be added as part of the Universal Payload work.
Signed-off-by: Simon Glass sjg@chromium.org Co-developed-by: Raymond Mao raymond.mao@linaro.org Signed-off-by: Raymond Mao raymond.mao@linaro.org --- Changes in v2 - New patch file created for v2. Amended from the original patch "[v2,30/32] fdt: Allow the devicetree to come from a bloblist". Remove CONFIG_OF_BLOBLIST and FDTSRC_BLOBLIST, a DTB from a previous loader is defined by CONFIG_OF_BOARD. The DTB can be located either in the bloblist or from a specified memory address.
doc/develop/devicetree/control.rst | 8 +++-- dts/Kconfig | 9 ++++-- include/fdtdec.h | 3 +- lib/fdtdec.c | 52 +++++++++++++++++++++++------- 4 files changed, 53 insertions(+), 19 deletions(-)
diff --git a/doc/develop/devicetree/control.rst b/doc/develop/devicetree/control.rst index cbb65c9b17..a7f0f87841 100644 --- a/doc/develop/devicetree/control.rst +++ b/doc/develop/devicetree/control.rst @@ -104,9 +104,11 @@ in u-boot.bin so you can still just flash u-boot.bin onto your board. If you are using CONFIG_SPL_FRAMEWORK, then u-boot.img will be built to include the device tree binary.
-If CONFIG_OF_BOARD is defined, 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_BOARD is defined, a board-specific routine will provide a bloblist +or a specified memory region to retrieve the devicetree at runtime, for example +if an earlier bootloader stage creates it and passes it to U-Boot. +A devicetree from a bloblist is prioritized than the one from a specified memory +region.
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 diff --git a/dts/Kconfig b/dts/Kconfig index 00c0aeff89..4faf4ba633 100644 --- a/dts/Kconfig +++ b/dts/Kconfig @@ -110,8 +110,13 @@ config OF_BOARD default y if SANDBOX || OF_HAS_PRIOR_STAGE help If this option is enabled, the device tree is provided at runtime by - a custom function called board_fdt_blob_setup(). The board must - implement this function if it wishes to provide special behaviour. + bloblist via a custom function called board_bloblist_from_boot_arg() + or a memory region from a custom function called + board_fdt_blob_setup(). The board must implement either these + functions if it wishes to provide special behaviour. + + A devicetree from a bloblist is prioritized then the one from a + specified memory region if the board provides both methods.
With this option, the device tree build by U-Boot may be overridden or ignored. See OF_HAS_PRIOR_STAGE. diff --git a/include/fdtdec.h b/include/fdtdec.h index bd1149f46d..0824fe1359 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -72,14 +72,13 @@ 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 */ enum fdt_source_t { FDTSRC_SEPARATE, FDTSRC_FIT, FDTSRC_BOARD, FDTSRC_EMBED, - FDTSRC_ENV, + FDTSRC_ENV };
/* diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 7a69167648..025baca4a4 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -7,7 +7,11 @@ */
#ifndef USE_HOSTCC + +#define LOG_CATEGORY LOGC_DT + #include <common.h> +#include <bloblist.h> #include <boot_fit.h> #include <display_options.h> #include <dm.h> @@ -86,7 +90,7 @@ static const char *const fdt_src_name[] = { [FDTSRC_FIT] = "fit", [FDTSRC_BOARD] = "board", [FDTSRC_EMBED] = "embed", - [FDTSRC_ENV] = "env", + [FDTSRC_ENV] = "env" };
const char *fdtdec_get_srcname(void) @@ -1665,21 +1669,45 @@ 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. */ + /* + * The devicetree is typically appended to U-Boot. + * Option 1: From bloblist. + * Option 2: From a specified memory address. + */ if (IS_ENABLED(CONFIG_OF_BOARD)) { - gd->fdt_blob = board_fdt_blob_setup(&ret); + /* + * DTB is from board. + * Either from bloblist or a platform specified memory. + */ + ret = bloblist_maybe_init(); if (ret) return ret; + + /* Check if a DTB exists in bloblist first */ + if (IS_ENABLED(CONFIG_BLOBLIST)) { + gd->fdt_blob = bloblist_find(BLOBLISTT_CONTROL_FDT, 0); + if (gd->fdt_blob) { + log_info("Fdt from bloblist at 0x%lx\n", + (unsigned long)gd->fdt_blob); + } + } + if (!gd->fdt_blob) { + /* Apply DTB from a platform specified memory */ + gd->fdt_blob = board_fdt_blob_setup(&ret); + if (ret) + return ret; + log_info("Fdt from memory at 0x%lx\n", + (unsigned long)gd->fdt_blob); + } gd->fdt_src = FDTSRC_BOARD; + } 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 early environment to override the fdt address */