X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=lib_ppc%2Fbootm.c;h=b08ee0dc4d0cdb0fc4744eb6de2316b233ea73a4;hb=c160a9544743e80e8889edb2275538e7764ce334;hp=29016075d78222df623510f2c09992e2e8a825bd;hpb=6fe2946f198481254a6ee9600d7456b8316a4083;p=kernel%2Fu-boot.git diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 2901607..b08ee0d 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -51,6 +51,10 @@ static int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, #include #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[]); @@ -71,11 +75,12 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ulong initrd_start, initrd_end; ulong rd_data_start, rd_data_end, rd_len; ulong size; + phys_size_t bootm_size; 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; @@ -84,23 +89,27 @@ 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(); - size = getenv_bootm_size(); + bootm_size = getenv_bootm_size(); #ifdef DEBUG - if (((u64)bootmap_base + size) > (CFG_SDRAM_BASE + (u64)gd->ram_size)) + if (((u64)bootmap_base + bootm_size) > + (CFG_SDRAM_BASE + (u64)gd->ram_size)) puts("WARNING: bootm_low + bootm_size exceed total memory\n"); - if ((bootmap_base + size) > get_effective_memsize()) + if ((bootmap_base + bootm_size) > get_effective_memsize()) puts("WARNING: bootm_low + bootm_size exceed eff. memory\n"); #endif - size = min(size, get_effective_memsize()); + size = min(bootm_size, get_effective_memsize()); size = min(size, CFG_LINUX_LOWMEM_MAX_SIZE); - if (size < getenv_bootm_size()) { + if (size < bootm_size) { ulong base = bootmap_base + size; - printf("WARNING: adjusting available memory to %x\n", size); - lmb_reserve(lmb, base, getenv_bootm_size() - size); + printf("WARNING: adjusting available memory to %lx\n", size); + lmb_reserve(lmb, base, bootm_size - size); } /* @@ -144,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); -#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; - /* find ramdisk */ ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_PPC, &rd_data_start, &rd_data_end); @@ -189,6 +180,45 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ft_board_setup(of_flat_tree, gd->bd); #endif } + + /* Fixup the fdt memreserve now that we know how big it is */ + if (of_flat_tree) { + int j; + uint64_t addr, size; + int total = fdt_num_mem_rsv(of_flat_tree); + uint actualsize; + + for (j = 0; j < total; j++) { + fdt_get_mem_rsv(of_flat_tree, j, &addr, &size); + if (addr == (uint64_t)(u32)of_flat_tree) { + fdt_del_mem_rsv(of_flat_tree, j); + break; + } + } + + /* Delete the old LMB reservation */ + lmb_free(lmb, (phys_addr_t)(u32)of_flat_tree, + (phys_size_t)fdt_totalsize(of_flat_tree)); + + /* Calculate the actual size of the fdt */ + actualsize = fdt_off_dt_strings(of_flat_tree) + + fdt_size_dt_strings(of_flat_tree); + + /* Make it so the fdt ends on a page boundary */ + actualsize = ALIGN(actualsize, 0x1000); + actualsize = actualsize - ((uint)of_flat_tree & 0xfff); + + /* Change the fdt header to reflect the correct size */ + fdt_set_totalsize(of_flat_tree, actualsize); + of_size = actualsize; + + /* Add the new reservation */ + ret = fdt_add_mem_rsv(of_flat_tree, (uint)of_flat_tree, + of_size); + + /* Create a new LMB reservation */ + lmb_reserve(lmb, (ulong)of_flat_tree, of_size); + } #endif /* CONFIG_OF_LIBFDT */ ret = boot_ramdisk_high (lmb, rd_data_start, rd_len, &initrd_start, &initrd_end); @@ -232,21 +262,28 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], #if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500) unlock_ram_in_cache(); #endif - if (!images->autostart) - return ; #if defined(CONFIG_OF_LIBFDT) 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 @@ -258,16 +295,18 @@ 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 ; error: - if (images->autostart) - do_reset (cmdtp, flag, argc, argv); + do_reset (cmdtp, flag, argc, argv); return ; } @@ -626,9 +665,9 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], /* * FDT blob */ - debug ("* fdt: raw FDT blob\n"); - printf ("## Flattened Device Tree blob at %08lx\n", 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: @@ -636,10 +675,10 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], goto error; } - printf (" Booting using the fdt blob at 0x%x\n", fdt_blob); + 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, IH_TYPE_MULTI)) { + image_check_type (&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) { ulong fdt_data, fdt_len; @@ -655,7 +694,7 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], if (fdt_len) { fdt_blob = (char *)fdt_data; - printf (" Booting using the fdt at 0x%x\n", fdt_blob); + 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"); @@ -667,9 +706,8 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], goto error; } } else { - fdt_error ("Did not find a Flattened Device Tree " - "in a legacy multi-component image"); - goto error; + debug ("## No Flattened Device Tree\n"); + return 0; } } else { debug ("## No Flattened Device Tree\n"); @@ -712,22 +750,25 @@ static int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, #endif /* - * The blob must be within CFG_BOOTMAPSZ, - * so we flag it to be copied if it is not. + * The blob needs to be inside the boot mapping. */ - if (fdt_blob >= (char *)CFG_BOOTMAPSZ) + if (fdt_blob < (char *)bootmap_base) relocate = 1; - of_len = be32_to_cpu (fdt_totalsize (fdt_blob)); + 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; + ulong of_start = 0; /* position on a 4K boundary before the alloc_current */ - of_start = lmb_alloc_base(lmb, of_len, 0x1000, - (CFG_BOOTMAPSZ + bootmap_base)); + /* 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"); @@ -735,7 +776,7 @@ static int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, } debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - (ulong)fdt_blob, (ulong)fdt_blob + of_len - 1, + (ulong)fdt_blob, (ulong)fdt_blob + *of_size - 1, of_len, of_len); printf (" Loading Device Tree to %08lx, end %08lx ... ", @@ -749,9 +790,14 @@ static int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, puts ("OK\n"); *of_flat_tree = (char *)of_start; + *of_size = of_len; } else { *of_flat_tree = fdt_blob; - lmb_reserve(lmb, (ulong)fdt, of_len); + 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;