From 3f51f78cbd1537deacf6ba163b014f9b200defd4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 16 Dec 2021 20:59:24 -0700 Subject: fdt: Move MULTI_DTB_FIT handling out of fdtdec_setup() This logic is a bit convoluted for one function. Move the mulit-FIT part into its own function. Signed-off-by: Simon Glass Reviewed-by: Ilias Apalodimas --- lib/fdtdec.c | 62 +++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 24 deletions(-) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 7681f272d27..e0ce2532f95 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1594,13 +1594,46 @@ __weak int fdtdec_board_setup(const void *fdt_blob) return 0; } +/** + * setup_multi_dtb_fit() - locate the correct dtb from a FIT + * + * This supports the CONFIG_MULTI_DTB_FIT feature, looking for the dtb in a + * supplied FIT + * + * It accepts the current value of gd->fdt_blob, which points to the FIT, then + * updates that gd->fdt_blob, to point to the chosen dtb so that U-Boot uses the + * correct one + */ +static void setup_multi_dtb_fit(void) +{ +# if CONFIG_IS_ENABLED(MULTI_DTB_FIT) + void *blob; + + /* + * Try and uncompress the blob. + * Unfortunately there is no way to know how big the input blob really + * is. So let us set the maximum input size arbitrarily high. 16MB + * ought to be more than enough for packed DTBs. + */ + if (uncompress_blob(gd->fdt_blob, 0x1000000, &blob) == 0) + gd->fdt_blob = blob; + + /* + * Check if blob is a FIT images containings DTBs. + * If so, pick the most relevant + */ + blob = locate_dtb_in_fit(gd->fdt_blob); + if (blob) { + gd->multi_dtb_fit = gd->fdt_blob; + gd->fdt_blob = blob; + } +#endif /* # MULTI_DTB_FIT */ +} + int fdtdec_setup(void) { int ret; #if CONFIG_IS_ENABLED(OF_CONTROL) -# if CONFIG_IS_ENABLED(MULTI_DTB_FIT) - void *fdt_blob; -# endif # ifdef CONFIG_OF_EMBED /* Get a pointer to the FDT */ # ifdef CONFIG_SPL_BUILD @@ -1621,27 +1654,8 @@ int fdtdec_setup(void) (unsigned long)map_to_sysmem(gd->fdt_blob)), 0); # endif -# if CONFIG_IS_ENABLED(MULTI_DTB_FIT) - /* - * Try and uncompress the blob. - * Unfortunately there is no way to know how big the input blob really - * is. So let us set the maximum input size arbitrarily high. 16MB - * ought to be more than enough for packed DTBs. - */ - if (uncompress_blob(gd->fdt_blob, 0x1000000, &fdt_blob) == 0) - gd->fdt_blob = fdt_blob; - - /* - * Check if blob is a FIT images containings DTBs. - * If so, pick the most relevant - */ - fdt_blob = locate_dtb_in_fit(gd->fdt_blob); - if (fdt_blob) { - gd->multi_dtb_fit = gd->fdt_blob; - gd->fdt_blob = fdt_blob; - } - -# endif + if (CONFIG_IS_ENABLED(MULTI_DTB_FIT)) + setup_multi_dtb_fit(); #endif ret = fdtdec_prepare_fdt(); -- cgit v1.2.3 From b4b6daf38d49c73f670bbf1654b568bca222fa79 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 16 Dec 2021 20:59:25 -0700 Subject: fdt: Drop #ifdefs with MULTI_DTB_FIT Refactor the code to drop the #ifdefs for this feature. Signed-off-by: Simon Glass --- lib/fdtdec.c | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index e0ce2532f95..4967ab87075 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1146,11 +1146,10 @@ int fdtdec_setup_mem_size_base_lowest(void) return 0; } -#if CONFIG_IS_ENABLED(MULTI_DTB_FIT) -# if CONFIG_IS_ENABLED(MULTI_DTB_FIT_GZIP) ||\ - CONFIG_IS_ENABLED(MULTI_DTB_FIT_LZO) static int uncompress_blob(const void *src, ulong sz_src, void **dstp) { +#if CONFIG_IS_ENABLED(MULTI_DTB_FIT_GZIP) ||\ + CONFIG_IS_ENABLED(MULTI_DTB_FIT_LZO) size_t sz_out = CONFIG_VAL(MULTI_DTB_FIT_UNCOMPRESS_SZ); bool gzip = 0, lzo = 0; ulong sz_in = sz_src; @@ -1175,11 +1174,11 @@ static int uncompress_blob(const void *src, ulong sz_src, void **dstp) return -ENOMEM; } } else { -# if CONFIG_IS_ENABLED(MULTI_DTB_FIT_USER_DEFINED_AREA) +# if CONFIG_IS_ENABLED(MULTI_DTB_FIT_USER_DEFINED_AREA) dst = (void *)CONFIG_VAL(MULTI_DTB_FIT_USER_DEF_ADDR); -# else +# else return -ENOTSUPP; -# endif +# endif } if (CONFIG_IS_ENABLED(GZIP) && gzip) @@ -1197,16 +1196,12 @@ static int uncompress_blob(const void *src, ulong sz_src, void **dstp) return -EBADMSG; } *dstp = dst; - return 0; -} -# else -static int uncompress_blob(const void *src, ulong sz_src, void **dstp) -{ +#else + *dstp = (void *)src; *dstp = (void *)src; +#endif return 0; } -# endif -#endif #if defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE) /* @@ -1606,7 +1601,6 @@ __weak int fdtdec_board_setup(const void *fdt_blob) */ static void setup_multi_dtb_fit(void) { -# if CONFIG_IS_ENABLED(MULTI_DTB_FIT) void *blob; /* @@ -1624,10 +1618,9 @@ static void setup_multi_dtb_fit(void) */ blob = locate_dtb_in_fit(gd->fdt_blob); if (blob) { - gd->multi_dtb_fit = gd->fdt_blob; + gd_set_multi_dtb_fit(gd->fdt_blob); gd->fdt_blob = blob; } -#endif /* # MULTI_DTB_FIT */ } int fdtdec_setup(void) @@ -1664,7 +1657,6 @@ int fdtdec_setup(void) return ret; } -#if CONFIG_IS_ENABLED(MULTI_DTB_FIT) int fdtdec_resetup(int *rescan) { void *fdt_blob; @@ -1675,8 +1667,8 @@ int fdtdec_resetup(int *rescan) * FIT image stillpresent there. Save the time and space * required to uncompress it again. */ - if (gd->multi_dtb_fit) { - fdt_blob = locate_dtb_in_fit(gd->multi_dtb_fit); + if (gd_multi_dtb_fit()) { + fdt_blob = locate_dtb_in_fit(gd_multi_dtb_fit()); if (fdt_blob == gd->fdt_blob) { /* @@ -1700,7 +1692,6 @@ int fdtdec_resetup(int *rescan) *rescan = 0; return 0; } -#endif int fdtdec_decode_ram_size(const void *blob, const char *area, int board_id, phys_addr_t *basep, phys_size_t *sizep, -- cgit v1.2.3 From d893b8ad095f952829933c79b09345ae0c8ebd6b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 16 Dec 2021 20:59:26 -0700 Subject: fdt: Drop CONFIG_SPL_BUILD check in fdtdec_setup() Move this to the header file to clean up the C code. Signed-off-by: Simon Glass --- lib/fdtdec.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 4967ab87075..fbdc92c0813 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1629,11 +1629,7 @@ int fdtdec_setup(void) #if CONFIG_IS_ENABLED(OF_CONTROL) # ifdef CONFIG_OF_EMBED /* Get a pointer to the FDT */ -# ifdef CONFIG_SPL_BUILD - gd->fdt_blob = __dtb_dt_spl_begin; -# else - gd->fdt_blob = __dtb_dt_begin; -# endif + gd->fdt_blob = dtb_dt_embedded(); # elif defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE) /* Allow the board to override the fdt address. */ gd->fdt_blob = board_fdt_blob_setup(&ret); -- cgit v1.2.3 From 66cd511f133a2f0e5f38d3c92317c851e42b01c0 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 16 Dec 2021 20:59:27 -0700 Subject: fdt: Drop #ifdef around board_fdt_blob_setup() This serves no purpose. Drop it. Signed-off-by: Simon Glass --- lib/fdtdec.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index fbdc92c0813..299a2c3a32f 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1203,7 +1203,6 @@ static int uncompress_blob(const void *src, ulong sz_src, void **dstp) return 0; } -#if defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE) /* * For CONFIG_OF_SEPARATE, the board may optionally implement this to * provide and/or fixup the fdt. @@ -1226,7 +1225,6 @@ __weak void *board_fdt_blob_setup(int *err) return fdt_blob; } -#endif int fdtdec_set_ethernet_mac_address(void *fdt, const u8 *mac, size_t size) { -- cgit v1.2.3 From 931511d0897ea1f63102b134733e3a71d3545f64 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 16 Dec 2021 20:59:28 -0700 Subject: fdt: Use if() for fdtcontroladdr check Change this to use if() instead of #if Signed-off-by: Simon Glass --- lib/fdtdec.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 299a2c3a32f..659aeffd82e 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1634,12 +1634,11 @@ int fdtdec_setup(void) if (ret) return ret; # endif -# ifndef CONFIG_SPL_BUILD - /* Allow the early environment to override the fdt address */ - gd->fdt_blob = map_sysmem - (env_get_ulong("fdtcontroladdr", 16, + if (!IS_ENABLED(CONFIG_SPL_BUILD)) { + /* Allow the early environment to override the fdt address */ + gd->fdt_blob = map_sysmem(env_get_ulong("fdtcontroladdr", 16, (unsigned long)map_to_sysmem(gd->fdt_blob)), 0); -# endif + } if (CONFIG_IS_ENABLED(MULTI_DTB_FIT)) setup_multi_dtb_fit(); -- cgit v1.2.3 From b5199380fc993174a795994f00ef3d67e60142c1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 16 Dec 2021 20:59:29 -0700 Subject: fdt: Drop OF_CONTROL check in fdtdec_setup() This function should only be called when OF_CONTROL is enabled. It fails in fdtdec_prepare_fdt() anyway, since gd->fdt_blob stays as NULL if OF_CONTROL is not enabled. Drop this useless check. Signed-off-by: Simon Glass --- lib/fdtdec.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 659aeffd82e..5b31064cee2 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1624,16 +1624,15 @@ static void setup_multi_dtb_fit(void) int fdtdec_setup(void) { int ret; -#if CONFIG_IS_ENABLED(OF_CONTROL) -# ifdef CONFIG_OF_EMBED +#ifdef CONFIG_OF_EMBED /* Get a pointer to the FDT */ gd->fdt_blob = dtb_dt_embedded(); -# elif defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE) +#elif defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE) /* Allow the board to override the fdt address. */ gd->fdt_blob = board_fdt_blob_setup(&ret); if (ret) return ret; -# endif +#endif if (!IS_ENABLED(CONFIG_SPL_BUILD)) { /* Allow the early environment to override the fdt address */ gd->fdt_blob = map_sysmem(env_get_ulong("fdtcontroladdr", 16, @@ -1642,7 +1641,6 @@ int fdtdec_setup(void) if (CONFIG_IS_ENABLED(MULTI_DTB_FIT)) setup_multi_dtb_fit(); -#endif ret = fdtdec_prepare_fdt(); if (!ret) -- cgit v1.2.3 From ba83d8593bde7aec6055ea5fe200b8db6f1b0810 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 16 Dec 2021 20:59:30 -0700 Subject: fdt: Drop remaining preprocessor macros in fdtdec_setup() We only have two choices for obtaining the devicetree. Simplify the code to make that clear. Signed-off-by: Simon Glass --- lib/fdtdec.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 5b31064cee2..a7f62123a94 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1624,15 +1624,17 @@ static void setup_multi_dtb_fit(void) int fdtdec_setup(void) { int ret; -#ifdef CONFIG_OF_EMBED - /* Get a pointer to the FDT */ - gd->fdt_blob = dtb_dt_embedded(); -#elif defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE) - /* Allow the board to override the fdt address. */ - gd->fdt_blob = board_fdt_blob_setup(&ret); - if (ret) - return ret; -#endif + + /* The devicetree is typically appended to U-Boot */ + if (IS_ENABLED(CONFIG_OF_SEPARATE) || IS_ENABLED(CONFIG_OF_BOARD)) { + /* Allow the board to override the fdt address. */ + gd->fdt_blob = board_fdt_blob_setup(&ret); + if (ret) + return ret; + } else { /* embed dtb in ELF file for testing / development */ + gd->fdt_blob = dtb_dt_embedded(); + } + if (!IS_ENABLED(CONFIG_SPL_BUILD)) { /* Allow the early environment to override the fdt address */ gd->fdt_blob = map_sysmem(env_get_ulong("fdtcontroladdr", 16, -- cgit v1.2.3 From 985503439762c3168aeb80f529bb9bbcd773dd2c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 16 Dec 2021 20:59:31 -0700 Subject: fdt: Don't call board_fdt_blob_setup() without OF_BOARD At present this override function is called even when OF_BOARD is not enabled. This makes it impossible to disable this feature and in fact makes the OF_BOARD option useless. Reinstate its intended purpose, so that it is possible to switch between the appended devicetree and one provided by the board's custom function. A follower patch adds warnings for this scenario, but for now we don't have a Kconfig that definitively tells us that OF_BOARD should be used. Signed-off-by: Simon Glass --- lib/fdtdec.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index a7f62123a94..31a509bc221 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1203,15 +1203,15 @@ static int uncompress_blob(const void *src, ulong sz_src, void **dstp) return 0; } -/* - * For CONFIG_OF_SEPARATE, the board may optionally implement this to - * provide and/or fixup the fdt. +/** + * fdt_find_separate() - Find a devicetree at the end of the image + * + * @return pointer to FDT blob */ -__weak void *board_fdt_blob_setup(int *err) +static void *fdt_find_separate(void) { void *fdt_blob = NULL; - *err = 0; #ifdef CONFIG_SPL_BUILD /* FDT is at end of BSS unless it is in a different memory region */ if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS)) @@ -1626,13 +1626,16 @@ int fdtdec_setup(void) int ret; /* The devicetree is typically appended to U-Boot */ - if (IS_ENABLED(CONFIG_OF_SEPARATE) || IS_ENABLED(CONFIG_OF_BOARD)) { - /* Allow the board to override the fdt address. */ + if (IS_ENABLED(CONFIG_OF_SEPARATE)) + gd->fdt_blob = fdt_find_separate(); + else /* embed dtb in ELF file for testing / development */ + gd->fdt_blob = dtb_dt_embedded(); + + /* 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; - } else { /* embed dtb in ELF file for testing / development */ - gd->fdt_blob = dtb_dt_embedded(); } if (!IS_ENABLED(CONFIG_SPL_BUILD)) { -- cgit v1.2.3 From 39605c6ec3618a848a4a1c4063d474270deab442 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 16 Dec 2021 20:59:33 -0700 Subject: fdt: Record where the devicetree came from Keep track of where the devicetree came from, so we can report this later. Signed-off-by: Simon Glass --- lib/fdtdec.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 31a509bc221..8cfa958fb96 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1618,6 +1618,7 @@ static void setup_multi_dtb_fit(void) if (blob) { gd_set_multi_dtb_fit(gd->fdt_blob); gd->fdt_blob = blob; + gd->fdt_src = FDTSRC_FIT; } } @@ -1626,22 +1627,31 @@ int fdtdec_setup(void) int ret; /* The devicetree is typically appended to U-Boot */ - if (IS_ENABLED(CONFIG_OF_SEPARATE)) + if (IS_ENABLED(CONFIG_OF_SEPARATE)) { gd->fdt_blob = fdt_find_separate(); - else /* embed dtb in ELF file for testing / development */ + 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 */ if (!IS_ENABLED(CONFIG_SPL_BUILD)) { - /* Allow the early environment to override the fdt address */ - gd->fdt_blob = map_sysmem(env_get_ulong("fdtcontroladdr", 16, - (unsigned long)map_to_sysmem(gd->fdt_blob)), 0); + ulong addr; + + addr = env_get_hex("fdtcontroladdr", 0); + if (addr) { + gd->fdt_blob = map_sysmem(addr, 0); + gd->fdt_src = FDTSRC_ENV; + } } if (CONFIG_IS_ENABLED(MULTI_DTB_FIT)) -- cgit v1.2.3 From ff66e7bb73233a4decfcdb66b7a858399dbccf50 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 16 Dec 2021 20:59:34 -0700 Subject: fdt: Report the devicetree source It can be confusing to figure out where the devicetree came from. It seems important enough to warrant a message during boot. Add information about the number of devices and uclasses too since it is helpful to have some idea what is going on with driver model. Report the devicetree source in bdinfo too. This looks something like this, with > marking the new line. U-Boot 2021.10-00190 (Oct 30 2021 - 09:01:29 -0600) DRAM: 128 MiB > Core: 42 devices, 11 uclasses, devicetree: passage Flash: 64 MiB Signed-off-by: Simon Glass --- lib/fdtdec.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 8cfa958fb96..118c100b389 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -76,6 +76,19 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(ALTERA_SOCFPGA_CLK_INIT, "altr,socfpga-a10-clk-init") }; +static const char *const fdt_src_name[] = { + [FDTSRC_SEPARATE] = "separate", + [FDTSRC_FIT] = "fit", + [FDTSRC_BOARD] = "board", + [FDTSRC_EMBED] = "embed", + [FDTSRC_ENV] = "env", +}; + +const char *fdtdec_get_srcname(void) +{ + return fdt_src_name[gd->fdt_src]; +} + const char *fdtdec_get_compatible(enum fdt_compat_id id) { /* We allow reading of the 'unknown' ID for testing purposes */ -- cgit v1.2.3 From 275b4832f6bf91ca723430efe93be06e4f07430d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 16 Dec 2021 20:59:35 -0700 Subject: fdt: Add a Kconfig for boards with a prior stage When U-Boot is started from another firmware program, not just a prior phase of U-Boot, special behaviour is typically used. In particular, the device tree may come from that prior stage. At present this is sort-of indicated by OF_BOARD, although the correlation is not 1:1, since that option simply means that the board has a custom mechanism for obtaining the device tree. For example, sandbox defines OF_BOARD. Also the board_fdt_blob_setup() function can in fact make use of the devicetree in U-Boot if it wishes, as used by dragonboard410c until very recently. Add an explicit Kconfig for this situation. Update the OF_BOARD option to more-accurately reflect what it is doing, e.g. for sandbox. Drop the docs in the README as it is out of date. Signed-off-by: Simon Glass --- lib/fdtdec.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 118c100b389..280cda61a72 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1595,6 +1595,7 @@ int fdtdec_set_carveout(void *blob, const char *node, const char *prop_name, return 0; } +/* TODO(sjg@chromium.org): This function should not be weak */ __weak int fdtdec_board_setup(const void *fdt_blob) { return 0; -- cgit v1.2.3