[U-Boot] [RFC][PATCH 00/15] bootm refactoring

[PATCH 01/15] Update linux bootm to support ePAPR client interface [PATCH 02/15] add ability to disable ft_board_setup as part of bootm
possibly drop this patch if the boots method is acceptable
[PATCH 03/15] Clean up usage of icache_disable/dcache_disable [PATCH 04/15] fdt: added the ability to set initrd start/end via chosen command [PATCH 05/15] fdt: fdt addr w/o any args reports back the current working address [PATCH 06/15] bootm: refactor entry point code [PATCH 07/15] bootm: refactor ramdisk locating code [PATCH 08/15] bootm: refactor fdt locating and relocation code [PATCH 09/15] bootm: Set working fdt address as part of the bootm flow [PATCH 10/15] bootm: move lmb into the bootm_headers_t structure [PATCH 11/15] bootm: refactor image detection and os load steps [PATCH 12/15] fdt: refactor fdt resize code [PATCH 13/15] fdt: refactor initrd related code [PATCH 14/15] fdt: Added resize command [PATCH 15/15] boots: start of sub commands
I believe all the patches except 15/15 should be in a reasonable state for u-boot-testing. I need to add an 'interrupt enable/disable' command but with a small hack I'm able to mimic the bootm command on ppc by:
boots start <A> <B> <C> boots load_os /* hacked to disable interrupts */ boots prep_os boots initrd_relocate boots fdt_relocate fdt chosen $initrd_start $initrd_end fdt boardsetup boots jump
Right now 15/15 is focused on only PPC w/Linux. If this looks acceptable I'll split 15/15 into proper patches an add support for the other ARCHes and OSes.
- k

the ePAPR spec has some subtle differences from the current device tree based boot interface to the powerpc linux kernel. The powerpc linux kernel currently ignores the differences that ePAPR specifies.
Signed-off-by: Kumar Gala galak@kernel.crashing.org --- lib_ppc/bootm.c | 33 +++++++++++++++++++++++---------- 1 files changed, 23 insertions(+), 10 deletions(-)
diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index cbe5592..e83c860 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -80,7 +80,8 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ulong cmd_start, cmd_end, bootmap_base; bd_t *kbd; ulong ep = 0; - void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); + void (*kernel)(bd_t *, ulong r4, ulong r5, ulong r6, + ulong r7, ulong r8, ulong r9); int ret; ulong of_size = 0; struct lmb *lmb = images->lmb; @@ -166,8 +167,8 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], puts ("Could not find kernel entry point!\n"); goto error; } - kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; - + kernel = (void (*)(bd_t *, ulong, ulong, ulong, + ulong, ulong, ulong))ep; /* find ramdisk */ ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_PPC, &rd_data_start, &rd_data_end); @@ -282,14 +283,23 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], if (of_flat_tree) { /* device tree; boot new style */ /* * Linux Kernel Parameters (passing device tree): - * r3: pointer to the fdt, followed by the board info data - * r4: physical pointer to the kernel itself - * r5: NULL - * r6: NULL - * r7: NULL + * r3: pointer to the fdt + * r4: 0 + * r5: 0 + * r6: epapr magic + * r7: size of IMA in bytes + * r8: 0 + * r9: 0 */ +#if defined(CONFIG_85xx) || defined(CONFIG_440) + #define EPAPR_MAGIC (0x45504150) +#else + #define EPAPR_MAGIC (0x65504150) +#endif + debug (" Booting using OF flat tree...\n"); - (*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0); + (*kernel) ((bd_t *)of_flat_tree, 0, 0, EPAPR_MAGIC, + CFG_BOOTMAPSZ, 0, 0); /* does not return */ } else #endif @@ -301,9 +311,12 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], * r5: initrd_end - unused if r4 is 0 * r6: Start of command line string * r7: End of command line string + * r8: 0 + * r9: 0 */ debug (" Booting using board info...\n"); - (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); + (*kernel) (kbd, initrd_start, initrd_end, + cmd_start, cmd_end, 0, 0); /* does not return */ } return ;

if the environment variable 'no_ft_board_setup' is set we skip doing the ft_board_setup().
Signed-off-by: Kumar Gala galak@kernel.crashing.org --- lib_ppc/bootm.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index e83c860..3cb17bf 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -193,7 +193,8 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], } #ifdef CONFIG_OF_BOARD_SETUP /* Call the board-specific fixup routine */ - ft_board_setup(of_flat_tree, gd->bd); + if (!getenv("no_ft_board_setup")) + ft_board_setup(of_flat_tree, gd->bd); #endif }

There is no point in disabling the icache on 7xx/74xx/86xx parts and not also flushing the icache. All callers of invalidate_l1_instruction_cache() call icache_disable() right after. Make it so icache_disable() calls invalidate_l1_instruction_cache() for us.
Also, dcache_disable() already calls dcache_flush() so there is no point in the explicit calls of dcache_flush().
Signed-off-by: Kumar Gala galak@kernel.crashing.org --- board/Marvell/db64360/db64360.c | 5 ----- board/Marvell/db64460/db64460.c | 5 ----- board/esd/cpci750/cpci750.c | 4 ---- board/freescale/mpc7448hpc2/mpc7448hpc2.c | 2 -- board/prodrive/p3mx/p3mx.c | 2 -- common/cmd_bootm.c | 2 -- cpu/74xx_7xx/cache.S | 4 ++++ cpu/mpc86xx/cache.S | 4 ++++ 8 files changed, 8 insertions(+), 20 deletions(-)
diff --git a/board/Marvell/db64360/db64360.c b/board/Marvell/db64360/db64360.c index a2ab2d7..2a810a6 100644 --- a/board/Marvell/db64360/db64360.c +++ b/board/Marvell/db64360/db64360.c @@ -51,9 +51,6 @@ #define DP(x) #endif
-extern void flush_data_cache (void); -extern void invalidate_l1_instruction_cache (void); - /* ------------------------------------------------------------------------- */
/* this is the current GT register space location */ @@ -930,7 +927,5 @@ void board_prebootm_init () my_remap_gt_regs_bootm (CFG_GT_REGS, BRIDGE_REG_BASE_BOOTM);
icache_disable (); - invalidate_l1_instruction_cache (); - flush_data_cache (); dcache_disable (); } diff --git a/board/Marvell/db64460/db64460.c b/board/Marvell/db64460/db64460.c index a4abf8d..1ae898d 100644 --- a/board/Marvell/db64460/db64460.c +++ b/board/Marvell/db64460/db64460.c @@ -51,9 +51,6 @@ #define DP(x) #endif
-extern void flush_data_cache (void); -extern void invalidate_l1_instruction_cache (void); - /* ------------------------------------------------------------------------- */
/* this is the current GT register space location */ @@ -930,7 +927,5 @@ void board_prebootm_init () my_remap_gt_regs_bootm (CFG_GT_REGS, BRIDGE_REG_BASE_BOOTM);
icache_disable (); - invalidate_l1_instruction_cache (); - flush_data_cache (); dcache_disable (); } diff --git a/board/esd/cpci750/cpci750.c b/board/esd/cpci750/cpci750.c index 298aa6a..5ab76c6 100644 --- a/board/esd/cpci750/cpci750.c +++ b/board/esd/cpci750/cpci750.c @@ -120,8 +120,6 @@ static char show_config_tab[][15] = {{"PCI0DLL_2 "}, /* 31 */ {"DRAMPLL_NDiv_1"}, /* 01 */ {"DRAMPLL_NDiv_0"}}; /* 00 */
-extern void flush_data_cache (void); -extern void invalidate_l1_instruction_cache (void); extern flash_info_t flash_info[];
/* ------------------------------------------------------------------------- */ @@ -961,8 +959,6 @@ void board_prebootm_init () my_remap_gt_regs_bootm (CFG_GT_REGS, CFG_DFL_GT_REGS);
icache_disable (); - invalidate_l1_instruction_cache (); - flush_data_cache (); dcache_disable (); }
diff --git a/board/freescale/mpc7448hpc2/mpc7448hpc2.c b/board/freescale/mpc7448hpc2/mpc7448hpc2.c index b3d83cc..6f74c31 100644 --- a/board/freescale/mpc7448hpc2/mpc7448hpc2.c +++ b/board/freescale/mpc7448hpc2/mpc7448hpc2.c @@ -37,8 +37,6 @@
DECLARE_GLOBAL_DATA_PTR;
-extern void flush_data_cache (void); -extern void invalidate_l1_instruction_cache (void); extern void tsi108_init_f (void);
int display_mem_map (void); diff --git a/board/prodrive/p3mx/p3mx.c b/board/prodrive/p3mx/p3mx.c index d54ddaf..69d7c9b 100644 --- a/board/prodrive/p3mx/p3mx.c +++ b/board/prodrive/p3mx/p3mx.c @@ -62,8 +62,6 @@ DECLARE_GLOBAL_DATA_PTR; #define DP(x) #endif
-extern void flush_data_cache (void); -extern void invalidate_l1_instruction_cache (void); extern flash_info_t flash_info[];
/* ------------------------------------------------------------------------- */ diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 5295969..0b14b06 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -236,8 +236,6 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * bios emulation, so turn them off again */ icache_disable(); - invalidate_l1_instruction_cache(); - flush_data_cache(); dcache_disable(); #endif
diff --git a/cpu/74xx_7xx/cache.S b/cpu/74xx_7xx/cache.S index 3a745cb..eac4544 100644 --- a/cpu/74xx_7xx/cache.S +++ b/cpu/74xx_7xx/cache.S @@ -245,6 +245,10 @@ _GLOBAL(icache_enable) * Disable L1 Instruction cache */ _GLOBAL(icache_disable) + mflr r4 + bl invalidate_l1_instruction_cache /* uses r3 */ + sync + mtlr r4 mfspr r3, HID0 li r5, 0 ori r5, r5, HID0_ICE diff --git a/cpu/mpc86xx/cache.S b/cpu/mpc86xx/cache.S index 2e4ea02..80ff688 100644 --- a/cpu/mpc86xx/cache.S +++ b/cpu/mpc86xx/cache.S @@ -232,6 +232,10 @@ _GLOBAL(icache_enable) * Disable L1 Instruction cache */ _GLOBAL(icache_disable) + mflr r4 + bl invalidate_l1_instruction_cache /* uses r3 */ + sync + mtlr r4 mfspr r3, HID0 li r5, 0 ori r5, r5, HID0_ICE

