[U-Boot-Users] [RFC] Remove some redundant fdt code from do_bootm_linux

There were a number of places where libfdt and the old ft code were doing essentially the same thing. By adding some stubs for some of the libfdt convenience functions, we can eliminate some of these redundancies.
This patch has some overlap with a patch Jerry already submitted, so I'm not expecting this to apply. I'm just interested in opinions as to whether this is a good approach.
In the process: * Eliminated a bug in the libfdt error handling for uImages where a correct header would trigger an error * Moved the debug message about transferring control to Linux next to the first potential invocation of Linux * Did a few minor formatting tweaks to improve readability * Removed what appeared to be redundant calls to fdt_chosen, fdt_env, and fdt_bd_t * Eliminated the #ifdef protecting the if statement which checked if we had an of_flat_tree. If CONFIG_OF_FLAT_TREE or CONFIG_OF_LIBFDT aren't defined, then of_flat_tree will be NULL (and any compiler will eliminate the check in that case) * Made clear in a few places that LIBFDT and OF_FLAT_TREE are mutually exclusive * Added definition for fdt_check_header (evaluates to 0 if the header is of type OF_DT_HEADER * Added definition for fdt_totalsize() (evaluates to the value of totalsize) * Added a stub for fdt_open_into() which just does the memmove and returns 0
Signed-off-by: Andy Fleming afleming@freescale.com --- common/cmd_bootm.c | 102 +++++++++++++--------------------------------------- include/ft_build.h | 11 ++++++ 2 files changed, 36 insertions(+), 77 deletions(-)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index d12ef76..b995b34 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -534,10 +534,8 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, bd_t *kbd; void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); image_header_t *hdr = &header; -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) char *of_flat_tree = NULL; ulong of_data = 0; -#endif
if ((s = getenv ("initrd_high")) != NULL) { /* a value of "no" or a similar string will act like 0, @@ -748,13 +746,9 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, if(argc > 3) { of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16); hdr = (image_header_t *)of_flat_tree; -#if defined(CONFIG_OF_LIBFDT) - if (fdt_check_header(of_flat_tree) == 0) { -#else - if (*(ulong *)of_flat_tree == OF_DT_HEADER) { -#endif + if (fdt_check_header(of_flat_tree) == 0) of_data = (ulong)of_flat_tree; - } else if (ntohl(hdr->ih_magic) == IH_MAGIC) { + else if (ntohl(hdr->ih_magic) == IH_MAGIC) { printf("## Flat Device Tree Image at %08lX\n", hdr); print_image_hdr(hdr);
@@ -791,11 +785,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, printf("ERROR: uImage is not uncompressed\n"); return; } -#if defined(CONFIG_OF_LIBFDT) - if (fdt_check_header(of_flat_tree + sizeof(image_header_t)) == 0) { -#else - if (*((ulong *)(of_flat_tree + sizeof(image_header_t))) != OF_DT_HEADER) { -#endif + if (fdt_check_header(of_flat_tree + sizeof(image_header_t)) != 0) { printf ("ERROR: uImage data is not a flat device tree\n"); return; } @@ -832,20 +822,12 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, of_data += 4 - tail; }
-#if defined(CONFIG_OF_LIBFDT) if (fdt_check_header((void *)of_data) != 0) { -#else - if (((struct boot_param_header *)of_data)->magic != OF_DT_HEADER) { -#endif printf ("ERROR: image is not a flat device tree\n"); return; }
-#if defined(CONFIG_OF_LIBFDT) if (be32_to_cpu(fdt_totalsize(of_data)) != ntohl(len_ptr[2])) { -#else - if (((struct boot_param_header *)of_data)->totalsize != ntohl(len_ptr[2])) { -#endif printf ("ERROR: flat device tree size does not agree with image\n"); return; } @@ -920,16 +902,10 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, initrd_end = 0; }
- debug ("## Transferring control to Linux (at address %08lx) ...\n", - (ulong)kernel); - - SHOW_BOOT_PROGRESS (15); - #if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500) unlock_ram_in_cache(); #endif
-#if defined(CONFIG_OF_LIBFDT) /* move of_flat_tree if needed */ if (of_data) { int err; @@ -937,62 +913,35 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
of_len = be32_to_cpu(fdt_totalsize(of_data));
- /* position on a 4K boundary before the initrd/kbd */ - of_start = (ulong)kbd - of_len; + /* + * Position on a 4K boundary before the initrd/kbd, + * and give it a little extra room + */ + of_start = (ulong)kbd - of_len - 8192; of_start &= ~(4096 - 1); /* align on page */ - debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", + + debug("## Device Tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", of_data, of_data + of_len - 1, of_len, of_len);
of_flat_tree = (char *)of_start; + printf (" Loading Device Tree to %08lx, end %08lx ... ", of_start, of_start + of_len - 1); + err = fdt_open_into((void *)of_start, (void *)of_data, of_len); if (err != 0) { - printf ("libfdt: %s " __FILE__ " %d\n", fdt_strerror(err), __LINE__); - } - printf("OK\n"); - - /* - * Add the chosen node if it doesn't exist, add the env and bd_t - * if the user wants it (the logic is in the subroutines). - */ - if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) { - printf("Failed creating the /chosen node (0x%08X), aborting.\n", of_flat_tree); - return; - } -#ifdef CONFIG_OF_HAS_UBOOT_ENV - if (fdt_env(of_flat_tree) < 0) { - printf("Failed creating the /u-boot-env node, aborting.\n"); - return; - } -#endif -#ifdef CONFIG_OF_HAS_BD_T - if (fdt_bd_t(of_flat_tree) < 0) { - printf("Failed creating the /bd_t node, aborting.\n"); - return; - } +#ifdef CONFIG_OF_LIBFDT + printf ("libfdt: %s " __FILE__ " %d\n", + fdt_strerror(err), __LINE__); #endif + } else + printf("OK\n"); } -#endif -#if defined(CONFIG_OF_FLAT_TREE) - /* move of_flat_tree if needed */ - if (of_data) { - ulong of_start, of_len; - of_len = ((struct boot_param_header *)of_data)->totalsize;
- /* provide extra 8k pad */ - of_start = (ulong)kbd - of_len - 8192; - of_start &= ~(4096 - 1); /* align on page */ - debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - of_data, of_data + of_len - 1, of_len, of_len); + debug ("## Transferring control to Linux (at address %08lx) ...\n", + (ulong)kernel);
- of_flat_tree = (char *)of_start; - printf (" Loading Device Tree to %08lx, end %08lx ... ", - of_start, of_start + of_len - 1); - memmove ((void *)of_start, (void *)of_data, of_len); - printf ("OK\n"); - } -#endif + SHOW_BOOT_PROGRESS (15);
/* * Linux Kernel Parameters (passing board info data): @@ -1002,9 +951,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, * r6: Start of command line string * r7: End of command line string */ -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) if (!of_flat_tree) /* no device tree; boot old style */ -#endif (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); /* does not return */
@@ -1020,10 +967,11 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, #if defined(CONFIG_OF_FLAT_TREE) ft_setup(of_flat_tree, kbd, initrd_start, initrd_end); /* ft_dump_blob(of_flat_tree); */ -#endif -#if defined(CONFIG_OF_LIBFDT) + +#else /* defined(CONFIG_OF_LIBFDT) */ if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) { - printf("Failed creating the /chosen node (0x%08X), aborting.\n", of_flat_tree); + printf("Failed creating the /chosen node (0x%08X), aborting.\n", + of_flat_tree); return; } #ifdef CONFIG_OF_HAS_UBOOT_ENV @@ -1041,7 +989,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, #endif /* if defined(CONFIG_OF_LIBFDT) */
(*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0); -#endif +#endif /* CONFIG_OF_FLAT_TREE || CONFIG_OF_LIBFDT */ } #endif /* CONFIG_PPC */
diff --git a/include/ft_build.h b/include/ft_build.h index 89c689c..c2222f7 100644 --- a/include/ft_build.h +++ b/include/ft_build.h @@ -20,6 +20,17 @@
#define OF_DT_VERSION 0x10
+/* Mimic some libfdt functions to reduce redundancy */ +#define fdt_check_header(fdt) (*(ulong *)fdt != OF_DT_HEADER) +#define fdt_totalsize(fdt) (((struct boot_param_header *)of_data)->totalsize) + +static inline int fdt_open_into(void *dest, void *src, int len) +{ + memmove(dest, src, len); + + return 0; +} + struct boot_param_header { u32 magic; /* magic word OF_DT_HEADER */ u32 totalsize; /* total size of DT block */