Signed-off-by: Kumar Gala galak@kernel.crashing.org --- common/cmd_fdt.c | 21 +++++++++++++++++---- 1 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index d3b19dd..436fec9 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -417,9 +417,21 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) ft_board_setup(working_fdt, gd->bd); #endif /* Create a chosen node */ - else if (argv[1][0] == 'c') - fdt_chosen(working_fdt, 0, 0, 1); - else { + else if (argv[1][0] == 'c') { + unsigned long initrd_start = 0, initrd_end = 0; + + if ((argc != 2) && (argc != 4)) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + if (argc == 4) { + initrd_start = simple_strtoul(argv[2], NULL, 16); + initrd_end = simple_strtoul(argv[3], NULL, 16); + } + + fdt_chosen(working_fdt, initrd_start, initrd_end, 1); + } else { /* Unrecognized command */ printf ("Usage:\n%s\n", cmdtp->usage); return 1; @@ -798,7 +810,8 @@ U_BOOT_CMD( "fdt rsvmem print - Show current mem reserves\n" "fdt rsvmem add <addr> <size> - Add a mem reserve\n" "fdt rsvmem delete <index> - Delete a mem reserves\n" - "fdt chosen - Add/update the /chosen branch in the tree\n" + "fdt chosen [<start> <end>] - Add/update the /chosen branch in the tree\n" + " <start>/<end> - initrd start/end addr\n" "NOTE: If the path or property you are setting/printing has a '#' character\n" " or spaces, you MUST escape it with a \ character or quote it with ".\n" );

Signed-off-by: Kumar Gala galak@kernel.crashing.org --- common/cmd_fdt.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index 436fec9..c129993 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -67,6 +67,14 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) /* * Set the address [and length] of the fdt. */ + if (argc == 2) { + if (!fdt_valid()) { + return 1; + } + printf("The address of the fdt is %p\n", working_fdt); + return 0; + } + working_fdt = (struct fdt_header *)simple_strtoul(argv[2], NULL, 16);
if (!fdt_valid()) {

Move entry point code out of each arch and into common code. Keep the entry point in the bootm_headers_t images struct.
Signed-off-by: Kumar Gala galak@kernel.crashing.org --- common/cmd_bootm.c | 31 ++++++++++++++++++++++--------- include/image.h | 2 ++ lib_arm/bootm.c | 19 +------------------ lib_avr32/bootm.c | 19 +------------------ lib_blackfin/bootm.c | 19 +------------------ lib_m68k/bootm.c | 19 +------------------ lib_microblaze/bootm.c | 19 +------------------ lib_mips/bootm.c | 18 +----------------- lib_nios2/bootm.c | 20 +------------------- lib_ppc/bootm.c | 22 +++------------------- lib_sh/bootm.c | 19 +------------------ lib_sparc/bootm.c | 12 ++---------- 12 files changed, 37 insertions(+), 182 deletions(-)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 0b14b06..3f63b84 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -205,6 +205,23 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; }
+ /* find kernel entry point */ + if (images.legacy_hdr_valid) { + images.ep = image_get_ep (&images.legacy_hdr_os_copy); +#if defined(CONFIG_FIT) + } else if (images.fit_uname_os) { + ret = fit_image_get_entry (images.fit_hdr_os, + images.fit_noffset_os, &images.ep); + if (ret) { + puts ("Can't get entry point property!\n"); + return 1; + } +#endif + } else { + puts ("Could not find kernel entry point!\n"); + return 1; + } + image_start = (ulong)os_hdr; load_end = 0; type_name = genimg_get_type_name (type); @@ -942,7 +959,7 @@ static void do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, cmdline = ""; }
- loader = (void (*)(bd_t *, image_header_t *, char *, char *))image_get_ep (hdr); + loader = (void (*)(bd_t *, image_header_t *, char *, char *))images->ep;
printf ("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n", (ulong)loader); @@ -981,7 +998,6 @@ static void do_bootm_rtems (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images) { - image_header_t *hdr = &images->legacy_hdr_os_copy; void (*entry_point)(bd_t *);
#if defined(CONFIG_FIT) @@ -991,7 +1007,7 @@ static void do_bootm_rtems (cmd_tbl_t *cmdtp, int flag, } #endif
- entry_point = (void (*)(bd_t *))image_get_ep (hdr); + entry_point = (void (*)(bd_t *))images->ep;
printf ("## Transferring control to RTEMS (at address %08lx) ...\n", (ulong)entry_point); @@ -1011,7 +1027,6 @@ static void do_bootm_vxworks (cmd_tbl_t *cmdtp, int flag, bootm_headers_t *images) { char str[80]; - image_header_t *hdr = &images->legacy_hdr_os_copy;
#if defined(CONFIG_FIT) if (!images->legacy_hdr_valid) { @@ -1020,7 +1035,7 @@ static void do_bootm_vxworks (cmd_tbl_t *cmdtp, int flag, } #endif
- sprintf(str, "%x", image_get_ep (hdr)); /* write entry-point into string */ + sprintf(str, "%lx", images->ep); /* write entry-point into string */ setenv("loadaddr", str); do_bootvx(cmdtp, 0, 0, NULL); } @@ -1031,7 +1046,6 @@ static void do_bootm_qnxelf(cmd_tbl_t *cmdtp, int flag, { char *local_args[2]; char str[16]; - image_header_t *hdr = &images->legacy_hdr_os_copy;
#if defined(CONFIG_FIT) if (!images->legacy_hdr_valid) { @@ -1040,7 +1054,7 @@ static void do_bootm_qnxelf(cmd_tbl_t *cmdtp, int flag, } #endif
- sprintf(str, "%x", image_get_ep (hdr)); /* write entry-point into string */ + sprintf(str, "%lx", images->ep); /* write entry-point into string */ local_args[0] = argv[0]; local_args[1] = str; /* and provide it via the arguments */ do_bootelf(cmdtp, 0, 2, local_args); @@ -1058,7 +1072,6 @@ static void do_bootm_artos (cmd_tbl_t *cmdtp, int flag, int i, j, nxt, len, envno, envsz; bd_t *kbd; void (*entry)(bd_t *bd, char *cmdline, char **fwenv, ulong top); - image_header_t *hdr = &images->legacy_hdr_os_copy;
#if defined(CONFIG_FIT) if (!images->legacy_hdr_valid) { @@ -1133,7 +1146,7 @@ static void do_bootm_artos (cmd_tbl_t *cmdtp, int flag, } *ss++ = NULL; /* terminate */
- entry = (void (*)(bd_t *, char *, char **, ulong))image_get_ep (hdr); + entry = (void (*)(bd_t *, char *, char **, ulong))images->ep; (*entry) (kbd, cmdline, fwenv, top); } #endif diff --git a/include/image.h b/include/image.h index 4b9c582..e16c253 100644 --- a/include/image.h +++ b/include/image.h @@ -219,6 +219,8 @@ typedef struct bootm_headers { #endif #endif
+ ulong ep; /* entry point of OS */ + int verify; /* getenv("verify")[0] != 'n' */ struct lmb *lmb; /* for memory mgmt */ } bootm_headers_t; diff --git a/lib_arm/bootm.c b/lib_arm/bootm.c index 955a1ae..5660a50 100644 --- a/lib_arm/bootm.c +++ b/lib_arm/bootm.c @@ -62,7 +62,6 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images) { ulong initrd_start, initrd_end; - ulong ep = 0; bd_t *bd = gd->bd; char *s; int machid = bd->bi_arch_number; @@ -73,23 +72,7 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], char *commandline = getenv ("bootargs"); #endif
- /* find kernel entry point */ - if (images->legacy_hdr_valid) { - ep = image_get_ep (&images->legacy_hdr_os_copy); -#if defined(CONFIG_FIT) - } else if (images->fit_uname_os) { - ret = fit_image_get_entry (images->fit_hdr_os, - images->fit_noffset_os, &ep); - if (ret) { - puts ("Can't get entry point property!\n"); - goto error; - } -#endif - } else { - puts ("Could not find kernel entry point!\n"); - goto error; - } - theKernel = (void (*)(int, int, uint))ep; + theKernel = (void (*)(int, int, uint))images->ep;
s = getenv ("machid"); if (s) { diff --git a/lib_avr32/bootm.c b/lib_avr32/bootm.c index 60e6b36..7beab99 100644 --- a/lib_avr32/bootm.c +++ b/lib_avr32/bootm.c @@ -177,29 +177,12 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images) { ulong initrd_start, initrd_end; - ulong ep = 0; void (*theKernel)(int magic, void *tagtable); struct tag *params, *params_start; char *commandline = getenv("bootargs"); int ret;
- /* find kernel entry point */ - if (images->legacy_hdr_valid) { - ep = image_get_ep (&images->legacy_hdr_os_copy); -#if defined(CONFIG_FIT) - } else if (images->fit_uname_os) { - ret = fit_image_get_entry (images->fit_hdr_os, - images->fit_noffset_os, &ep); - if (ret) { - puts ("Can't get entry point property!\n"); - goto error; - } -#endif - } else { - puts ("Could not find kernel entry point!\n"); - goto error; - } - theKernel = (void *)ep; + theKernel = (void *)images->ep;
ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_AVR32, &initrd_start, &initrd_end); diff --git a/lib_blackfin/bootm.c b/lib_blackfin/bootm.c index 54f69a9..f789e24 100644 --- a/lib_blackfin/bootm.c +++ b/lib_blackfin/bootm.c @@ -38,29 +38,12 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], { int (*appl) (char *cmdline); char *cmdline; - ulong ep = 0;
#ifdef SHARED_RESOURCES swap_to(FLASH); #endif
- /* find kernel entry point */ - if (images->legacy_hdr_valid) { - ep = image_get_ep (&images->legacy_hdr_os_copy); -#if defined(CONFIG_FIT) - } else if (images->fit_uname_os) { - int ret = fit_image_get_entry (images->fit_hdr_os, - images->fit_noffset_os, &ep); - if (ret) { - puts ("Can't get entry point property!\n"); - goto error; - } -#endif - } else { - puts ("Could not find kernel entry point!\n"); - goto error; - } - appl = (int (*)(char *))ep; + appl = (int (*)(char *))images->ep;
printf("Starting Kernel at = %x\n", appl); cmdline = make_command_line(); diff --git a/lib_m68k/bootm.c b/lib_m68k/bootm.c index b45203d..fe658fe 100644 --- a/lib_m68k/bootm.c +++ b/lib_m68k/bootm.c @@ -57,7 +57,6 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, ulong cmd_start, cmd_end; ulong bootmap_base; bd_t *kbd; - ulong ep = 0; void (*kernel) (bd_t *, ulong, ulong, ulong, ulong); struct lmb *lmb = images->lmb;
@@ -94,23 +93,7 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, } set_clocks_in_mhz(kbd);
- /* find kernel entry point */ - if (images->legacy_hdr_valid) { - ep = image_get_ep (&images->legacy_hdr_os_copy); -#if defined(CONFIG_FIT) - } else if (images->fit_uname_os) { - ret = fit_image_get_entry (images->fit_hdr_os, - images->fit_noffset_os, &ep); - if (ret) { - puts ("Can't get entry point property!\n"); - goto error; - } -#endif - } else { - puts ("Could not find kernel entry point!\n"); - goto error; - } - kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; + kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))images->ep;
/* find ramdisk */ ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_M68K, diff --git a/lib_microblaze/bootm.c b/lib_microblaze/bootm.c index 68edcdb..baf6d77 100644 --- a/lib_microblaze/bootm.c +++ b/lib_microblaze/bootm.c @@ -40,25 +40,8 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], /* First parameter is mapped to $r5 for kernel boot args */ void (*theKernel) (char *); char *commandline = getenv ("bootargs"); - ulong ep = 0;
- /* find kernel entry point */ - if (images->legacy_hdr_valid) { - ep = image_get_ep (&images->legacy_hdr_os_copy); -#if defined(CONFIG_FIT) - } else if (images->fit_uname_os) { - int ret = fit_image_get_entry (images->fit_hdr_os, - images->fit_noffset_os, &ep); - if (ret) { - puts ("Can't get entry point property!\n"); - goto error; - } -#endif - } else { - puts ("Could not find kernel entry point!\n"); - goto error; - } - theKernel = (void (*)(char *))ep; + theKernel = (void (*)(char *))images->ep;
show_boot_progress (15);
diff --git a/lib_mips/bootm.c b/lib_mips/bootm.c index 53e8e19..7df6ce6 100644 --- a/lib_mips/bootm.c +++ b/lib_mips/bootm.c @@ -49,7 +49,6 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images) { ulong initrd_start, initrd_end; - ulong ep = 0; void (*theKernel) (int, char **, char **, int *); char *commandline = getenv ("bootargs"); char env_buf[12]; @@ -57,22 +56,7 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], char *cp;
/* find kernel entry point */ - if (images->legacy_hdr_valid) { - ep = image_get_ep (&images->legacy_hdr_os_copy); -#if defined(CONFIG_FIT) - } else if (images->fit_uname_os) { - ret = fit_image_get_entry (images->fit_hdr_os, - images->fit_noffset_os, &ep); - if (ret) { - puts ("Can't get entry point property!\n"); - goto error; - } -#endif - } else { - puts ("Could not find kernel entry point!\n"); - goto error; - } - theKernel = (void (*)(int, char **, char **, int *))ep; + theKernel = (void (*)(int, char **, char **, int *))images->ep;
ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_MIPS, &initrd_start, &initrd_end); diff --git a/lib_nios2/bootm.c b/lib_nios2/bootm.c index 18cf773..c74b5d6 100644 --- a/lib_nios2/bootm.c +++ b/lib_nios2/bootm.c @@ -30,25 +30,7 @@ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images) { - ulong ep = 0; - - /* find kernel entry point */ - if (images->legacy_hdr_valid) { - ep = image_get_ep (&images->legacy_hdr_os_copy); -#if defined(CONFIG_FIT) - } else if (images->fit_uname_os) { - int ret = fit_image_get_entry (images->fit_hdr_os, - images->fit_noffset_os, &ep); - if (ret) { - puts ("Can't get entry point property!\n"); - goto error; - } -#endif - } else { - puts ("Could not find kernel entry point!\n"); - goto error; - } - void (*kernel)(void) = (void (*)(void))ep; + void (*kernel)(void) = (void (*)(void))images->ep;
/* For now we assume the Microtronix linux ... which only * needs to be called ;-) diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 3cb17bf..b481c2a 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -79,7 +79,6 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
ulong cmd_start, cmd_end, bootmap_base; bd_t *kbd; - ulong ep = 0; void (*kernel)(bd_t *, ulong r4, ulong r5, ulong r6, ulong r7, ulong r8, ulong r9); int ret; @@ -90,6 +89,9 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], char *of_flat_tree = NULL; #endif
+ kernel = (void (*)(bd_t *, ulong, ulong, ulong, + ulong, ulong, ulong))images->ep; + bootmap_base = getenv_bootm_low(); bootm_size = getenv_bootm_size();
@@ -151,24 +153,6 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], set_clocks_in_mhz(kbd); }
- /* find kernel entry point */ - if (images->legacy_hdr_valid) { - ep = image_get_ep (&images->legacy_hdr_os_copy); -#if defined(CONFIG_FIT) - } else if (images->fit_uname_os) { - ret = fit_image_get_entry (images->fit_hdr_os, - images->fit_noffset_os, &ep); - if (ret) { - puts ("Can't get entry point property!\n"); - goto error; - } -#endif - } else { - puts ("Could not find kernel entry point!\n"); - goto error; - } - kernel = (void (*)(bd_t *, ulong, ulong, ulong, - ulong, ulong, ulong))ep; /* find ramdisk */ ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_PPC, &rd_data_start, &rd_data_end); diff --git a/lib_sh/bootm.c b/lib_sh/bootm.c index 4ee7ff3..9d2c908 100644 --- a/lib_sh/bootm.c +++ b/lib_sh/bootm.c @@ -62,26 +62,9 @@ static void hexdump (unsigned char *buf, int len) void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images) { - ulong ep = 0; char *bootargs = getenv("bootargs");
- /* find kernel entry point */ - if (images->legacy_hdr_valid) { - ep = image_get_ep (&images->legacy_hdr_os_copy); -#if defined(CONFIG_FIT) - } else if (images->fit_uname_os) { - int ret = fit_image_get_entry (images->fit_hdr_os, - images->fit_noffset_os, &ep); - if (ret) { - puts ("Can't get entry point property!\n"); - goto error; - } -#endif - } else { - puts ("Could not find kernel entry point!\n"); - goto error; - } - void (*kernel) (void) = (void (*)(void))ep; + void (*kernel) (void) = (void (*)(void))images->ep;
/* Setup parameters */ memset(PARAM, 0, 0x1000); /* Clear zero page */ diff --git a/lib_sparc/bootm.c b/lib_sparc/bootm.c index b1a3d98..ac15396 100644 --- a/lib_sparc/bootm.c +++ b/lib_sparc/bootm.c @@ -87,7 +87,7 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], bootm_headers_t * images) { char *bootargs; - ulong ep, load; + ulong load; ulong initrd_start, initrd_end; ulong rd_data_start, rd_data_end, rd_len; unsigned int data, len, checksum; @@ -97,17 +97,9 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], int ret;
if (images->legacy_hdr_valid) { - ep = image_get_ep(images->legacy_hdr_os); load = image_get_load(images->legacy_hdr_os); #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { - int ret = fit_image_get_entry(images->fit_hdr_os, - images->fit_noffset_os, &ep); - if (ret) { - puts("Can't get entry point property!\n"); - goto error; - } - ret = fit_image_get_load(images->fit_hdr_os, images->fit_noffset_os, &load); if (ret) { @@ -124,7 +116,7 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], linux_hdr = (void *)load;
/* */ - kernel = (void (*)(struct linux_romvec *, void *))ep; + kernel = (void (*)(struct linux_romvec *, void *))images->ep;
/* check for a SPARC kernel */ if ((linux_hdr->hdr[0] != 'H') ||

Move determing if we have a ramdisk and where its located into the common code. Keep track of the ramdisk start and end in the bootm_headers_t image struct.
Signed-off-by: Kumar Gala galak@kernel.crashing.org --- common/cmd_bootm.c | 38 ++++++++++++++++++++++++++++++++++++++ include/image.h | 2 ++ lib_arm/bootm.c | 10 ++-------- lib_avr32/bootm.c | 12 +++--------- lib_i386/bootm.c | 8 +------- lib_m68k/bootm.c | 12 +++--------- lib_mips/bootm.c | 12 +++--------- lib_ppc/bootm.c | 16 +++++----------- lib_sparc/bootm.c | 17 +++-------------- 9 files changed, 60 insertions(+), 67 deletions(-)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 3f63b84..56236b9 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -116,6 +116,33 @@ void __board_lmb_reserve(struct lmb *lmb) } void board_lmb_reserve(struct lmb *lmb) __attribute__((weak, alias("__board_lmb_reserve")));
+#if defined(__ARM__) + #define IH_INITRD_ARCH IH_ARCH_ARM +#elif defined(__avr32__) + #define IH_INITRD_ARCH IH_ARCH_AVR32 +#elif defined(__bfin__) + #define IH_INITRD_ARCH IH_ARCH_BLACKFIN +#elif defined(__I386__) + #define IH_INITRD_ARCH IH_ARCH_I386 +#elif defined(__M68K__) + #define IH_INITRD_ARCH IH_ARCH_M68K +#elif defined(__microblaze__) + #define IH_INITRD_ARCH IH_ARCH_MICROBLAZE +#elif defined(__mips__) + #define IH_INITRD_ARCH IH_ARCH_MIPS +#elif defined(__nios__) + #define IH_INITRD_ARCH IH_ARCH_NIOS +#elif defined(__nios2__) + #define IH_INITRD_ARCH IH_ARCH_NIOS2 +#elif defined(__PPC__) + #define IH_INITRD_ARCH IH_ARCH_PPC +#elif defined(__sh__) + #define IH_INITRD_ARCH IH_ARCH_SH +#elif defined(__sparc__) + #define IH_INITRD_ARCH IH_ARCH_SPARC +#else +# error Unknown CPU type +#endif
/*******************************************************************/ /* bootm - boot application image from image in memory */ @@ -133,6 +160,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) ulong load_start, load_end; ulong mem_start; phys_size_t mem_size; + int ret;
struct lmb lmb;
@@ -222,6 +250,16 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; }
+ if (os == IH_OS_LINUX) { + /* find ramdisk */ + ret = boot_get_ramdisk (argc, argv, &images, IH_INITRD_ARCH, + &images.rd_start, &images.rd_end); + if (ret) { + puts ("Ramdisk image is corrupt\n"); + return 1; + } + } + image_start = (ulong)os_hdr; load_end = 0; type_name = genimg_get_type_name (type); diff --git a/include/image.h b/include/image.h index e16c253..b8577a0 100644 --- a/include/image.h +++ b/include/image.h @@ -221,6 +221,8 @@ typedef struct bootm_headers {
ulong ep; /* entry point of OS */
+ ulong rd_start, rd_end;/* ramdisk start/end */ + int verify; /* getenv("verify")[0] != 'n' */ struct lmb *lmb; /* for memory mgmt */ } bootm_headers_t; diff --git a/lib_arm/bootm.c b/lib_arm/bootm.c index 5660a50..f9f702f 100644 --- a/lib_arm/bootm.c +++ b/lib_arm/bootm.c @@ -61,7 +61,6 @@ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images) { - ulong initrd_start, initrd_end; bd_t *bd = gd->bd; char *s; int machid = bd->bi_arch_number; @@ -80,11 +79,6 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], printf ("Using machid 0x%x from environment\n", machid); }
- ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_ARM, - &initrd_start, &initrd_end); - if (ret) - goto error; - show_boot_progress (15);
debug ("## Transferring control to Linux (at address %08lx) ...\n", @@ -111,8 +105,8 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], setup_commandline_tag (bd, commandline); #endif #ifdef CONFIG_INITRD_TAG - if (initrd_start && initrd_end) - setup_initrd_tag (bd, initrd_start, initrd_end); + if (images->rd_start && images->rd_end) + setup_initrd_tag (bd, images->rd_start, images->rd_end); #endif #if defined (CONFIG_VFD) || defined (CONFIG_LCD) setup_videolfb_tag ((gd_t *) gd); diff --git a/lib_avr32/bootm.c b/lib_avr32/bootm.c index 7beab99..762701f 100644 --- a/lib_avr32/bootm.c +++ b/lib_avr32/bootm.c @@ -176,7 +176,6 @@ static void setup_end_tag(struct tag *params) void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images) { - ulong initrd_start, initrd_end; void (*theKernel)(int magic, void *tagtable); struct tag *params, *params_start; char *commandline = getenv("bootargs"); @@ -184,20 +183,15 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
theKernel = (void *)images->ep;
- ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_AVR32, - &initrd_start, &initrd_end); - if (ret) - goto error; - show_boot_progress (15);
params = params_start = (struct tag *)gd->bd->bi_boot_params; params = setup_start_tag(params); params = setup_memory_tags(params); - if (initrd_start) { + if (images->rd_start) { params = setup_ramdisk_tag(params, - PHYSADDR(initrd_start), - PHYSADDR(initrd_end)); + PHYSADDR(images->rd_start), + PHYSADDR(images->rd_end)); } params = setup_commandline_tag(params, commandline); params = setup_clock_tags(params); diff --git a/lib_i386/bootm.c b/lib_i386/bootm.c index 452eef7..8c0b225 100644 --- a/lib_i386/bootm.c +++ b/lib_i386/bootm.c @@ -36,7 +36,6 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], { void *base_ptr; ulong os_data, os_len; - ulong initrd_start, initrd_end; image_header_t *hdr; int ret; #if defined(CONFIG_FIT) @@ -44,11 +43,6 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], size_t len; #endif
- ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_I386, - &initrd_start, &initrd_end); - if (ret) - goto error; - if (images->legacy_hdr_valid) { hdr = images->legacy_hdr_os; if (image_check_type (hdr, IH_TYPE_MULTI)) { @@ -76,7 +70,7 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], }
base_ptr = load_zimage ((void*)os_data, os_len, - initrd_start, initrd_end - initrd_start, 0); + images->rd_start, images->rd_end - images->rd_start, 0);
if (NULL == base_ptr) { printf ("## Kernel loading failed ...\n"); diff --git a/lib_m68k/bootm.c b/lib_m68k/bootm.c index fe658fe..241721d 100644 --- a/lib_m68k/bootm.c +++ b/lib_m68k/bootm.c @@ -50,7 +50,7 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, { ulong sp;
- ulong rd_data_start, rd_data_end, rd_len; + ulong rd_len; ulong initrd_start, initrd_end; int ret;
@@ -95,14 +95,8 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag,
kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))images->ep;
- /* find ramdisk */ - ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_M68K, - &rd_data_start, &rd_data_end); - if (ret) - goto error; - - rd_len = rd_data_end - rd_data_start; - ret = boot_ramdisk_high (lmb, rd_data_start, rd_len, + rd_len = images->rd_end - images->rd_start; + ret = boot_ramdisk_high (lmb, images->rd_start, rd_len, &initrd_start, &initrd_end); if (ret) goto error; diff --git a/lib_mips/bootm.c b/lib_mips/bootm.c index 7df6ce6..9869c33 100644 --- a/lib_mips/bootm.c +++ b/lib_mips/bootm.c @@ -48,7 +48,6 @@ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images) { - ulong initrd_start, initrd_end; void (*theKernel) (int, char **, char **, int *); char *commandline = getenv ("bootargs"); char env_buf[12]; @@ -58,11 +57,6 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], /* find kernel entry point */ theKernel = (void (*)(int, char **, char **, int *))images->ep;
- ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_MIPS, - &initrd_start, &initrd_end); - if (ret) - goto error; - show_boot_progress (15);
#ifdef DEBUG @@ -82,10 +76,10 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],
linux_env_set ("memsize", env_buf);
- sprintf (env_buf, "0x%08X", (uint) UNCACHED_SDRAM (initrd_start)); - linux_env_set ("initrd_start", env_buf); + sprintf (env_buf, "0x%08X", (uint) UNCACHED_SDRAM (images->rd_start)); + linux_env_set ("images->rd_start", env_buf);
- sprintf (env_buf, "0x%X", (uint) (initrd_end - initrd_start)); + sprintf (env_buf, "0x%X", (uint) (images->rd_end - images->rd_start)); linux_env_set ("initrd_size", env_buf);
sprintf (env_buf, "0x%08X", (uint) (gd->bd->bi_flashstart)); diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index b481c2a..942b891 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -73,7 +73,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ulong sp;
ulong initrd_start, initrd_end; - ulong rd_data_start, rd_data_end, rd_len; + ulong rd_len; ulong size; phys_size_t bootm_size;
@@ -153,13 +153,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], set_clocks_in_mhz(kbd); }
- /* find ramdisk */ - ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_PPC, - &rd_data_start, &rd_data_end); - if (ret) - goto error; - - rd_len = rd_data_end - rd_data_start; + rd_len = images->rd_end - images->rd_start;
#if defined(CONFIG_OF_LIBFDT) ret = boot_relocate_fdt (lmb, bootmap_base, @@ -171,7 +165,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], */ if (of_size) { /* pass in dummy initrd info, we'll fix up later */ - if (fdt_chosen(of_flat_tree, rd_data_start, rd_data_end, 0) < 0) { + if (fdt_chosen(of_flat_tree, images->rd_start, images->rd_end, 0) < 0) { fdt_error ("/chosen node create failed"); goto error; } @@ -222,7 +216,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], } #endif /* CONFIG_OF_LIBFDT */
- ret = boot_ramdisk_high (lmb, rd_data_start, rd_len, &initrd_start, &initrd_end); + ret = boot_ramdisk_high (lmb, images->rd_start, rd_len, &initrd_start, &initrd_end); if (ret) goto error;
@@ -236,7 +230,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], /* Look for the dummy entry and delete it */ for (j = 0; j < total; j++) { fdt_get_mem_rsv(of_flat_tree, j, &addr, &size); - if (addr == rd_data_start) { + if (addr == images->rd_start) { fdt_del_mem_rsv(of_flat_tree, j); break; } diff --git a/lib_sparc/bootm.c b/lib_sparc/bootm.c index ac15396..71d34ba 100644 --- a/lib_sparc/bootm.c +++ b/lib_sparc/bootm.c @@ -89,7 +89,7 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], char *bootargs; ulong load; ulong initrd_start, initrd_end; - ulong rd_data_start, rd_data_end, rd_len; + ulong rd_len; unsigned int data, len, checksum; unsigned int initrd_addr, kernend; void (*kernel) (struct linux_romvec *, void *); @@ -139,19 +139,8 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], * extracted and is writeable. */
- /* - * Are we going to use an initrd image? - */ - ret = boot_get_ramdisk(argc, argv, images, IH_ARCH_SPARC, - &rd_data_start, &rd_data_end); - if (ret) { - /* RAM disk found but was corrupt */ - puts("RAM Disk corrupt\n"); - goto error; - } - /* Calc length of RAM disk, if zero no ramdisk available */ - rd_len = rd_data_end - rd_data_start; + rd_len = images->rd_end - images->rd_start;
if (rd_len) {
@@ -161,7 +150,7 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], */ lmb_reserve(lmb, CFG_RELOC_MONITOR_BASE, CFG_RAM_END);
- ret = boot_ramdisk_high(lmb, rd_data_start, rd_len, + ret = boot_ramdisk_high(lmb, images->rd_start, rd_len, &initrd_start, &initrd_end); if (ret) { puts("### Failed to relocate RAM disk\n");

Move the code that handles finding a device tree blob and relocating it (if needed) into common code so all arch's have access to it.
Signed-off-by: Kumar Gala galak@kernel.crashing.org --- common/cmd_bootm.c | 10 + common/image.c | 502 ++++++++++++++++++++++++++++++++++++++++++++++++++++ include/image.h | 13 ++ lib_ppc/bootm.c | 492 +-------------------------------------------------- 4 files changed, 533 insertions(+), 484 deletions(-)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 56236b9..918ea98 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -258,6 +258,16 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) puts ("Ramdisk image is corrupt\n"); return 1; } + +#if defined(CONFIG_OF_LIBFDT) + /* find flattened device tree */ + ret = boot_get_fdt (cmdtp, flag, argc, argv, + &images, &images.ft_addr, &images.ft_len); + if (ret) { + puts ("Could not find a valid device tree\n"); + return 1; + } +#endif }
image_start = (ulong)os_hdr; diff --git a/common/image.c b/common/image.c index 6d2ce32..e7cb57c 100644 --- a/common/image.c +++ b/common/image.c @@ -1070,6 +1070,508 @@ error: return -1; }
+#ifdef CONFIG_OF_LIBFDT +static void fdt_error (const char *msg) +{ + puts ("ERROR: "); + puts (msg); + puts (" - must RESET the board to recover.\n"); +} + +static image_header_t *image_get_fdt (ulong fdt_addr) +{ + image_header_t *fdt_hdr = (image_header_t *)fdt_addr; + + image_print_contents (fdt_hdr); + + puts (" Verifying Checksum ... "); + if (!image_check_hcrc (fdt_hdr)) { + fdt_error ("fdt header checksum invalid"); + return NULL; + } + + if (!image_check_dcrc (fdt_hdr)) { + fdt_error ("fdt checksum invalid"); + return NULL; + } + puts ("OK\n"); + + if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) { + fdt_error ("uImage is not a fdt"); + return NULL; + } + if (image_get_comp (fdt_hdr) != IH_COMP_NONE) { + fdt_error ("uImage is compressed"); + return NULL; + } + if (fdt_check_header ((char *)image_get_data (fdt_hdr)) != 0) { + fdt_error ("uImage data is not a fdt"); + return NULL; + } + return fdt_hdr; +} + +/** + * fit_check_fdt - verify FIT format FDT subimage + * @fit_hdr: pointer to the FIT header + * fdt_noffset: FDT subimage node offset within FIT image + * @verify: data CRC verification flag + * + * fit_check_fdt() verifies integrity of the FDT subimage and from + * specified FIT image. + * + * returns: + * 1, on success + * 0, on failure + */ +#if defined(CONFIG_FIT) +static int fit_check_fdt (const void *fit, int fdt_noffset, int verify) +{ + fit_image_print (fit, fdt_noffset, " "); + + if (verify) { + puts (" Verifying Hash Integrity ... "); + if (!fit_image_check_hashes (fit, fdt_noffset)) { + fdt_error ("Bad Data Hash"); + return 0; + } + puts ("OK\n"); + } + + if (!fit_image_check_type (fit, fdt_noffset, IH_TYPE_FLATDT)) { + fdt_error ("Not a FDT image"); + return 0; + } + + if (!fit_image_check_comp (fit, fdt_noffset, IH_COMP_NONE)) { + fdt_error ("FDT image is compressed"); + return 0; + } + + return 1; +} +#endif /* CONFIG_FIT */ + +#ifndef CFG_FDT_PAD +#define CFG_FDT_PAD 0x3000 +#endif + +/** + * boot_relocate_fdt - relocate flat device tree + * @lmb: pointer to lmb handle, will be used for memory mgmt + * @bootmap_base: base address of the bootmap region + * @of_flat_tree: pointer to a char* variable, will hold fdt start address + * @of_size: pointer to a ulong variable, will hold fdt length + * + * boot_relocate_fdt() determines if the of_flat_tree address is within + * the bootmap and if not relocates it into that region + * + * of_flat_tree and of_size are set to final (after relocation) values + * + * returns: + * 0 - success + * 1 - failure + */ +int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, + char **of_flat_tree, ulong *of_size) +{ + char *fdt_blob = *of_flat_tree; + ulong relocate = 0; + ulong of_len = 0; + + /* nothing to do */ + if (*of_size == 0) + return 0; + + if (fdt_check_header (fdt_blob) != 0) { + fdt_error ("image is not a fdt"); + goto error; + } + +#ifndef CFG_NO_FLASH + /* move the blob if it is in flash (set relocate) */ + if (addr2info ((ulong)fdt_blob) != NULL) + relocate = 1; +#endif + + /* + * The blob needs to be inside the boot mapping. + */ + if (fdt_blob < (char *)bootmap_base) + relocate = 1; + + if ((fdt_blob + *of_size + CFG_FDT_PAD) >= + ((char *)CFG_BOOTMAPSZ + bootmap_base)) + relocate = 1; + + /* move flattend device tree if needed */ + if (relocate) { + int err; + ulong of_start = 0; + + /* position on a 4K boundary before the alloc_current */ + /* Pad the FDT by a specified amount */ + of_len = *of_size + CFG_FDT_PAD; + of_start = (unsigned long)lmb_alloc_base(lmb, of_len, 0x1000, + (CFG_BOOTMAPSZ + bootmap_base)); + + if (of_start == 0) { + puts("device tree - allocation error\n"); + goto error; + } + + debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", + (ulong)fdt_blob, (ulong)fdt_blob + *of_size - 1, + of_len, of_len); + + printf (" Loading Device Tree to %08lx, end %08lx ... ", + of_start, of_start + of_len - 1); + + err = fdt_open_into (fdt_blob, (void *)of_start, of_len); + if (err != 0) { + fdt_error ("fdt move failed"); + goto error; + } + puts ("OK\n"); + + *of_flat_tree = (char *)of_start; + *of_size = of_len; + } else { + *of_flat_tree = fdt_blob; + of_len = (CFG_BOOTMAPSZ + bootmap_base) - (ulong)fdt_blob; + lmb_reserve(lmb, (ulong)fdt_blob, of_len); + fdt_set_totalsize(*of_flat_tree, of_len); + + *of_size = of_len; + } + + return 0; + +error: + return 1; +} + +/** + * boot_get_fdt - main fdt handling routine + * @argc: command argument count + * @argv: command argument list + * @images: pointer to the bootm images structure + * @of_flat_tree: pointer to a char* variable, will hold fdt start address + * @of_size: pointer to a ulong variable, will hold fdt length + * + * boot_get_fdt() is responsible for finding a valid flat device tree image. + * Curently supported are the following ramdisk sources: + * - multicomponent kernel/ramdisk image, + * - commandline provided address of decicated ramdisk image. + * + * returns: + * 0, if fdt image was found and valid, or skipped + * of_flat_tree and of_size are set to fdt start address and length if + * fdt image is found and valid + * + * 1, if fdt image is found but corrupted + * of_flat_tree and of_size are set to 0 if no fdt exists + */ +int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + bootm_headers_t *images, char **of_flat_tree, ulong *of_size) +{ + ulong fdt_addr; + image_header_t *fdt_hdr; + char *fdt_blob = NULL; + ulong image_start, image_end; + ulong load_start, load_end; +#if defined(CONFIG_FIT) + void *fit_hdr; + const char *fit_uname_config = NULL; + const char *fit_uname_fdt = NULL; + ulong default_addr; + int cfg_noffset; + int fdt_noffset; + const void *data; + size_t size; +#endif + + *of_flat_tree = NULL; + *of_size = 0; + + if (argc > 3 || genimg_has_config (images)) { +#if defined(CONFIG_FIT) + if (argc > 3) { + /* + * If the FDT blob comes from the FIT image and the + * FIT image address is omitted in the command line + * argument, try to use ramdisk or os FIT image + * address or default load address. + */ + if (images->fit_uname_rd) + default_addr = (ulong)images->fit_hdr_rd; + else if (images->fit_uname_os) + default_addr = (ulong)images->fit_hdr_os; + else + default_addr = load_addr; + + if (fit_parse_conf (argv[3], default_addr, + &fdt_addr, &fit_uname_config)) { + debug ("* fdt: config '%s' from image at 0x%08lx\n", + fit_uname_config, fdt_addr); + } else if (fit_parse_subimage (argv[3], default_addr, + &fdt_addr, &fit_uname_fdt)) { + debug ("* fdt: subimage '%s' from image at 0x%08lx\n", + fit_uname_fdt, fdt_addr); + } else +#endif + { + fdt_addr = simple_strtoul(argv[3], NULL, 16); + debug ("* fdt: cmdline image address = 0x%08lx\n", + fdt_addr); + } +#if defined(CONFIG_FIT) + } else { + /* use FIT configuration provided in first bootm + * command argument + */ + fdt_addr = (ulong)images->fit_hdr_os; + fit_uname_config = images->fit_uname_cfg; + debug ("* fdt: using config '%s' from image at 0x%08lx\n", + fit_uname_config, fdt_addr); + + /* + * Check whether configuration has FDT blob defined, + * if not quit silently. + */ + fit_hdr = (void *)fdt_addr; + cfg_noffset = fit_conf_get_node (fit_hdr, + fit_uname_config); + if (cfg_noffset < 0) { + debug ("* fdt: no such config\n"); + return 0; + } + + fdt_noffset = fit_conf_get_fdt_node (fit_hdr, + cfg_noffset); + if (fdt_noffset < 0) { + debug ("* fdt: no fdt in config\n"); + return 0; + } + } +#endif + + debug ("## Checking for 'FDT'/'FDT Image' at %08lx\n", + fdt_addr); + + /* copy from dataflash if needed */ + fdt_addr = genimg_get_image (fdt_addr); + + /* + * Check if there is an FDT image at the + * address provided in the second bootm argument + * check image type, for FIT images get a FIT node. + */ + switch (genimg_get_format ((void *)fdt_addr)) { + case IMAGE_FORMAT_LEGACY: + /* verify fdt_addr points to a valid image header */ + printf ("## Flattened Device Tree from Legacy Image at %08lx\n", + fdt_addr); + fdt_hdr = image_get_fdt (fdt_addr); + if (!fdt_hdr) + goto error; + + /* + * move image data to the load address, + * make sure we don't overwrite initial image + */ + image_start = (ulong)fdt_hdr; + image_end = image_get_image_end (fdt_hdr); + + load_start = image_get_load (fdt_hdr); + load_end = load_start + image_get_data_size (fdt_hdr); + + if ((load_start < image_end) && (load_end > image_start)) { + fdt_error ("fdt overwritten"); + goto error; + } + + debug (" Loading FDT from 0x%08lx to 0x%08lx\n", + image_get_data (fdt_hdr), load_start); + + memmove ((void *)load_start, + (void *)image_get_data (fdt_hdr), + image_get_data_size (fdt_hdr)); + + fdt_blob = (char *)load_start; + break; + case IMAGE_FORMAT_FIT: + /* + * This case will catch both: new uImage format + * (libfdt based) and raw FDT blob (also libfdt + * based). + */ +#if defined(CONFIG_FIT) + /* check FDT blob vs FIT blob */ + if (fit_check_format ((const void *)fdt_addr)) { + /* + * FIT image + */ + fit_hdr = (void *)fdt_addr; + printf ("## Flattened Device Tree from FIT Image at %08lx\n", + fdt_addr); + + if (!fit_uname_fdt) { + /* + * no FDT blob image node unit name, + * try to get config node first. If + * config unit node name is NULL + * fit_conf_get_node() will try to + * find default config node + */ + cfg_noffset = fit_conf_get_node (fit_hdr, + fit_uname_config); + + if (cfg_noffset < 0) { + fdt_error ("Could not find configuration node\n"); + goto error; + } + + fit_uname_config = fdt_get_name (fit_hdr, + cfg_noffset, NULL); + printf (" Using '%s' configuration\n", + fit_uname_config); + + fdt_noffset = fit_conf_get_fdt_node (fit_hdr, + cfg_noffset); + fit_uname_fdt = fit_get_name (fit_hdr, + fdt_noffset, NULL); + } else { + /* get FDT component image node offset */ + fdt_noffset = fit_image_get_node (fit_hdr, + fit_uname_fdt); + } + if (fdt_noffset < 0) { + fdt_error ("Could not find subimage node\n"); + goto error; + } + + printf (" Trying '%s' FDT blob subimage\n", + fit_uname_fdt); + + if (!fit_check_fdt (fit_hdr, fdt_noffset, + images->verify)) + goto error; + + /* get ramdisk image data address and length */ + if (fit_image_get_data (fit_hdr, fdt_noffset, + &data, &size)) { + fdt_error ("Could not find FDT subimage data"); + goto error; + } + + /* verift that image data is a proper FDT blob */ + if (fdt_check_header ((char *)data) != 0) { + fdt_error ("Subimage data is not a FTD"); + goto error; + } + + /* + * move image data to the load address, + * make sure we don't overwrite initial image + */ + image_start = (ulong)fit_hdr; + image_end = fit_get_end (fit_hdr); + + if (fit_image_get_load (fit_hdr, fdt_noffset, + &load_start) == 0) { + load_end = load_start + size; + + if ((load_start < image_end) && + (load_end > image_start)) { + fdt_error ("FDT overwritten"); + goto error; + } + + printf (" Loading FDT from 0x%08lx to 0x%08lx\n", + (ulong)data, load_start); + + memmove ((void *)load_start, + (void *)data, size); + + fdt_blob = (char *)load_start; + } else { + fdt_blob = (char *)data; + } + + images->fit_hdr_fdt = fit_hdr; + images->fit_uname_fdt = fit_uname_fdt; + images->fit_noffset_fdt = fdt_noffset; + break; + } else +#endif + { + /* + * FDT blob + */ + fdt_blob = (char *)fdt_addr; + debug ("* fdt: raw FDT blob\n"); + printf ("## Flattened Device Tree blob at %08lx\n", (long)fdt_blob); + } + break; + default: + fdt_error ("Did not find a cmdline Flattened Device Tree"); + goto error; + } + + printf (" Booting using the fdt blob at 0x%x\n", (int)fdt_blob); + + } else if (images->legacy_hdr_valid && + image_check_type (&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) { + + ulong fdt_data, fdt_len; + + /* + * Now check if we have a legacy multi-component image, + * get second entry data start address and len. + */ + printf ("## Flattened Device Tree from multi " + "component Image at %08lX\n", + (ulong)images->legacy_hdr_os); + + image_multi_getimg (images->legacy_hdr_os, 2, &fdt_data, &fdt_len); + if (fdt_len) { + + fdt_blob = (char *)fdt_data; + printf (" Booting using the fdt at 0x%x\n", (int)fdt_blob); + + if (fdt_check_header (fdt_blob) != 0) { + fdt_error ("image is not a fdt"); + goto error; + } + + if (be32_to_cpu (fdt_totalsize (fdt_blob)) != fdt_len) { + fdt_error ("fdt size != image size"); + goto error; + } + } else { + debug ("## No Flattened Device Tree\n"); + return 0; + } + } else { + debug ("## No Flattened Device Tree\n"); + return 0; + } + + *of_flat_tree = fdt_blob; + *of_size = be32_to_cpu (fdt_totalsize (fdt_blob)); + debug (" of_flat_tree at 0x%08lx size 0x%08lx\n", + *of_flat_tree, *of_size); + + return 0; + +error: + *of_flat_tree = 0; + *of_size = 0; + return 1; +} +#endif /* CONFIG_OF_LIBFDT */ + /** * boot_get_cmdline - allocate and initialize kernel cmdline * @lmb: pointer to lmb handle, will be used for memory mgmt diff --git a/include/image.h b/include/image.h index b8577a0..20700eb 100644 --- a/include/image.h +++ b/include/image.h @@ -223,6 +223,11 @@ typedef struct bootm_headers {
ulong rd_start, rd_end;/* ramdisk start/end */
+#ifdef CONFIG_OF_LIBFDT + char *ft_addr; /* flat dev tree address */ +#endif + ulong ft_len; /* length of flat device tree */ + int verify; /* getenv("verify")[0] != 'n' */ struct lmb *lmb; /* for memory mgmt */ } bootm_headers_t; @@ -273,6 +278,14 @@ ulong genimg_get_image (ulong img_addr); int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, uint8_t arch, ulong *rd_start, ulong *rd_end);
+ +#ifdef CONFIG_OF_LIBFDT +int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + bootm_headers_t *images, char **of_flat_tree, ulong *of_size); +int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, + char **of_flat_tree, ulong *of_size); +#endif + #if defined(CONFIG_PPC) || defined(CONFIG_M68K) int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, ulong *initrd_start, ulong *initrd_end); diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 942b891..45f6a47 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -39,22 +39,12 @@ #include <libfdt.h> #include <fdt_support.h>
-static void fdt_error (const char *msg); -static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, char **of_flat_tree, ulong *of_size); -static int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, - cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - char **of_flat_tree, ulong *of_size); #endif
#ifdef CFG_INIT_RAM_LOCK #include <asm/cache.h> #endif
-#ifndef CFG_FDT_PAD -#define CFG_FDT_PAD 0x3000 -#endif - DECLARE_GLOBAL_DATA_PTR;
extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); @@ -82,11 +72,11 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], void (*kernel)(bd_t *, ulong r4, ulong r5, ulong r6, ulong r7, ulong r8, ulong r9); int ret; - ulong of_size = 0; + ulong of_size = images->ft_len; struct lmb *lmb = images->lmb;
#if defined(CONFIG_OF_LIBFDT) - char *of_flat_tree = NULL; + char *of_flat_tree = images->ft_addr; #endif
kernel = (void (*)(bd_t *, ulong, ulong, ulong, @@ -128,14 +118,6 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], sp -= 1024; lmb_reserve(lmb, sp, (CFG_SDRAM_BASE + get_effective_memsize() - sp));
-#if defined(CONFIG_OF_LIBFDT) - /* find flattened device tree */ - ret = boot_get_fdt (cmdtp, flag, argc, argv, images, &of_flat_tree, &of_size); - - if (ret) - goto error; -#endif - if (!of_size) { /* allocate space and init command line */ ret = boot_get_cmdline (lmb, &cmd_start, &cmd_end, bootmap_base); @@ -156,8 +138,9 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], rd_len = images->rd_end - images->rd_start;
#if defined(CONFIG_OF_LIBFDT) - ret = boot_relocate_fdt (lmb, bootmap_base, - cmdtp, flag, argc, argv, &of_flat_tree, &of_size); + ret = boot_relocate_fdt(lmb, bootmap_base, &of_flat_tree, &of_size); + if (ret) + goto error;
/* * Add the chosen node if it doesn't exist, add the env and bd_t @@ -166,7 +149,9 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], if (of_size) { /* pass in dummy initrd info, we'll fix up later */ if (fdt_chosen(of_flat_tree, images->rd_start, images->rd_end, 0) < 0) { - fdt_error ("/chosen node create failed"); + puts ("ERROR: "); + puts ("/chosen node create failed"); + puts (" - must RESET the board to recover.\n"); goto error; } #ifdef CONFIG_OF_BOARD_SETUP @@ -340,464 +325,3 @@ static void set_clocks_in_mhz (bd_t *kbd) #endif /* CONFIG_MPC5xxx */ } } - -#if defined(CONFIG_OF_LIBFDT) -static void fdt_error (const char *msg) -{ - puts ("ERROR: "); - puts (msg); - puts (" - must RESET the board to recover.\n"); -} - -static image_header_t *image_get_fdt (ulong fdt_addr) -{ - image_header_t *fdt_hdr = (image_header_t *)fdt_addr; - - image_print_contents (fdt_hdr); - - puts (" Verifying Checksum ... "); - if (!image_check_hcrc (fdt_hdr)) { - fdt_error ("fdt header checksum invalid"); - return NULL; - } - - if (!image_check_dcrc (fdt_hdr)) { - fdt_error ("fdt checksum invalid"); - return NULL; - } - puts ("OK\n"); - - if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) { - fdt_error ("uImage is not a fdt"); - return NULL; - } - if (image_get_comp (fdt_hdr) != IH_COMP_NONE) { - fdt_error ("uImage is compressed"); - return NULL; - } - if (fdt_check_header ((char *)image_get_data (fdt_hdr)) != 0) { - fdt_error ("uImage data is not a fdt"); - return NULL; - } - return fdt_hdr; -} - -/** - * fit_check_fdt - verify FIT format FDT subimage - * @fit_hdr: pointer to the FIT header - * fdt_noffset: FDT subimage node offset within FIT image - * @verify: data CRC verification flag - * - * fit_check_fdt() verifies integrity of the FDT subimage and from - * specified FIT image. - * - * returns: - * 1, on success - * 0, on failure - */ -#if defined(CONFIG_FIT) -static int fit_check_fdt (const void *fit, int fdt_noffset, int verify) -{ - fit_image_print (fit, fdt_noffset, " "); - - if (verify) { - puts (" Verifying Hash Integrity ... "); - if (!fit_image_check_hashes (fit, fdt_noffset)) { - fdt_error ("Bad Data Hash"); - return 0; - } - puts ("OK\n"); - } - - if (!fit_image_check_type (fit, fdt_noffset, IH_TYPE_FLATDT)) { - fdt_error ("Not a FDT image"); - return 0; - } - - if (!fit_image_check_comp (fit, fdt_noffset, IH_COMP_NONE)) { - fdt_error ("FDT image is compressed"); - return 0; - } - - return 1; -} -#endif /* CONFIG_FIT */ - -static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, char **of_flat_tree, ulong *of_size) -{ - ulong fdt_addr; - image_header_t *fdt_hdr; - char *fdt_blob = NULL; - ulong image_start, image_end; - ulong load_start, load_end; -#if defined(CONFIG_FIT) - void *fit_hdr; - const char *fit_uname_config = NULL; - const char *fit_uname_fdt = NULL; - ulong default_addr; - int cfg_noffset; - int fdt_noffset; - const void *data; - size_t size; -#endif - - *of_flat_tree = NULL; - *of_size = 0; - - if (argc > 3 || genimg_has_config (images)) { -#if defined(CONFIG_FIT) - if (argc > 3) { - /* - * If the FDT blob comes from the FIT image and the - * FIT image address is omitted in the command line - * argument, try to use ramdisk or os FIT image - * address or default load address. - */ - if (images->fit_uname_rd) - default_addr = (ulong)images->fit_hdr_rd; - else if (images->fit_uname_os) - default_addr = (ulong)images->fit_hdr_os; - else - default_addr = load_addr; - - if (fit_parse_conf (argv[3], default_addr, - &fdt_addr, &fit_uname_config)) { - debug ("* fdt: config '%s' from image at 0x%08lx\n", - fit_uname_config, fdt_addr); - } else if (fit_parse_subimage (argv[3], default_addr, - &fdt_addr, &fit_uname_fdt)) { - debug ("* fdt: subimage '%s' from image at 0x%08lx\n", - fit_uname_fdt, fdt_addr); - } else -#endif - { - fdt_addr = simple_strtoul(argv[3], NULL, 16); - debug ("* fdt: cmdline image address = 0x%08lx\n", - fdt_addr); - } -#if defined(CONFIG_FIT) - } else { - /* use FIT configuration provided in first bootm - * command argument - */ - fdt_addr = (ulong)images->fit_hdr_os; - fit_uname_config = images->fit_uname_cfg; - debug ("* fdt: using config '%s' from image at 0x%08lx\n", - fit_uname_config, fdt_addr); - - /* - * Check whether configuration has FDT blob defined, - * if not quit silently. - */ - fit_hdr = (void *)fdt_addr; - cfg_noffset = fit_conf_get_node (fit_hdr, - fit_uname_config); - if (cfg_noffset < 0) { - debug ("* fdt: no such config\n"); - return 0; - } - - fdt_noffset = fit_conf_get_fdt_node (fit_hdr, - cfg_noffset); - if (fdt_noffset < 0) { - debug ("* fdt: no fdt in config\n"); - return 0; - } - } -#endif - - debug ("## Checking for 'FDT'/'FDT Image' at %08lx\n", - fdt_addr); - - /* copy from dataflash if needed */ - fdt_addr = genimg_get_image (fdt_addr); - - /* - * Check if there is an FDT image at the - * address provided in the second bootm argument - * check image type, for FIT images get a FIT node. - */ - switch (genimg_get_format ((void *)fdt_addr)) { - case IMAGE_FORMAT_LEGACY: - /* verify fdt_addr points to a valid image header */ - printf ("## Flattened Device Tree from Legacy Image at %08lx\n", - fdt_addr); - fdt_hdr = image_get_fdt (fdt_addr); - if (!fdt_hdr) - goto error; - - /* - * move image data to the load address, - * make sure we don't overwrite initial image - */ - image_start = (ulong)fdt_hdr; - image_end = image_get_image_end (fdt_hdr); - - load_start = image_get_load (fdt_hdr); - load_end = load_start + image_get_data_size (fdt_hdr); - - if ((load_start < image_end) && (load_end > image_start)) { - fdt_error ("fdt overwritten"); - goto error; - } - - debug (" Loading FDT from 0x%08lx to 0x%08lx\n", - image_get_data (fdt_hdr), load_start); - - memmove ((void *)load_start, - (void *)image_get_data (fdt_hdr), - image_get_data_size (fdt_hdr)); - - fdt_blob = (char *)load_start; - break; - case IMAGE_FORMAT_FIT: - /* - * This case will catch both: new uImage format - * (libfdt based) and raw FDT blob (also libfdt - * based). - */ -#if defined(CONFIG_FIT) - /* check FDT blob vs FIT blob */ - if (fit_check_format ((const void *)fdt_addr)) { - /* - * FIT image - */ - fit_hdr = (void *)fdt_addr; - printf ("## Flattened Device Tree from FIT Image at %08lx\n", - fdt_addr); - - if (!fit_uname_fdt) { - /* - * no FDT blob image node unit name, - * try to get config node first. If - * config unit node name is NULL - * fit_conf_get_node() will try to - * find default config node - */ - cfg_noffset = fit_conf_get_node (fit_hdr, - fit_uname_config); - - if (cfg_noffset < 0) { - fdt_error ("Could not find configuration node\n"); - goto error; - } - - fit_uname_config = fdt_get_name (fit_hdr, - cfg_noffset, NULL); - printf (" Using '%s' configuration\n", - fit_uname_config); - - fdt_noffset = fit_conf_get_fdt_node (fit_hdr, - cfg_noffset); - fit_uname_fdt = fit_get_name (fit_hdr, - fdt_noffset, NULL); - } else { - /* get FDT component image node offset */ - fdt_noffset = fit_image_get_node (fit_hdr, - fit_uname_fdt); - } - if (fdt_noffset < 0) { - fdt_error ("Could not find subimage node\n"); - goto error; - } - - printf (" Trying '%s' FDT blob subimage\n", - fit_uname_fdt); - - if (!fit_check_fdt (fit_hdr, fdt_noffset, - images->verify)) - goto error; - - /* get ramdisk image data address and length */ - if (fit_image_get_data (fit_hdr, fdt_noffset, - &data, &size)) { - fdt_error ("Could not find FDT subimage data"); - goto error; - } - - /* verift that image data is a proper FDT blob */ - if (fdt_check_header ((char *)data) != 0) { - fdt_error ("Subimage data is not a FTD"); - goto error; - } - - /* - * move image data to the load address, - * make sure we don't overwrite initial image - */ - image_start = (ulong)fit_hdr; - image_end = fit_get_end (fit_hdr); - - if (fit_image_get_load (fit_hdr, fdt_noffset, - &load_start) == 0) { - load_end = load_start + size; - - if ((load_start < image_end) && - (load_end > image_start)) { - fdt_error ("FDT overwritten"); - goto error; - } - - printf (" Loading FDT from 0x%08lx to 0x%08lx\n", - (ulong)data, load_start); - - memmove ((void *)load_start, - (void *)data, size); - - fdt_blob = (char *)load_start; - } else { - fdt_blob = (char *)data; - } - - images->fit_hdr_fdt = fit_hdr; - images->fit_uname_fdt = fit_uname_fdt; - images->fit_noffset_fdt = fdt_noffset; - break; - } else -#endif - { - /* - * FDT blob - */ - fdt_blob = (char *)fdt_addr; - debug ("* fdt: raw FDT blob\n"); - printf ("## Flattened Device Tree blob at %08lx\n", (long)fdt_blob); - } - break; - default: - fdt_error ("Did not find a cmdline Flattened Device Tree"); - goto error; - } - - printf (" Booting using the fdt blob at 0x%x\n", (int)fdt_blob); - - } else if (images->legacy_hdr_valid && - image_check_type (&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) { - - ulong fdt_data, fdt_len; - - /* - * Now check if we have a legacy multi-component image, - * get second entry data start address and len. - */ - printf ("## Flattened Device Tree from multi " - "component Image at %08lX\n", - (ulong)images->legacy_hdr_os); - - image_multi_getimg (images->legacy_hdr_os, 2, &fdt_data, &fdt_len); - if (fdt_len) { - - fdt_blob = (char *)fdt_data; - printf (" Booting using the fdt at 0x%x\n", (int)fdt_blob); - - if (fdt_check_header (fdt_blob) != 0) { - fdt_error ("image is not a fdt"); - goto error; - } - - if (be32_to_cpu (fdt_totalsize (fdt_blob)) != fdt_len) { - fdt_error ("fdt size != image size"); - goto error; - } - } else { - debug ("## No Flattened Device Tree\n"); - return 0; - } - } else { - debug ("## No Flattened Device Tree\n"); - return 0; - } - - *of_flat_tree = fdt_blob; - *of_size = be32_to_cpu (fdt_totalsize (fdt_blob)); - debug (" of_flat_tree at 0x%08lx size 0x%08lx\n", - *of_flat_tree, *of_size); - - return 0; - -error: - do_reset (cmdtp, flag, argc, argv); - return 1; -} - -static int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, - cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - char **of_flat_tree, ulong *of_size) -{ - char *fdt_blob = *of_flat_tree; - ulong relocate = 0; - ulong of_len = 0; - - /* nothing to do */ - if (*of_size == 0) - return 0; - - if (fdt_check_header (fdt_blob) != 0) { - fdt_error ("image is not a fdt"); - goto error; - } - -#ifndef CFG_NO_FLASH - /* move the blob if it is in flash (set relocate) */ - if (addr2info ((ulong)fdt_blob) != NULL) - relocate = 1; -#endif - - /* - * The blob needs to be inside the boot mapping. - */ - if (fdt_blob < (char *)bootmap_base) - relocate = 1; - - if ((fdt_blob + *of_size + CFG_FDT_PAD) >= - ((char *)CFG_BOOTMAPSZ + bootmap_base)) - relocate = 1; - - /* move flattend device tree if needed */ - if (relocate) { - int err; - ulong of_start = 0; - - /* position on a 4K boundary before the alloc_current */ - /* Pad the FDT by a specified amount */ - of_len = *of_size + CFG_FDT_PAD; - of_start = (unsigned long)lmb_alloc_base(lmb, of_len, 0x1000, - (CFG_BOOTMAPSZ + bootmap_base)); - - if (of_start == 0) { - puts("device tree - allocation error\n"); - goto error; - } - - debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - (ulong)fdt_blob, (ulong)fdt_blob + *of_size - 1, - of_len, of_len); - - printf (" Loading Device Tree to %08lx, end %08lx ... ", - of_start, of_start + of_len - 1); - - err = fdt_open_into (fdt_blob, (void *)of_start, of_len); - if (err != 0) { - fdt_error ("fdt move failed"); - goto error; - } - puts ("OK\n"); - - *of_flat_tree = (char *)of_start; - *of_size = of_len; - } else { - *of_flat_tree = fdt_blob; - of_len = (CFG_BOOTMAPSZ + bootmap_base) - (ulong)fdt_blob; - lmb_reserve(lmb, (ulong)fdt_blob, of_len); - fdt_set_totalsize(*of_flat_tree, of_len); - - *of_size = of_len; - } - - return 0; - -error: - return 1; -} -#endif

Set the fdt working address so "fdt FOO" commands can be used as part of the bootm flow.
Signed-off-by: Kumar Gala galak@kernel.crashing.org --- common/cmd_bootm.c | 9 +++++++++ common/cmd_fdt.c | 5 +++++ common/image.c | 1 + include/fdt_support.h | 2 ++ 4 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 918ea98..c5dbf76 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -44,6 +44,13 @@ #include <hush.h> #endif
+#if defined(CONFIG_OF_LIBFDT) +#include <fdt.h> +#include <libfdt.h> +#include <fdt_support.h> +#endif + + DECLARE_GLOBAL_DATA_PTR;
extern int gunzip (void *dst, int dstlen, unsigned char *src, unsigned long *lenp); @@ -267,6 +274,8 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) puts ("Could not find a valid device tree\n"); return 1; } + + set_working_fdt_addr(images.ft_addr); #endif }
diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index c129993..b397a21 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -50,6 +50,11 @@ static int fdt_print(const char *pathp, char *prop, int depth); */ struct fdt_header *working_fdt;
+void set_working_fdt_addr(void *addr) +{ + working_fdt = addr; +} + /* * Flattened Device Tree command, see the help for parameter definitions. */ diff --git a/common/image.c b/common/image.c index e7cb57c..60e1c9d 100644 --- a/common/image.c +++ b/common/image.c @@ -1245,6 +1245,7 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, *of_size = of_len; }
+ set_working_fdt_addr(*of_flat_tree); return 0;
error: diff --git a/include/fdt_support.h b/include/fdt_support.h index a7c6326..761f85c 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -68,5 +68,7 @@ void ft_cpu_setup(void *blob, bd_t *bd); void ft_pci_setup(void *blob, bd_t *bd); #endif
+void set_working_fdt_addr(void *addr); + #endif /* ifdef CONFIG_OF_LIBFDT */ #endif /* ifndef __FDT_SUPPORT_H */