Andy Fleming wrote:
There were a number of places where libfdt and the old ft code were doing essentially the same thing. By adding some stubs for some of the libfdt convenience functions, we can eliminate some of these redundancies.
This patch has some overlap with a patch Jerry already submitted, so I'm not expecting this to apply. I'm just interested in opinions as to whether this is a good approach.
In the process:
- Eliminated a bug in the libfdt error handling for uImages where a correct header would trigger an error
Did my latest patch set fix this or am I still missing it?
- Moved the debug message about transferring control to Linux next to the first potential invocation of Linux
Yup, that's all changed now, hopefully for the better... If I missed something or if something could be improved, hollar.
- Did a few minor formatting tweaks to improve readability
- Removed what appeared to be redundant calls to fdt_chosen, fdt_env, and fdt_bd_t
Hmm, that sure looks redundant. What was I thinking??? Oh yeah, that's right, I wasn't thinking when I hacked up bootm. :-(
- Eliminated the #ifdef protecting the if statement which checked if we had an of_flat_tree. If CONFIG_OF_FLAT_TREE or CONFIG_OF_LIBFDT aren't defined, then of_flat_tree will be NULL (and any compiler will eliminate the check in that case)
Makes sense. Simplifying is GOOD. We may want to keep the #ifdef around "of_data" to prevent a "unused variable" compiler warning (or maybe it isn't a problem, I didn't really look at it).
- Made clear in a few places that LIBFDT and OF_FLAT_TREE are mutually exclusive
- Added definition for fdt_check_header (evaluates to 0 if the header is of type OF_DT_HEADER
- Added definition for fdt_totalsize() (evaluates to the value of totalsize)
- Added a stub for fdt_open_into() which just does the memmove and returns 0
WRT the above, my intent is to evangelize for LIBFDT, convert the other targets that use fdt to LIBFDT, and remove OF_FLAT_TREE. That solves the above bullets in a whole lot cleaner fashion. LIBFDT does everything OF_FLAT_TREE does and much more. It's just a problem of time (unlike Wolfgang, I need to sleep ;-).
The conversion is not difficult, following my lead on the MPC8360. There are three functions that need to be updated. The three functions that need to be converted are: * ft_board_setup * ft_cpu_setup * ft_pci_setup
See the table in the ToDo section: http://www.denx.de/wiki/view/UBoot/UBootFdtInfo#ToDo
Signed-off-by: Andy Fleming afleming@freescale.com
Thanks for the thoughts & proposals, gvb
participants (2)
-
Andy Fleming
-
Jerry Van Baren