Hi Kumar,
I'm on the road this week, so my ability to review code this week is suboptimal. Having said that, this looks good!
Kumar Gala wrote:
[PATCH 01/15] Update linux bootm to support ePAPR client interface [PATCH 02/15] add ability to disable ft_board_setup as part of bootm
possibly drop this patch if the boots method is acceptable
I don't follow what this remark is saying.
Is there a reason scripting in the "fdt boardsetup" command, eliminating the need to call ft_board_setup() as part of the bootm command chain?
[PATCH 03/15] Clean up usage of icache_disable/dcache_disable [PATCH 04/15] fdt: added the ability to set initrd start/end via chosen command [PATCH 05/15] fdt: fdt addr w/o any args reports back the current working address [PATCH 06/15] bootm: refactor entry point code [PATCH 07/15] bootm: refactor ramdisk locating code [PATCH 08/15] bootm: refactor fdt locating and relocation code [PATCH 09/15] bootm: Set working fdt address as part of the bootm flow [PATCH 10/15] bootm: move lmb into the bootm_headers_t structure [PATCH 11/15] bootm: refactor image detection and os load steps [PATCH 12/15] fdt: refactor fdt resize code [PATCH 13/15] fdt: refactor initrd related code [PATCH 14/15] fdt: Added resize command [PATCH 15/15] boots: start of sub commands
I believe all the patches except 15/15 should be in a reasonable state for u-boot-testing. I need to add an 'interrupt enable/disable' command but with a small hack I'm able to mimic the bootm command on ppc by:
boots start <A> <B> <C>
Per my previous comment: boots is already taken.
boots load_os /* hacked to disable interrupts */ boots prep_os boots initrd_relocate boots fdt_relocate fdt chosen $initrd_start $initrd_end fdt boardsetup boots jump
Would "bootm go" be better than "bootm jump"? I'm thinking we have a "go" command, so "bootm go" sounds better, more symmetric, to me. Maybe I'm painting the bikeshed?
Right now 15/15 is focused on only PPC w/Linux. If this looks acceptable I'll split 15/15 into proper patches an add support for the other ARCHes and OSes.
- k
Thanks for working this, gvb

On Aug 13, 2008, at 12:31 AM, Jerry Van Baren wrote:
Hi Kumar,
I'm on the road this week, so my ability to review code this week is suboptimal. Having said that, this looks good!
Kumar Gala wrote:
[PATCH 01/15] Update linux bootm to support ePAPR client interface [PATCH 02/15] add ability to disable ft_board_setup as part of bootm possibly drop this patch if the boots method is acceptable
I don't follow what this remark is saying.
Is there a reason scripting in the "fdt boardsetup" command, eliminating the need to call ft_board_setup() as part of the bootm command chain?
I just meant that the patch adds an 'env' var to stop calling 'fdt boardsetup' Once we have sub commands that isn't really needed anymore so I'm ok w/dropping the patch. It was a stop gap before subcommands are working.
[PATCH 03/15] Clean up usage of icache_disable/dcache_disable [PATCH 04/15] fdt: added the ability to set initrd start/end via chosen command [PATCH 05/15] fdt: fdt addr w/o any args reports back the current working address [PATCH 06/15] bootm: refactor entry point code [PATCH 07/15] bootm: refactor ramdisk locating code [PATCH 08/15] bootm: refactor fdt locating and relocation code [PATCH 09/15] bootm: Set working fdt address as part of the bootm flow [PATCH 10/15] bootm: move lmb into the bootm_headers_t structure [PATCH 11/15] bootm: refactor image detection and os load steps [PATCH 12/15] fdt: refactor fdt resize code [PATCH 13/15] fdt: refactor initrd related code [PATCH 14/15] fdt: Added resize command [PATCH 15/15] boots: start of sub commands I believe all the patches except 15/15 should be in a reasonable state for u-boot-testing. I need to add an 'interrupt enable/disable' command but with a small hack I'm able to mimic the bootm command on ppc by: boots start <A> <B> <C>
Per my previous comment: boots is already taken.
Yeah, I need to understand wd's concerns here.
boots load_os /* hacked to disable interrupts */ boots prep_os boots initrd_relocate boots fdt_relocate fdt chosen $initrd_start $initrd_end fdt boardsetup boots jump
Would "bootm go" be better than "bootm jump"? I'm thinking we have a "go" command, so "bootm go" sounds better, more symmetric, to me. Maybe I'm painting the bikeshed?
got not issue w/renaming.
Right now 15/15 is focused on only PPC w/Linux. If this looks acceptable I'll split 15/15 into proper patches an add support for the other ARCHes and OSes.
- k
Thanks for working this, gvb
- k

Kumar Gala wrote:
On Aug 13, 2008, at 12:31 AM, Jerry Van Baren wrote:
Hi Kumar,
I'm on the road this week, so my ability to review code this week is suboptimal. Having said that, this looks good!
Kumar Gala wrote:
[PATCH 01/15] Update linux bootm to support ePAPR client interface [PATCH 02/15] add ability to disable ft_board_setup as part of bootm possibly drop this patch if the boots method is acceptable
I don't follow what this remark is saying.
Is there a reason scripting in the "fdt boardsetup" command, eliminating the need to call ft_board_setup() as part of the bootm command chain?
I just meant that the patch adds an 'env' var to stop calling 'fdt boardsetup' Once we have sub commands that isn't really needed anymore so I'm ok w/dropping the patch. It was a stop gap before subcommands are working.
Ahh, OK, I understand now.
Thanks, gvb
participants (2)
-
Jerry Van Baren
-
Kumar Gala