From 5d3cc55ecbae277e08f5ff771da20b1d6a36ec36 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 8 Jan 2008 18:11:43 +0100 Subject: [new uImage] Move PPC do_bootm_linux() to lib_ppc/ppc_linux.c PPC implementation of do_bootm_linux() routine is moved to a dedicated file lib_ppc/ppc_linux.c Signed-off-by: Marian Balakowicz --- lib_ppc/Makefile | 3 +- lib_ppc/ppc_linux.c | 589 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 591 insertions(+), 1 deletion(-) create mode 100644 lib_ppc/ppc_linux.c (limited to 'lib_ppc') diff --git a/lib_ppc/Makefile b/lib_ppc/Makefile index 2ba034f1ee..2aa0154856 100644 --- a/lib_ppc/Makefile +++ b/lib_ppc/Makefile @@ -28,7 +28,8 @@ LIB = $(obj)lib$(ARCH).a SOBJS = ppcstring.o ticks.o COBJS = board.o \ - bat_rw.o cache.o extable.o kgdb.o time.o interrupts.o + bat_rw.o cache.o extable.o kgdb.o time.o interrupts.o \ + ppc_linux.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/lib_ppc/ppc_linux.c b/lib_ppc/ppc_linux.c new file mode 100644 index 0000000000..ff2a3e56ff --- /dev/null +++ b/lib_ppc/ppc_linux.c @@ -0,0 +1,589 @@ +/* + * (C) Copyright 2008 Semihalf + * + * (C) Copyright 2000-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_OF_LIBFDT) +#include +#include +#include +#endif +#if defined(CONFIG_OF_FLAT_TREE) +#include +#endif + +#ifdef CONFIG_LOGBUFFER +#include +#endif + +#ifdef CFG_INIT_RAM_LOCK +#include +#endif + +#define CHUNKSZ (64 * 1024) + +DECLARE_GLOBAL_DATA_PTR; +extern image_header_t header; + +/*cmd_boot.c*/ +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + +#if defined(CONFIG_CMD_BDI) +extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +#endif + +void __attribute__((noinline)) +do_bootm_linux (cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + ulong addr, + ulong *len_ptr, + int verify) +{ + ulong sp; + ulong len; + ulong initrd_start, initrd_end; + ulong cmd_start, cmd_end; + ulong initrd_high; + ulong data; + int initrd_copy_to_ram = 1; + char *cmdline; + char *s; + 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, + * turning the "load high" feature off. This is intentional. + */ + initrd_high = simple_strtoul(s, NULL, 16); + if (initrd_high == ~0) + initrd_copy_to_ram = 0; + } else { /* not set, no restrictions to load high */ + initrd_high = ~0; + } + +#ifdef CONFIG_LOGBUFFER + kbd=gd->bd; + /* Prevent initrd from overwriting logbuffer */ + if (initrd_high < (kbd->bi_memsize-LOGBUFF_LEN-LOGBUFF_OVERHEAD)) + initrd_high = kbd->bi_memsize-LOGBUFF_LEN-LOGBUFF_OVERHEAD; + debug ("## Logbuffer at 0x%08lX ", kbd->bi_memsize-LOGBUFF_LEN); +#endif + + /* + * Booting a (Linux) kernel image + * + * Allocate space for command line and board info - the + * address should be as high as possible within the reach of + * the kernel (see CFG_BOOTMAPSZ settings), but in unused + * memory, which means far enough below the current stack + * pointer. + */ + + asm( "mr %0,1": "=r"(sp) : ); + + debug ("## Current stack ends at 0x%08lX ", sp); + + sp -= 2048; /* just to be sure */ + if (sp > CFG_BOOTMAPSZ) + sp = CFG_BOOTMAPSZ; + sp &= ~0xF; + + debug ("=> set upper limit to 0x%08lX\n", sp); + + cmdline = (char *)((sp - CFG_BARGSIZE) & ~0xF); + kbd = (bd_t *)(((ulong)cmdline - sizeof(bd_t)) & ~0xF); + + if ((s = getenv("bootargs")) == NULL) + s = ""; + + strcpy (cmdline, s); + + cmd_start = (ulong)&cmdline[0]; + cmd_end = cmd_start + strlen(cmdline); + + *kbd = *(gd->bd); + +#ifdef DEBUG + printf ("## cmdline at 0x%08lX ... 0x%08lX\n", cmd_start, cmd_end); + +#if defined(CONFIG_CMD_BDI) + do_bdinfo (NULL, 0, 0, NULL); +#endif +#endif + + if ((s = getenv ("clocks_in_mhz")) != NULL) { + /* convert all clock information to MHz */ + kbd->bi_intfreq /= 1000000L; + kbd->bi_busfreq /= 1000000L; +#if defined(CONFIG_MPC8220) + kbd->bi_inpfreq /= 1000000L; + kbd->bi_pcifreq /= 1000000L; + kbd->bi_pevfreq /= 1000000L; + kbd->bi_flbfreq /= 1000000L; + kbd->bi_vcofreq /= 1000000L; +#endif +#if defined(CONFIG_CPM2) + kbd->bi_cpmfreq /= 1000000L; + kbd->bi_brgfreq /= 1000000L; + kbd->bi_sccfreq /= 1000000L; + kbd->bi_vco /= 1000000L; +#endif +#if defined(CONFIG_MPC5xxx) + kbd->bi_ipbfreq /= 1000000L; + kbd->bi_pcifreq /= 1000000L; +#endif /* CONFIG_MPC5xxx */ + } + + kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr); + + /* + * Check if there is an initrd image + */ + +#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) + /* Look for a '-' which indicates to ignore the ramdisk argument */ + if (argc >= 3 && strcmp(argv[2], "-") == 0) { + debug ("Skipping initrd\n"); + len = data = 0; + } + else +#endif + if (argc >= 3) { + debug ("Not skipping initrd\n"); + show_boot_progress (9); + + addr = simple_strtoul(argv[2], NULL, 16); + + printf ("## Loading RAMDisk Image at %08lx ...\n", addr); + hdr = (image_header_t *)addr; + + if (!image_check_magic (hdr)) { + puts ("Bad Magic Number\n"); + show_boot_progress (-10); + do_reset (cmdtp, flag, argc, argv); + } + + if (!image_check_hcrc (hdr)) { + puts ("Bad Header Checksum\n"); + show_boot_progress (-11); + do_reset (cmdtp, flag, argc, argv); + } + show_boot_progress (10); + + print_image_hdr (hdr); + + if (verify) { + puts (" Verifying Checksum ... "); + + if (!image_check_dcrc_wd (hdr, CHUNKSZ)) { + puts ("Bad Data CRC\n"); + show_boot_progress (-12); + do_reset (cmdtp, flag, argc, argv); + } + puts ("OK\n"); + } + + show_boot_progress (11); + + if (!image_check_os (hdr, IH_OS_LINUX) || + !image_check_arch (hdr, IH_ARCH_PPC) || + !image_check_type (hdr, IH_TYPE_RAMDISK)) { + puts ("No Linux PPC Ramdisk Image\n"); + show_boot_progress (-13); + do_reset (cmdtp, flag, argc, argv); + } + + data = image_get_data (hdr); + len = image_get_data_size (hdr); + + /* + * Now check if we have a multifile image + */ + } else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1])) { + u_long tail = image_to_cpu (len_ptr[0]) % 4; + int i; + + show_boot_progress (13); + + /* skip kernel length and terminator */ + data = (ulong)(&len_ptr[2]); + /* skip any additional image length fields */ + for (i=1; len_ptr[i]; ++i) + data += 4; + /* add kernel length, and align */ + data += image_to_cpu (len_ptr[0]); + if (tail) { + data += 4 - tail; + } + + len = image_to_cpu (len_ptr[1]); + + } else { + /* + * no initrd image + */ + show_boot_progress (14); + + len = data = 0; + } + +#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) + if(argc > 3) { + of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16); + hdr = (image_header_t *)of_flat_tree; +#if defined(CONFIG_OF_FLAT_TREE) + if (*((ulong *)(of_flat_tree + image_get_header_size ())) != OF_DT_HEADER) { +#else + if (fdt_check_header (of_flat_tree + image_get_header_size ()) != 0) { +#endif +#ifndef CFG_NO_FLASH + if (addr2info((ulong)of_flat_tree) != NULL) + of_data = (ulong)of_flat_tree; +#endif + } else if (image_check_magic (hdr)) { + printf("## Flat Device Tree at %08lX\n", hdr); + print_image_hdr (hdr); + + if ((image_get_load (hdr) < ((unsigned long)hdr + image_get_image_size (hdr))) && + ((image_get_load (hdr) + image_get_data_size (hdr)) > (unsigned long)hdr)) { + puts ("ERROR: fdt overwritten - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + + puts (" Verifying Checksum ... "); + if (!image_check_hcrc (hdr)) { + puts ("ERROR: fdt header checksum invalid - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + + if (!image_check_dcrc (hdr)) { + puts ("ERROR: fdt checksum invalid - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + puts ("OK\n"); + + if (!image_check_type (hdr, IH_TYPE_FLATDT)) { + puts ("ERROR: uImage is not a fdt - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + if (image_get_comp (hdr) != IH_COMP_NONE) { + puts ("ERROR: uImage is compressed - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } +#if defined(CONFIG_OF_FLAT_TREE) + if (*((ulong *)(of_flat_tree + image_get_header_size ())) != OF_DT_HEADER) { +#else + if (fdt_check_header (of_flat_tree + image_get_header_size ()) != 0) { +#endif + puts ("ERROR: uImage data is not a fdt - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + + memmove ((void *)image_get_load (hdr), + (void *)(of_flat_tree + image_get_header_size ()), + image_get_data_size (hdr)); + + of_flat_tree = (char *)image_get_load (hdr); + } else { + puts ("Did not find a flat Flat Device Tree.\n" + "Must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + printf (" Booting using the fdt at 0x%x\n", + of_flat_tree); + } else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1]) && (len_ptr[2])) { + u_long tail = image_to_cpu (len_ptr[0]) % 4; + int i; + + /* skip kernel length, initrd length, and terminator */ + of_flat_tree = (char *)(&len_ptr[3]); + /* skip any additional image length fields */ + for (i=2; len_ptr[i]; ++i) + of_flat_tree += 4; + /* add kernel length, and align */ + of_flat_tree += image_to_cpu (len_ptr[0]); + if (tail) { + of_flat_tree += 4 - tail; + } + + /* add initrd length, and align */ + tail = image_to_cpu (len_ptr[1]) % 4; + of_flat_tree += image_to_cpu (len_ptr[1]); + if (tail) { + of_flat_tree += 4 - tail; + } + +#ifndef CFG_NO_FLASH + /* move the blob if it is in flash (set of_data to !null) */ + if (addr2info ((ulong)of_flat_tree) != NULL) + of_data = (ulong)of_flat_tree; +#endif + + +#if defined(CONFIG_OF_FLAT_TREE) + if (*((ulong *)(of_flat_tree)) != OF_DT_HEADER) { +#else + if (fdt_check_header (of_flat_tree) != 0) { +#endif + puts ("ERROR: image is not a fdt - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + +#if defined(CONFIG_OF_FLAT_TREE) + if (((struct boot_param_header *)of_flat_tree)->totalsize != + image_to_cpu (len_ptr[2])) { +#else + if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != + image_to_cpu (len_ptr[2])) { +#endif + puts ("ERROR: fdt size != image size - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + } +#endif + if (!data) { + debug ("No initrd\n"); + } + + if (data) { + if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ + initrd_start = data; + initrd_end = initrd_start + len; + } else { + initrd_start = (ulong)kbd - len; + initrd_start &= ~(4096 - 1); /* align on page */ + + if (initrd_high) { + ulong nsp; + + /* + * the inital ramdisk does not need to be within + * CFG_BOOTMAPSZ as it is not accessed until after + * the mm system is initialised. + * + * do the stack bottom calculation again and see if + * the initrd will fit just below the monitor stack + * bottom without overwriting the area allocated + * above for command line args and board info. + */ + asm( "mr %0,1": "=r"(nsp) : ); + nsp -= 2048; /* just to be sure */ + nsp &= ~0xF; + if (nsp > initrd_high) /* limit as specified */ + nsp = initrd_high; + nsp -= len; + nsp &= ~(4096 - 1); /* align on page */ + if (nsp >= sp) + initrd_start = nsp; + } + + show_boot_progress (12); + + debug ("## initrd at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", + data, data + len - 1, len, len); + + initrd_end = initrd_start + len; + printf (" Loading Ramdisk to %08lx, end %08lx ... ", + initrd_start, initrd_end); +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) + { + size_t l = len; + void *to = (void *)initrd_start; + void *from = (void *)data; + + while (l > 0) { + size_t tail = (l > CHUNKSZ) ? CHUNKSZ : l; + WATCHDOG_RESET(); + memmove (to, from, tail); + to += tail; + from += tail; + l -= tail; + } + } +#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ + memmove ((void *)initrd_start, (void *)data, len); +#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ + puts ("OK\n"); + } + } else { + initrd_start = 0; + initrd_end = 0; + } + +#if defined(CONFIG_OF_LIBFDT) + +#ifdef CFG_BOOTMAPSZ + /* + * The blob must be within CFG_BOOTMAPSZ, + * so we flag it to be copied if it is not. + */ + if (of_flat_tree >= (char *)CFG_BOOTMAPSZ) + of_data = (ulong)of_flat_tree; +#endif + + /* move of_flat_tree if needed */ + if (of_data) { + int err; + ulong of_start, of_len; + + of_len = be32_to_cpu(fdt_totalsize(of_data)); + + /* position on a 4K boundary before the kbd */ + of_start = (ulong)kbd - of_len; + 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); + + 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_data, (void *)of_start, of_len); + if (err != 0) { + puts ("ERROR: fdt move failed - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + puts ("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 (of_flat_tree) { + if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) { + puts ("ERROR: /chosen node create failed - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } +#ifdef CONFIG_OF_HAS_UBOOT_ENV + if (fdt_env(of_flat_tree) < 0) { + puts ("ERROR: /u-boot-env node create failed - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } +#endif +#ifdef CONFIG_OF_HAS_BD_T + if (fdt_bd_t(of_flat_tree) < 0) { + puts ("ERROR: /bd_t node create failed - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } +#endif +#ifdef CONFIG_OF_BOARD_SETUP + /* Call the board-specific fixup routine */ + ft_board_setup(of_flat_tree, gd->bd); +#endif + } +#endif /* CONFIG_OF_LIBFDT */ +#if defined(CONFIG_OF_FLAT_TREE) +#ifdef CFG_BOOTMAPSZ + /* + * The blob must be within CFG_BOOTMAPSZ, + * so we flag it to be copied if it is not. + */ + if (of_flat_tree >= (char *)CFG_BOOTMAPSZ) + of_data = (ulong)of_flat_tree; +#endif + + /* 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); + + 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); + puts ("OK\n"); + } + /* + * Create the /chosen node and modify the blob with board specific + * values as needed. + */ + ft_setup(of_flat_tree, kbd, initrd_start, initrd_end); + /* ft_dump_blob(of_flat_tree); */ +#endif + 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_FLAT_TREE) || 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 + */ + (*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0); + /* does not return */ + } +#endif + /* + * Linux Kernel Parameters (passing board info data): + * r3: ptr to board info data + * r4: initrd_start or 0 if no initrd + * r5: initrd_end - unused if r4 is 0 + * r6: Start of command line string + * r7: End of command line string + */ + (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); + /* does not return */ +} -- cgit v1.2.1 From d45d5a18b6b36688f2365623f9d550566c664b5b Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 8 Jan 2008 18:11:43 +0100 Subject: [new uImage] Cleanup OF/FDT #if/#elif/#endif use in do_bootm_linux() Make CONFIG_OF_LIBFDT and CONFIG_OF_FLAT_TREE use more readable in PPC variant of do_bootm_linux() routine. Signed-off-by: Marian Balakowicz --- lib_ppc/ppc_linux.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/ppc_linux.c b/lib_ppc/ppc_linux.c index ff2a3e56ff..94872a61dc 100644 --- a/lib_ppc/ppc_linux.c +++ b/lib_ppc/ppc_linux.c @@ -37,8 +37,7 @@ #include #include #include -#endif -#if defined(CONFIG_OF_FLAT_TREE) +#elif defined(CONFIG_OF_FLAT_TREE) #include #endif @@ -269,7 +268,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, hdr = (image_header_t *)of_flat_tree; #if defined(CONFIG_OF_FLAT_TREE) if (*((ulong *)(of_flat_tree + image_get_header_size ())) != OF_DT_HEADER) { -#else +#elif defined(CONFIG_OF_LIBFDT) if (fdt_check_header (of_flat_tree + image_get_header_size ()) != 0) { #endif #ifndef CFG_NO_FLASH @@ -313,7 +312,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, } #if defined(CONFIG_OF_FLAT_TREE) if (*((ulong *)(of_flat_tree + image_get_header_size ())) != OF_DT_HEADER) { -#else +#elif defined(CONFIG_OF_LIBFDT) if (fdt_check_header (of_flat_tree + image_get_header_size ()) != 0) { #endif puts ("ERROR: uImage data is not a fdt - " @@ -364,7 +363,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, #if defined(CONFIG_OF_FLAT_TREE) if (*((ulong *)(of_flat_tree)) != OF_DT_HEADER) { -#else +#elif defined(CONFIG_OF_LIBFDT) if (fdt_check_header (of_flat_tree) != 0) { #endif puts ("ERROR: image is not a fdt - " @@ -375,7 +374,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, #if defined(CONFIG_OF_FLAT_TREE) if (((struct boot_param_header *)of_flat_tree)->totalsize != image_to_cpu (len_ptr[2])) { -#else +#elif defined(CONFIG_OF_LIBFDT) if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != image_to_cpu (len_ptr[2])) { #endif @@ -518,8 +517,9 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, ft_board_setup(of_flat_tree, gd->bd); #endif } -#endif /* CONFIG_OF_LIBFDT */ -#if defined(CONFIG_OF_FLAT_TREE) + +#elif defined(CONFIG_OF_FLAT_TREE) + #ifdef CFG_BOOTMAPSZ /* * The blob must be within CFG_BOOTMAPSZ, @@ -552,7 +552,9 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, */ ft_setup(of_flat_tree, kbd, initrd_start, initrd_end); /* ft_dump_blob(of_flat_tree); */ -#endif + +#endif /* #if defined(CONFIG_OF_LIBFDT) #elif defined(CONFIG_OF_FLAT_TREE) */ + debug ("## Transferring control to Linux (at address %08lx) ...\n", (ulong)kernel); -- cgit v1.2.1 From 559316faf7eae0614c91d77f509b57d6c4c091ba Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 8 Jan 2008 18:11:44 +0100 Subject: [new uImage] Move CHUNKSZ definition to image.h CHUNKSZ defined for PPC and M68K is set to the same value of 64K, move this definition to a common header. Signed-off-by: Marian Balakowicz --- lib_ppc/ppc_linux.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/ppc_linux.c b/lib_ppc/ppc_linux.c index 94872a61dc..4e7734ccd3 100644 --- a/lib_ppc/ppc_linux.c +++ b/lib_ppc/ppc_linux.c @@ -49,8 +49,6 @@ #include #endif -#define CHUNKSZ (64 * 1024) - DECLARE_GLOBAL_DATA_PTR; extern image_header_t header; -- cgit v1.2.1 From 958fc48abddeab513ea4847e34f22a2e9fe67fe1 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 8 Jan 2008 18:11:44 +0100 Subject: [new uImage] Fix FDT header verification in PPC do_boot_linux() routine Signed-off-by: Marian Balakowicz --- lib_ppc/ppc_linux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/ppc_linux.c b/lib_ppc/ppc_linux.c index 4e7734ccd3..671673fcb8 100644 --- a/lib_ppc/ppc_linux.c +++ b/lib_ppc/ppc_linux.c @@ -265,9 +265,9 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16); hdr = (image_header_t *)of_flat_tree; #if defined(CONFIG_OF_FLAT_TREE) - if (*((ulong *)(of_flat_tree + image_get_header_size ())) != OF_DT_HEADER) { + if (*((ulong *)(of_flat_tree)) == OF_DT_HEADER) { #elif defined(CONFIG_OF_LIBFDT) - if (fdt_check_header (of_flat_tree + image_get_header_size ()) != 0) { + if (fdt_check_header (of_flat_tree) == 0) { #endif #ifndef CFG_NO_FLASH if (addr2info((ulong)of_flat_tree) != NULL) -- cgit v1.2.1 From af13cdbc01eaf88880978bfb4f603e012818ba24 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 8 Jan 2008 18:11:45 +0100 Subject: [new uImage] Add memmove_wd() common routine Move common, watchdog sensible memmove code to a helper memmmove_wd() routine. Signed-off-by: Marian Balakowicz --- lib_ppc/ppc_linux.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/ppc_linux.c b/lib_ppc/ppc_linux.c index 671673fcb8..6e2afed9b0 100644 --- a/lib_ppc/ppc_linux.c +++ b/lib_ppc/ppc_linux.c @@ -426,24 +426,10 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, initrd_end = initrd_start + len; printf (" Loading Ramdisk to %08lx, end %08lx ... ", initrd_start, initrd_end); -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - { - size_t l = len; - void *to = (void *)initrd_start; - void *from = (void *)data; - - while (l > 0) { - size_t tail = (l > CHUNKSZ) ? CHUNKSZ : l; - WATCHDOG_RESET(); - memmove (to, from, tail); - to += tail; - from += tail; - l -= tail; - } - } -#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ - memmove ((void *)initrd_start, (void *)data, len); -#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ + + memmove_wd((void *)initrd_start, + (void *)data, len, CHUNKSZ); + puts ("OK\n"); } } else { -- cgit v1.2.1 From f13e7b2e993c61fed1f607962501e051940d6e80 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 8 Jan 2008 18:12:17 +0100 Subject: [new uImage] Cleanup image header pointer use in bootm code - use single image header pointer instead of a set of auxilliary variables. - add multi component image helper routines: get component size/data address Signed-off-by: Marian Balakowicz --- lib_ppc/ppc_linux.c | 177 ++++++++++++++++++++++------------------------------ 1 file changed, 73 insertions(+), 104 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/ppc_linux.c b/lib_ppc/ppc_linux.c index 6e2afed9b0..0a625fc071 100644 --- a/lib_ppc/ppc_linux.c +++ b/lib_ppc/ppc_linux.c @@ -50,9 +50,7 @@ #endif DECLARE_GLOBAL_DATA_PTR; -extern image_header_t header; -/*cmd_boot.c*/ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #if defined(CONFIG_CMD_BDI) @@ -60,25 +58,27 @@ extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #endif void __attribute__((noinline)) -do_bootm_linux (cmd_tbl_t *cmdtp, int flag, +do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - ulong addr, - ulong *len_ptr, + image_header_t *hdr, int verify) { - ulong sp; - ulong len; - ulong initrd_start, initrd_end; - ulong cmd_start, cmd_end; ulong initrd_high; - ulong data; int initrd_copy_to_ram = 1; + ulong initrd_start, initrd_end; + ulong rd_data, rd_len; + image_header_t *rd_hdr; + + ulong cmd_start, cmd_end; char *cmdline; + + ulong sp; char *s; 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) + image_header_t *fdt_hdr; char *of_flat_tree = NULL; ulong of_data = 0; #endif @@ -177,7 +177,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, /* Look for a '-' which indicates to ignore the ramdisk argument */ if (argc >= 3 && strcmp(argv[2], "-") == 0) { debug ("Skipping initrd\n"); - len = data = 0; + rd_len = rd_data = 0; } else #endif @@ -185,30 +185,28 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, debug ("Not skipping initrd\n"); show_boot_progress (9); - addr = simple_strtoul(argv[2], NULL, 16); + rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); + printf ("## Loading RAMDisk Image at %08lx ...\n", (ulong)rd_hdr); - printf ("## Loading RAMDisk Image at %08lx ...\n", addr); - hdr = (image_header_t *)addr; - - if (!image_check_magic (hdr)) { + if (!image_check_magic (rd_hdr)) { puts ("Bad Magic Number\n"); show_boot_progress (-10); do_reset (cmdtp, flag, argc, argv); } - if (!image_check_hcrc (hdr)) { + if (!image_check_hcrc (rd_hdr)) { puts ("Bad Header Checksum\n"); show_boot_progress (-11); do_reset (cmdtp, flag, argc, argv); } show_boot_progress (10); - print_image_hdr (hdr); + print_image_hdr (rd_hdr); if (verify) { puts (" Verifying Checksum ... "); - if (!image_check_dcrc_wd (hdr, CHUNKSZ)) { + if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) { puts ("Bad Data CRC\n"); show_boot_progress (-12); do_reset (cmdtp, flag, argc, argv); @@ -218,52 +216,39 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, show_boot_progress (11); - if (!image_check_os (hdr, IH_OS_LINUX) || - !image_check_arch (hdr, IH_ARCH_PPC) || - !image_check_type (hdr, IH_TYPE_RAMDISK)) { + if (!image_check_os (rd_hdr, IH_OS_LINUX) || + !image_check_arch (rd_hdr, IH_ARCH_PPC) || + !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { puts ("No Linux PPC Ramdisk Image\n"); show_boot_progress (-13); do_reset (cmdtp, flag, argc, argv); } - data = image_get_data (hdr); - len = image_get_data_size (hdr); + rd_data = image_get_data (rd_hdr); + rd_len = image_get_data_size (rd_hdr); /* * Now check if we have a multifile image */ - } else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1])) { - u_long tail = image_to_cpu (len_ptr[0]) % 4; - int i; - + } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + /* + * Get second entry data start address and len + */ + image_multi_getimg (hdr, 1, &rd_data, &rd_len); show_boot_progress (13); - - /* skip kernel length and terminator */ - data = (ulong)(&len_ptr[2]); - /* skip any additional image length fields */ - for (i=1; len_ptr[i]; ++i) - data += 4; - /* add kernel length, and align */ - data += image_to_cpu (len_ptr[0]); - if (tail) { - data += 4 - tail; - } - - len = image_to_cpu (len_ptr[1]); - } else { /* - * no initrd image + * No initrd image */ show_boot_progress (14); - len = data = 0; + rd_len = rd_data = 0; } #if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) if(argc > 3) { of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16); - hdr = (image_header_t *)of_flat_tree; + fdt_hdr = (image_header_t *)of_flat_tree; #if defined(CONFIG_OF_FLAT_TREE) if (*((ulong *)(of_flat_tree)) == OF_DT_HEADER) { #elif defined(CONFIG_OF_LIBFDT) @@ -273,37 +258,37 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, if (addr2info((ulong)of_flat_tree) != NULL) of_data = (ulong)of_flat_tree; #endif - } else if (image_check_magic (hdr)) { - printf("## Flat Device Tree at %08lX\n", hdr); - print_image_hdr (hdr); + } else if (image_check_magic (fdt_hdr)) { + printf ("## Flat Device Tree at %08lX\n", fdt_hdr); + print_image_hdr (fdt_hdr); - if ((image_get_load (hdr) < ((unsigned long)hdr + image_get_image_size (hdr))) && - ((image_get_load (hdr) + image_get_data_size (hdr)) > (unsigned long)hdr)) { + if ((image_get_load (fdt_hdr) < image_get_image_end (fdt_hdr)) && + ((image_get_load (fdt_hdr) + image_get_data_size (fdt_hdr)) > (unsigned long)fdt_hdr)) { puts ("ERROR: fdt overwritten - " "must RESET the board to recover.\n"); do_reset (cmdtp, flag, argc, argv); } puts (" Verifying Checksum ... "); - if (!image_check_hcrc (hdr)) { + if (!image_check_hcrc (fdt_hdr)) { puts ("ERROR: fdt header checksum invalid - " "must RESET the board to recover.\n"); do_reset (cmdtp, flag, argc, argv); } - if (!image_check_dcrc (hdr)) { + if (!image_check_dcrc (fdt_hdr)) { puts ("ERROR: fdt checksum invalid - " "must RESET the board to recover.\n"); do_reset (cmdtp, flag, argc, argv); } puts ("OK\n"); - if (!image_check_type (hdr, IH_TYPE_FLATDT)) { + if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) { puts ("ERROR: uImage is not a fdt - " "must RESET the board to recover.\n"); do_reset (cmdtp, flag, argc, argv); } - if (image_get_comp (hdr) != IH_COMP_NONE) { + if (image_get_comp (fdt_hdr) != IH_COMP_NONE) { puts ("ERROR: uImage is compressed - " "must RESET the board to recover.\n"); do_reset (cmdtp, flag, argc, argv); @@ -318,11 +303,11 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, do_reset (cmdtp, flag, argc, argv); } - memmove ((void *)image_get_load (hdr), + memmove ((void *)image_get_load (fdt_hdr), (void *)(of_flat_tree + image_get_header_size ()), - image_get_data_size (hdr)); + image_get_data_size (fdt_hdr)); - of_flat_tree = (char *)image_get_load (hdr); + of_flat_tree = (char *)image_get_load (fdt_hdr); } else { puts ("Did not find a flat Flat Device Tree.\n" "Must RESET the board to recover.\n"); @@ -330,68 +315,52 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, } printf (" Booting using the fdt at 0x%x\n", of_flat_tree); - } else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1]) && (len_ptr[2])) { - u_long tail = image_to_cpu (len_ptr[0]) % 4; - int i; - - /* skip kernel length, initrd length, and terminator */ - of_flat_tree = (char *)(&len_ptr[3]); - /* skip any additional image length fields */ - for (i=2; len_ptr[i]; ++i) - of_flat_tree += 4; - /* add kernel length, and align */ - of_flat_tree += image_to_cpu (len_ptr[0]); - if (tail) { - of_flat_tree += 4 - tail; - } + } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + ulong fdt_data, fdt_len; - /* add initrd length, and align */ - tail = image_to_cpu (len_ptr[1]) % 4; - of_flat_tree += image_to_cpu (len_ptr[1]); - if (tail) { - of_flat_tree += 4 - tail; - } + image_multi_getimg (hdr, 2, &fdt_data, &fdt_len); + if (fdt_len) { + + of_flat_tree = (char *)fdt_data; #ifndef CFG_NO_FLASH - /* move the blob if it is in flash (set of_data to !null) */ - if (addr2info ((ulong)of_flat_tree) != NULL) - of_data = (ulong)of_flat_tree; + /* move the blob if it is in flash (set of_data to !null) */ + if (addr2info ((ulong)of_flat_tree) != NULL) + of_data = (ulong)of_flat_tree; #endif - #if defined(CONFIG_OF_FLAT_TREE) - if (*((ulong *)(of_flat_tree)) != OF_DT_HEADER) { + if (*((ulong *)(of_flat_tree)) != OF_DT_HEADER) { #elif defined(CONFIG_OF_LIBFDT) - if (fdt_check_header (of_flat_tree) != 0) { + if (fdt_check_header (of_flat_tree) != 0) { #endif - puts ("ERROR: image is not a fdt - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } + puts ("ERROR: image is not a fdt - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } #if defined(CONFIG_OF_FLAT_TREE) - if (((struct boot_param_header *)of_flat_tree)->totalsize != - image_to_cpu (len_ptr[2])) { + if (((struct boot_param_header *)of_flat_tree)->totalsize != fdt_len) { #elif defined(CONFIG_OF_LIBFDT) - if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != - image_to_cpu (len_ptr[2])) { + if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != fdt_len) { #endif - puts ("ERROR: fdt size != image size - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); + puts ("ERROR: fdt size != image size - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } } } #endif - if (!data) { + if (!rd_data) { debug ("No initrd\n"); } - if (data) { + if (rd_data) { if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ - initrd_start = data; - initrd_end = initrd_start + len; + initrd_start = rd_data; + initrd_end = initrd_start + rd_len; } else { - initrd_start = (ulong)kbd - len; + initrd_start = (ulong)kbd - rd_len; initrd_start &= ~(4096 - 1); /* align on page */ if (initrd_high) { @@ -412,7 +381,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, nsp &= ~0xF; if (nsp > initrd_high) /* limit as specified */ nsp = initrd_high; - nsp -= len; + nsp -= rd_len; nsp &= ~(4096 - 1); /* align on page */ if (nsp >= sp) initrd_start = nsp; @@ -421,14 +390,14 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, show_boot_progress (12); debug ("## initrd at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - data, data + len - 1, len, len); + rd_data, rd_data + rd_len - 1, rd_len, rd_len); - initrd_end = initrd_start + len; + initrd_end = initrd_start + rd_len; printf (" Loading Ramdisk to %08lx, end %08lx ... ", initrd_start, initrd_end); memmove_wd((void *)initrd_start, - (void *)data, len, CHUNKSZ); + (void *)rd_data, rd_len, CHUNKSZ); puts ("OK\n"); } -- cgit v1.2.1 From 7582438c285bf0cef82909d0f232de64ec567a8a Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:20:06 +0100 Subject: [new uImage] Return error on image move/uncompress overwrites Check for overwrites during image move/uncompress, return with error when the original image gets corrupted. Report clear message to the user and prevent further troubles when pointer to the corrupted images is passed to do_bootm_linux routine. Signed-off-by: Marian Balakowicz --- lib_ppc/ppc_linux.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/ppc_linux.c b/lib_ppc/ppc_linux.c index 0a625fc071..391168787a 100644 --- a/lib_ppc/ppc_linux.c +++ b/lib_ppc/ppc_linux.c @@ -23,6 +23,8 @@ * MA 02111-1307 USA */ +#define DEBUG + #include #include #include @@ -259,11 +261,19 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, of_data = (ulong)of_flat_tree; #endif } else if (image_check_magic (fdt_hdr)) { + ulong image_start, image_end; + ulong load_start, load_end; + printf ("## Flat Device Tree at %08lX\n", fdt_hdr); print_image_hdr (fdt_hdr); - if ((image_get_load (fdt_hdr) < image_get_image_end (fdt_hdr)) && - ((image_get_load (fdt_hdr) + image_get_data_size (fdt_hdr)) > (unsigned long)fdt_hdr)) { + 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)) { puts ("ERROR: fdt overwritten - " "must RESET the board to recover.\n"); do_reset (cmdtp, flag, argc, argv); -- cgit v1.2.1 From 4a995edec1ac163d9326d143ffe2b47e7543407f Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:20:06 +0100 Subject: [new uImage] Rename architecture specific bootm code files Implementation of the do_bootm_linux() and other bootm helper routines is architecture specific code. As such it resides in lib_ directories in files named _linux.c This patch renames those files to a more clear and accurate lib_/bootm.c form. List of the renamed files: lib_arm/armlinux.c -> lib_arm/bootm.c lib_avr32/avr32_linux.c -> lib_avr32/bootm.c lib_blackfin/bf533_linux.c -> lib_blackfin/bootm.c lib_i386/i386_linux.c -> lib_i386/bootm.c lib_m68k/m68k_linux.c -> lib_m68k/bootm.c lib_microblaze/microblaze_linux.c -> lib_microblaze/bootm.c lib_mips/mips_linux.c -> lib_mips/bootm.c lib_nios/nios_linux.c -> lib_nios/bootm.c lib_nios2/nios_linux.c -> lib_nios2/bootm.c lib_ppc/ppc_linux.c -> lib_ppc/bootm.c lib_sh/sh_linux.c -> lib_sh/bootm.c Signed-off-by: Marian Balakowicz --- lib_ppc/Makefile | 2 +- lib_ppc/bootm.c | 554 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lib_ppc/ppc_linux.c | 554 ---------------------------------------------------- 3 files changed, 555 insertions(+), 555 deletions(-) create mode 100644 lib_ppc/bootm.c delete mode 100644 lib_ppc/ppc_linux.c (limited to 'lib_ppc') diff --git a/lib_ppc/Makefile b/lib_ppc/Makefile index 2aa0154856..6845ed0121 100644 --- a/lib_ppc/Makefile +++ b/lib_ppc/Makefile @@ -29,7 +29,7 @@ SOBJS = ppcstring.o ticks.o COBJS = board.o \ bat_rw.o cache.o extable.o kgdb.o time.o interrupts.o \ - ppc_linux.o + bootm.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c new file mode 100644 index 0000000000..391168787a --- /dev/null +++ b/lib_ppc/bootm.c @@ -0,0 +1,554 @@ +/* + * (C) Copyright 2008 Semihalf + * + * (C) Copyright 2000-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#define DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_OF_LIBFDT) +#include +#include +#include +#elif defined(CONFIG_OF_FLAT_TREE) +#include +#endif + +#ifdef CONFIG_LOGBUFFER +#include +#endif + +#ifdef CFG_INIT_RAM_LOCK +#include +#endif + +DECLARE_GLOBAL_DATA_PTR; + +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + +#if defined(CONFIG_CMD_BDI) +extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +#endif + +void __attribute__((noinline)) +do_bootm_linux(cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + image_header_t *hdr, + int verify) +{ + ulong initrd_high; + int initrd_copy_to_ram = 1; + ulong initrd_start, initrd_end; + ulong rd_data, rd_len; + image_header_t *rd_hdr; + + ulong cmd_start, cmd_end; + char *cmdline; + + ulong sp; + char *s; + bd_t *kbd; + void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); + +#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) + image_header_t *fdt_hdr; + 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, + * turning the "load high" feature off. This is intentional. + */ + initrd_high = simple_strtoul(s, NULL, 16); + if (initrd_high == ~0) + initrd_copy_to_ram = 0; + } else { /* not set, no restrictions to load high */ + initrd_high = ~0; + } + +#ifdef CONFIG_LOGBUFFER + kbd=gd->bd; + /* Prevent initrd from overwriting logbuffer */ + if (initrd_high < (kbd->bi_memsize-LOGBUFF_LEN-LOGBUFF_OVERHEAD)) + initrd_high = kbd->bi_memsize-LOGBUFF_LEN-LOGBUFF_OVERHEAD; + debug ("## Logbuffer at 0x%08lX ", kbd->bi_memsize-LOGBUFF_LEN); +#endif + + /* + * Booting a (Linux) kernel image + * + * Allocate space for command line and board info - the + * address should be as high as possible within the reach of + * the kernel (see CFG_BOOTMAPSZ settings), but in unused + * memory, which means far enough below the current stack + * pointer. + */ + + asm( "mr %0,1": "=r"(sp) : ); + + debug ("## Current stack ends at 0x%08lX ", sp); + + sp -= 2048; /* just to be sure */ + if (sp > CFG_BOOTMAPSZ) + sp = CFG_BOOTMAPSZ; + sp &= ~0xF; + + debug ("=> set upper limit to 0x%08lX\n", sp); + + cmdline = (char *)((sp - CFG_BARGSIZE) & ~0xF); + kbd = (bd_t *)(((ulong)cmdline - sizeof(bd_t)) & ~0xF); + + if ((s = getenv("bootargs")) == NULL) + s = ""; + + strcpy (cmdline, s); + + cmd_start = (ulong)&cmdline[0]; + cmd_end = cmd_start + strlen(cmdline); + + *kbd = *(gd->bd); + +#ifdef DEBUG + printf ("## cmdline at 0x%08lX ... 0x%08lX\n", cmd_start, cmd_end); + +#if defined(CONFIG_CMD_BDI) + do_bdinfo (NULL, 0, 0, NULL); +#endif +#endif + + if ((s = getenv ("clocks_in_mhz")) != NULL) { + /* convert all clock information to MHz */ + kbd->bi_intfreq /= 1000000L; + kbd->bi_busfreq /= 1000000L; +#if defined(CONFIG_MPC8220) + kbd->bi_inpfreq /= 1000000L; + kbd->bi_pcifreq /= 1000000L; + kbd->bi_pevfreq /= 1000000L; + kbd->bi_flbfreq /= 1000000L; + kbd->bi_vcofreq /= 1000000L; +#endif +#if defined(CONFIG_CPM2) + kbd->bi_cpmfreq /= 1000000L; + kbd->bi_brgfreq /= 1000000L; + kbd->bi_sccfreq /= 1000000L; + kbd->bi_vco /= 1000000L; +#endif +#if defined(CONFIG_MPC5xxx) + kbd->bi_ipbfreq /= 1000000L; + kbd->bi_pcifreq /= 1000000L; +#endif /* CONFIG_MPC5xxx */ + } + + kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr); + + /* + * Check if there is an initrd image + */ + +#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) + /* Look for a '-' which indicates to ignore the ramdisk argument */ + if (argc >= 3 && strcmp(argv[2], "-") == 0) { + debug ("Skipping initrd\n"); + rd_len = rd_data = 0; + } + else +#endif + if (argc >= 3) { + debug ("Not skipping initrd\n"); + show_boot_progress (9); + + rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); + printf ("## Loading RAMDisk Image at %08lx ...\n", (ulong)rd_hdr); + + if (!image_check_magic (rd_hdr)) { + puts ("Bad Magic Number\n"); + show_boot_progress (-10); + do_reset (cmdtp, flag, argc, argv); + } + + if (!image_check_hcrc (rd_hdr)) { + puts ("Bad Header Checksum\n"); + show_boot_progress (-11); + do_reset (cmdtp, flag, argc, argv); + } + show_boot_progress (10); + + print_image_hdr (rd_hdr); + + if (verify) { + puts (" Verifying Checksum ... "); + + if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) { + puts ("Bad Data CRC\n"); + show_boot_progress (-12); + do_reset (cmdtp, flag, argc, argv); + } + puts ("OK\n"); + } + + show_boot_progress (11); + + if (!image_check_os (rd_hdr, IH_OS_LINUX) || + !image_check_arch (rd_hdr, IH_ARCH_PPC) || + !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { + puts ("No Linux PPC Ramdisk Image\n"); + show_boot_progress (-13); + do_reset (cmdtp, flag, argc, argv); + } + + rd_data = image_get_data (rd_hdr); + rd_len = image_get_data_size (rd_hdr); + + /* + * Now check if we have a multifile image + */ + } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + /* + * Get second entry data start address and len + */ + image_multi_getimg (hdr, 1, &rd_data, &rd_len); + show_boot_progress (13); + } else { + /* + * No initrd image + */ + show_boot_progress (14); + + rd_len = rd_data = 0; + } + +#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) + if(argc > 3) { + of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16); + fdt_hdr = (image_header_t *)of_flat_tree; +#if defined(CONFIG_OF_FLAT_TREE) + if (*((ulong *)(of_flat_tree)) == OF_DT_HEADER) { +#elif defined(CONFIG_OF_LIBFDT) + if (fdt_check_header (of_flat_tree) == 0) { +#endif +#ifndef CFG_NO_FLASH + if (addr2info((ulong)of_flat_tree) != NULL) + of_data = (ulong)of_flat_tree; +#endif + } else if (image_check_magic (fdt_hdr)) { + ulong image_start, image_end; + ulong load_start, load_end; + + printf ("## Flat Device Tree at %08lX\n", fdt_hdr); + print_image_hdr (fdt_hdr); + + 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)) { + puts ("ERROR: fdt overwritten - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + + puts (" Verifying Checksum ... "); + if (!image_check_hcrc (fdt_hdr)) { + puts ("ERROR: fdt header checksum invalid - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + + if (!image_check_dcrc (fdt_hdr)) { + puts ("ERROR: fdt checksum invalid - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + puts ("OK\n"); + + if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) { + puts ("ERROR: uImage is not a fdt - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + if (image_get_comp (fdt_hdr) != IH_COMP_NONE) { + puts ("ERROR: uImage is compressed - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } +#if defined(CONFIG_OF_FLAT_TREE) + if (*((ulong *)(of_flat_tree + image_get_header_size ())) != OF_DT_HEADER) { +#elif defined(CONFIG_OF_LIBFDT) + if (fdt_check_header (of_flat_tree + image_get_header_size ()) != 0) { +#endif + puts ("ERROR: uImage data is not a fdt - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + + memmove ((void *)image_get_load (fdt_hdr), + (void *)(of_flat_tree + image_get_header_size ()), + image_get_data_size (fdt_hdr)); + + of_flat_tree = (char *)image_get_load (fdt_hdr); + } else { + puts ("Did not find a flat Flat Device Tree.\n" + "Must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + printf (" Booting using the fdt at 0x%x\n", + of_flat_tree); + } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + ulong fdt_data, fdt_len; + + image_multi_getimg (hdr, 2, &fdt_data, &fdt_len); + if (fdt_len) { + + of_flat_tree = (char *)fdt_data; + +#ifndef CFG_NO_FLASH + /* move the blob if it is in flash (set of_data to !null) */ + if (addr2info ((ulong)of_flat_tree) != NULL) + of_data = (ulong)of_flat_tree; +#endif + +#if defined(CONFIG_OF_FLAT_TREE) + if (*((ulong *)(of_flat_tree)) != OF_DT_HEADER) { +#elif defined(CONFIG_OF_LIBFDT) + if (fdt_check_header (of_flat_tree) != 0) { +#endif + puts ("ERROR: image is not a fdt - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + +#if defined(CONFIG_OF_FLAT_TREE) + if (((struct boot_param_header *)of_flat_tree)->totalsize != fdt_len) { +#elif defined(CONFIG_OF_LIBFDT) + if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != fdt_len) { +#endif + puts ("ERROR: fdt size != image size - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + } + } +#endif + if (!rd_data) { + debug ("No initrd\n"); + } + + if (rd_data) { + if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ + initrd_start = rd_data; + initrd_end = initrd_start + rd_len; + } else { + initrd_start = (ulong)kbd - rd_len; + initrd_start &= ~(4096 - 1); /* align on page */ + + if (initrd_high) { + ulong nsp; + + /* + * the inital ramdisk does not need to be within + * CFG_BOOTMAPSZ as it is not accessed until after + * the mm system is initialised. + * + * do the stack bottom calculation again and see if + * the initrd will fit just below the monitor stack + * bottom without overwriting the area allocated + * above for command line args and board info. + */ + asm( "mr %0,1": "=r"(nsp) : ); + nsp -= 2048; /* just to be sure */ + nsp &= ~0xF; + if (nsp > initrd_high) /* limit as specified */ + nsp = initrd_high; + nsp -= rd_len; + nsp &= ~(4096 - 1); /* align on page */ + if (nsp >= sp) + initrd_start = nsp; + } + + show_boot_progress (12); + + debug ("## initrd at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", + rd_data, rd_data + rd_len - 1, rd_len, rd_len); + + initrd_end = initrd_start + rd_len; + printf (" Loading Ramdisk to %08lx, end %08lx ... ", + initrd_start, initrd_end); + + memmove_wd((void *)initrd_start, + (void *)rd_data, rd_len, CHUNKSZ); + + puts ("OK\n"); + } + } else { + initrd_start = 0; + initrd_end = 0; + } + +#if defined(CONFIG_OF_LIBFDT) + +#ifdef CFG_BOOTMAPSZ + /* + * The blob must be within CFG_BOOTMAPSZ, + * so we flag it to be copied if it is not. + */ + if (of_flat_tree >= (char *)CFG_BOOTMAPSZ) + of_data = (ulong)of_flat_tree; +#endif + + /* move of_flat_tree if needed */ + if (of_data) { + int err; + ulong of_start, of_len; + + of_len = be32_to_cpu(fdt_totalsize(of_data)); + + /* position on a 4K boundary before the kbd */ + of_start = (ulong)kbd - of_len; + 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); + + 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_data, (void *)of_start, of_len); + if (err != 0) { + puts ("ERROR: fdt move failed - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + puts ("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 (of_flat_tree) { + if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) { + puts ("ERROR: /chosen node create failed - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } +#ifdef CONFIG_OF_HAS_UBOOT_ENV + if (fdt_env(of_flat_tree) < 0) { + puts ("ERROR: /u-boot-env node create failed - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } +#endif +#ifdef CONFIG_OF_HAS_BD_T + if (fdt_bd_t(of_flat_tree) < 0) { + puts ("ERROR: /bd_t node create failed - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } +#endif +#ifdef CONFIG_OF_BOARD_SETUP + /* Call the board-specific fixup routine */ + ft_board_setup(of_flat_tree, gd->bd); +#endif + } + +#elif defined(CONFIG_OF_FLAT_TREE) + +#ifdef CFG_BOOTMAPSZ + /* + * The blob must be within CFG_BOOTMAPSZ, + * so we flag it to be copied if it is not. + */ + if (of_flat_tree >= (char *)CFG_BOOTMAPSZ) + of_data = (ulong)of_flat_tree; +#endif + + /* 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); + + 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); + puts ("OK\n"); + } + /* + * Create the /chosen node and modify the blob with board specific + * values as needed. + */ + ft_setup(of_flat_tree, kbd, initrd_start, initrd_end); + /* ft_dump_blob(of_flat_tree); */ + +#endif /* #if defined(CONFIG_OF_LIBFDT) #elif defined(CONFIG_OF_FLAT_TREE) */ + + 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_FLAT_TREE) || 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 + */ + (*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0); + /* does not return */ + } +#endif + /* + * Linux Kernel Parameters (passing board info data): + * r3: ptr to board info data + * r4: initrd_start or 0 if no initrd + * r5: initrd_end - unused if r4 is 0 + * r6: Start of command line string + * r7: End of command line string + */ + (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); + /* does not return */ +} diff --git a/lib_ppc/ppc_linux.c b/lib_ppc/ppc_linux.c deleted file mode 100644 index 391168787a..0000000000 --- a/lib_ppc/ppc_linux.c +++ /dev/null @@ -1,554 +0,0 @@ -/* - * (C) Copyright 2008 Semihalf - * - * (C) Copyright 2000-2006 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#define DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(CONFIG_OF_LIBFDT) -#include -#include -#include -#elif defined(CONFIG_OF_FLAT_TREE) -#include -#endif - -#ifdef CONFIG_LOGBUFFER -#include -#endif - -#ifdef CFG_INIT_RAM_LOCK -#include -#endif - -DECLARE_GLOBAL_DATA_PTR; - -extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); - -#if defined(CONFIG_CMD_BDI) -extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); -#endif - -void __attribute__((noinline)) -do_bootm_linux(cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - image_header_t *hdr, - int verify) -{ - ulong initrd_high; - int initrd_copy_to_ram = 1; - ulong initrd_start, initrd_end; - ulong rd_data, rd_len; - image_header_t *rd_hdr; - - ulong cmd_start, cmd_end; - char *cmdline; - - ulong sp; - char *s; - bd_t *kbd; - void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); - -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) - image_header_t *fdt_hdr; - 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, - * turning the "load high" feature off. This is intentional. - */ - initrd_high = simple_strtoul(s, NULL, 16); - if (initrd_high == ~0) - initrd_copy_to_ram = 0; - } else { /* not set, no restrictions to load high */ - initrd_high = ~0; - } - -#ifdef CONFIG_LOGBUFFER - kbd=gd->bd; - /* Prevent initrd from overwriting logbuffer */ - if (initrd_high < (kbd->bi_memsize-LOGBUFF_LEN-LOGBUFF_OVERHEAD)) - initrd_high = kbd->bi_memsize-LOGBUFF_LEN-LOGBUFF_OVERHEAD; - debug ("## Logbuffer at 0x%08lX ", kbd->bi_memsize-LOGBUFF_LEN); -#endif - - /* - * Booting a (Linux) kernel image - * - * Allocate space for command line and board info - the - * address should be as high as possible within the reach of - * the kernel (see CFG_BOOTMAPSZ settings), but in unused - * memory, which means far enough below the current stack - * pointer. - */ - - asm( "mr %0,1": "=r"(sp) : ); - - debug ("## Current stack ends at 0x%08lX ", sp); - - sp -= 2048; /* just to be sure */ - if (sp > CFG_BOOTMAPSZ) - sp = CFG_BOOTMAPSZ; - sp &= ~0xF; - - debug ("=> set upper limit to 0x%08lX\n", sp); - - cmdline = (char *)((sp - CFG_BARGSIZE) & ~0xF); - kbd = (bd_t *)(((ulong)cmdline - sizeof(bd_t)) & ~0xF); - - if ((s = getenv("bootargs")) == NULL) - s = ""; - - strcpy (cmdline, s); - - cmd_start = (ulong)&cmdline[0]; - cmd_end = cmd_start + strlen(cmdline); - - *kbd = *(gd->bd); - -#ifdef DEBUG - printf ("## cmdline at 0x%08lX ... 0x%08lX\n", cmd_start, cmd_end); - -#if defined(CONFIG_CMD_BDI) - do_bdinfo (NULL, 0, 0, NULL); -#endif -#endif - - if ((s = getenv ("clocks_in_mhz")) != NULL) { - /* convert all clock information to MHz */ - kbd->bi_intfreq /= 1000000L; - kbd->bi_busfreq /= 1000000L; -#if defined(CONFIG_MPC8220) - kbd->bi_inpfreq /= 1000000L; - kbd->bi_pcifreq /= 1000000L; - kbd->bi_pevfreq /= 1000000L; - kbd->bi_flbfreq /= 1000000L; - kbd->bi_vcofreq /= 1000000L; -#endif -#if defined(CONFIG_CPM2) - kbd->bi_cpmfreq /= 1000000L; - kbd->bi_brgfreq /= 1000000L; - kbd->bi_sccfreq /= 1000000L; - kbd->bi_vco /= 1000000L; -#endif -#if defined(CONFIG_MPC5xxx) - kbd->bi_ipbfreq /= 1000000L; - kbd->bi_pcifreq /= 1000000L; -#endif /* CONFIG_MPC5xxx */ - } - - kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr); - - /* - * Check if there is an initrd image - */ - -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) - /* Look for a '-' which indicates to ignore the ramdisk argument */ - if (argc >= 3 && strcmp(argv[2], "-") == 0) { - debug ("Skipping initrd\n"); - rd_len = rd_data = 0; - } - else -#endif - if (argc >= 3) { - debug ("Not skipping initrd\n"); - show_boot_progress (9); - - rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); - printf ("## Loading RAMDisk Image at %08lx ...\n", (ulong)rd_hdr); - - if (!image_check_magic (rd_hdr)) { - puts ("Bad Magic Number\n"); - show_boot_progress (-10); - do_reset (cmdtp, flag, argc, argv); - } - - if (!image_check_hcrc (rd_hdr)) { - puts ("Bad Header Checksum\n"); - show_boot_progress (-11); - do_reset (cmdtp, flag, argc, argv); - } - show_boot_progress (10); - - print_image_hdr (rd_hdr); - - if (verify) { - puts (" Verifying Checksum ... "); - - if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) { - puts ("Bad Data CRC\n"); - show_boot_progress (-12); - do_reset (cmdtp, flag, argc, argv); - } - puts ("OK\n"); - } - - show_boot_progress (11); - - if (!image_check_os (rd_hdr, IH_OS_LINUX) || - !image_check_arch (rd_hdr, IH_ARCH_PPC) || - !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { - puts ("No Linux PPC Ramdisk Image\n"); - show_boot_progress (-13); - do_reset (cmdtp, flag, argc, argv); - } - - rd_data = image_get_data (rd_hdr); - rd_len = image_get_data_size (rd_hdr); - - /* - * Now check if we have a multifile image - */ - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { - /* - * Get second entry data start address and len - */ - image_multi_getimg (hdr, 1, &rd_data, &rd_len); - show_boot_progress (13); - } else { - /* - * No initrd image - */ - show_boot_progress (14); - - rd_len = rd_data = 0; - } - -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) - if(argc > 3) { - of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16); - fdt_hdr = (image_header_t *)of_flat_tree; -#if defined(CONFIG_OF_FLAT_TREE) - if (*((ulong *)(of_flat_tree)) == OF_DT_HEADER) { -#elif defined(CONFIG_OF_LIBFDT) - if (fdt_check_header (of_flat_tree) == 0) { -#endif -#ifndef CFG_NO_FLASH - if (addr2info((ulong)of_flat_tree) != NULL) - of_data = (ulong)of_flat_tree; -#endif - } else if (image_check_magic (fdt_hdr)) { - ulong image_start, image_end; - ulong load_start, load_end; - - printf ("## Flat Device Tree at %08lX\n", fdt_hdr); - print_image_hdr (fdt_hdr); - - 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)) { - puts ("ERROR: fdt overwritten - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - - puts (" Verifying Checksum ... "); - if (!image_check_hcrc (fdt_hdr)) { - puts ("ERROR: fdt header checksum invalid - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - - if (!image_check_dcrc (fdt_hdr)) { - puts ("ERROR: fdt checksum invalid - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - puts ("OK\n"); - - if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) { - puts ("ERROR: uImage is not a fdt - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - if (image_get_comp (fdt_hdr) != IH_COMP_NONE) { - puts ("ERROR: uImage is compressed - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } -#if defined(CONFIG_OF_FLAT_TREE) - if (*((ulong *)(of_flat_tree + image_get_header_size ())) != OF_DT_HEADER) { -#elif defined(CONFIG_OF_LIBFDT) - if (fdt_check_header (of_flat_tree + image_get_header_size ()) != 0) { -#endif - puts ("ERROR: uImage data is not a fdt - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - - memmove ((void *)image_get_load (fdt_hdr), - (void *)(of_flat_tree + image_get_header_size ()), - image_get_data_size (fdt_hdr)); - - of_flat_tree = (char *)image_get_load (fdt_hdr); - } else { - puts ("Did not find a flat Flat Device Tree.\n" - "Must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - printf (" Booting using the fdt at 0x%x\n", - of_flat_tree); - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { - ulong fdt_data, fdt_len; - - image_multi_getimg (hdr, 2, &fdt_data, &fdt_len); - if (fdt_len) { - - of_flat_tree = (char *)fdt_data; - -#ifndef CFG_NO_FLASH - /* move the blob if it is in flash (set of_data to !null) */ - if (addr2info ((ulong)of_flat_tree) != NULL) - of_data = (ulong)of_flat_tree; -#endif - -#if defined(CONFIG_OF_FLAT_TREE) - if (*((ulong *)(of_flat_tree)) != OF_DT_HEADER) { -#elif defined(CONFIG_OF_LIBFDT) - if (fdt_check_header (of_flat_tree) != 0) { -#endif - puts ("ERROR: image is not a fdt - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - -#if defined(CONFIG_OF_FLAT_TREE) - if (((struct boot_param_header *)of_flat_tree)->totalsize != fdt_len) { -#elif defined(CONFIG_OF_LIBFDT) - if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != fdt_len) { -#endif - puts ("ERROR: fdt size != image size - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - } - } -#endif - if (!rd_data) { - debug ("No initrd\n"); - } - - if (rd_data) { - if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ - initrd_start = rd_data; - initrd_end = initrd_start + rd_len; - } else { - initrd_start = (ulong)kbd - rd_len; - initrd_start &= ~(4096 - 1); /* align on page */ - - if (initrd_high) { - ulong nsp; - - /* - * the inital ramdisk does not need to be within - * CFG_BOOTMAPSZ as it is not accessed until after - * the mm system is initialised. - * - * do the stack bottom calculation again and see if - * the initrd will fit just below the monitor stack - * bottom without overwriting the area allocated - * above for command line args and board info. - */ - asm( "mr %0,1": "=r"(nsp) : ); - nsp -= 2048; /* just to be sure */ - nsp &= ~0xF; - if (nsp > initrd_high) /* limit as specified */ - nsp = initrd_high; - nsp -= rd_len; - nsp &= ~(4096 - 1); /* align on page */ - if (nsp >= sp) - initrd_start = nsp; - } - - show_boot_progress (12); - - debug ("## initrd at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - rd_data, rd_data + rd_len - 1, rd_len, rd_len); - - initrd_end = initrd_start + rd_len; - printf (" Loading Ramdisk to %08lx, end %08lx ... ", - initrd_start, initrd_end); - - memmove_wd((void *)initrd_start, - (void *)rd_data, rd_len, CHUNKSZ); - - puts ("OK\n"); - } - } else { - initrd_start = 0; - initrd_end = 0; - } - -#if defined(CONFIG_OF_LIBFDT) - -#ifdef CFG_BOOTMAPSZ - /* - * The blob must be within CFG_BOOTMAPSZ, - * so we flag it to be copied if it is not. - */ - if (of_flat_tree >= (char *)CFG_BOOTMAPSZ) - of_data = (ulong)of_flat_tree; -#endif - - /* move of_flat_tree if needed */ - if (of_data) { - int err; - ulong of_start, of_len; - - of_len = be32_to_cpu(fdt_totalsize(of_data)); - - /* position on a 4K boundary before the kbd */ - of_start = (ulong)kbd - of_len; - 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); - - 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_data, (void *)of_start, of_len); - if (err != 0) { - puts ("ERROR: fdt move failed - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - puts ("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 (of_flat_tree) { - if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) { - puts ("ERROR: /chosen node create failed - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } -#ifdef CONFIG_OF_HAS_UBOOT_ENV - if (fdt_env(of_flat_tree) < 0) { - puts ("ERROR: /u-boot-env node create failed - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } -#endif -#ifdef CONFIG_OF_HAS_BD_T - if (fdt_bd_t(of_flat_tree) < 0) { - puts ("ERROR: /bd_t node create failed - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } -#endif -#ifdef CONFIG_OF_BOARD_SETUP - /* Call the board-specific fixup routine */ - ft_board_setup(of_flat_tree, gd->bd); -#endif - } - -#elif defined(CONFIG_OF_FLAT_TREE) - -#ifdef CFG_BOOTMAPSZ - /* - * The blob must be within CFG_BOOTMAPSZ, - * so we flag it to be copied if it is not. - */ - if (of_flat_tree >= (char *)CFG_BOOTMAPSZ) - of_data = (ulong)of_flat_tree; -#endif - - /* 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); - - 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); - puts ("OK\n"); - } - /* - * Create the /chosen node and modify the blob with board specific - * values as needed. - */ - ft_setup(of_flat_tree, kbd, initrd_start, initrd_end); - /* ft_dump_blob(of_flat_tree); */ - -#endif /* #if defined(CONFIG_OF_LIBFDT) #elif defined(CONFIG_OF_FLAT_TREE) */ - - 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_FLAT_TREE) || 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 - */ - (*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0); - /* does not return */ - } -#endif - /* - * Linux Kernel Parameters (passing board info data): - * r3: ptr to board info data - * r4: initrd_start or 0 if no initrd - * r5: initrd_end - unused if r4 is 0 - * r6: Start of command line string - * r7: End of command line string - */ - (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); - /* does not return */ -} -- cgit v1.2.1 From 4a2ad5ff6400698433dd7203d34939c3c9cc9bff Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:20:07 +0100 Subject: [new uImage] Remove OF_FLAT_TREE support from PPC bootm code Support for OF_FLAT_TREE is to be obsoleted in the near future, remove related code from the bootm routines. Signed-off-by: Marian Balakowicz --- lib_ppc/bootm.c | 65 ++++++--------------------------------------------------- 1 file changed, 6 insertions(+), 59 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 391168787a..16b2f3804e 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -39,8 +39,6 @@ #include #include #include -#elif defined(CONFIG_OF_FLAT_TREE) -#include #endif #ifdef CONFIG_LOGBUFFER @@ -79,7 +77,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, bd_t *kbd; void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) +#if defined(CONFIG_OF_LIBFDT) image_header_t *fdt_hdr; char *of_flat_tree = NULL; ulong of_data = 0; @@ -175,7 +173,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, * Check if there is an initrd image */ -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) +#if defined(CONFIG_OF_LIBFDT) /* Look for a '-' which indicates to ignore the ramdisk argument */ if (argc >= 3 && strcmp(argv[2], "-") == 0) { debug ("Skipping initrd\n"); @@ -247,15 +245,12 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, rd_len = rd_data = 0; } -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) +#if defined(CONFIG_OF_LIBFDT) if(argc > 3) { of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16); fdt_hdr = (image_header_t *)of_flat_tree; -#if defined(CONFIG_OF_FLAT_TREE) - if (*((ulong *)(of_flat_tree)) == OF_DT_HEADER) { -#elif defined(CONFIG_OF_LIBFDT) + if (fdt_check_header (of_flat_tree) == 0) { -#endif #ifndef CFG_NO_FLASH if (addr2info((ulong)of_flat_tree) != NULL) of_data = (ulong)of_flat_tree; @@ -303,11 +298,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, "must RESET the board to recover.\n"); do_reset (cmdtp, flag, argc, argv); } -#if defined(CONFIG_OF_FLAT_TREE) - if (*((ulong *)(of_flat_tree + image_get_header_size ())) != OF_DT_HEADER) { -#elif defined(CONFIG_OF_LIBFDT) if (fdt_check_header (of_flat_tree + image_get_header_size ()) != 0) { -#endif puts ("ERROR: uImage data is not a fdt - " "must RESET the board to recover.\n"); do_reset (cmdtp, flag, argc, argv); @@ -339,21 +330,13 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, of_data = (ulong)of_flat_tree; #endif -#if defined(CONFIG_OF_FLAT_TREE) - if (*((ulong *)(of_flat_tree)) != OF_DT_HEADER) { -#elif defined(CONFIG_OF_LIBFDT) if (fdt_check_header (of_flat_tree) != 0) { -#endif puts ("ERROR: image is not a fdt - " "must RESET the board to recover.\n"); do_reset (cmdtp, flag, argc, argv); } -#if defined(CONFIG_OF_FLAT_TREE) - if (((struct boot_param_header *)of_flat_tree)->totalsize != fdt_len) { -#elif defined(CONFIG_OF_LIBFDT) if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != fdt_len) { -#endif puts ("ERROR: fdt size != image size - " "must RESET the board to recover.\n"); do_reset (cmdtp, flag, argc, argv); @@ -480,43 +463,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, ft_board_setup(of_flat_tree, gd->bd); #endif } - -#elif defined(CONFIG_OF_FLAT_TREE) - -#ifdef CFG_BOOTMAPSZ - /* - * The blob must be within CFG_BOOTMAPSZ, - * so we flag it to be copied if it is not. - */ - if (of_flat_tree >= (char *)CFG_BOOTMAPSZ) - of_data = (ulong)of_flat_tree; -#endif - - /* 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); - - 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); - puts ("OK\n"); - } - /* - * Create the /chosen node and modify the blob with board specific - * values as needed. - */ - ft_setup(of_flat_tree, kbd, initrd_start, initrd_end); - /* ft_dump_blob(of_flat_tree); */ - -#endif /* #if defined(CONFIG_OF_LIBFDT) #elif defined(CONFIG_OF_FLAT_TREE) */ +#endif /* CONFIG_OF_LIBFDT */ debug ("## Transferring control to Linux (at address %08lx) ...\n", (ulong)kernel); @@ -527,7 +474,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, unlock_ram_in_cache(); #endif -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) +#if defined(CONFIG_OF_LIBFDT) if (of_flat_tree) { /* device tree; boot new style */ /* * Linux Kernel Parameters (passing device tree): -- cgit v1.2.1 From d3c5eb6dd1f4ed3c3388386cf1d1bf82aa51d56b Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:20:08 +0100 Subject: [new uImage] Move FDT error printing to common fdt_error() routine FDT error handling in PPC do_bootm_linux() shares the same message format. This patch moves error message printing to a helper fdt_error() routine. Signed-off-by: Marian Balakowicz Acked-by: Gerald Van Baren --- lib_ppc/bootm.c | 50 ++++++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 26 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 16b2f3804e..36e67763b9 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -39,6 +39,8 @@ #include #include #include + +static void fdt_error (const char *msg); #endif #ifdef CONFIG_LOGBUFFER @@ -269,38 +271,32 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, load_end = load_start + image_get_data_size (fdt_hdr); if ((load_start < image_end) && (load_end > image_start)) { - puts ("ERROR: fdt overwritten - " - "must RESET the board to recover.\n"); + fdt_error ("fdt overwritten"); do_reset (cmdtp, flag, argc, argv); } puts (" Verifying Checksum ... "); if (!image_check_hcrc (fdt_hdr)) { - puts ("ERROR: fdt header checksum invalid - " - "must RESET the board to recover.\n"); + fdt_error ("fdt header checksum invalid"); do_reset (cmdtp, flag, argc, argv); } if (!image_check_dcrc (fdt_hdr)) { - puts ("ERROR: fdt checksum invalid - " - "must RESET the board to recover.\n"); + fdt_error ("fdt checksum invalid"); do_reset (cmdtp, flag, argc, argv); } puts ("OK\n"); if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) { - puts ("ERROR: uImage is not a fdt - " - "must RESET the board to recover.\n"); + fdt_error ("uImage is not a fdt"); do_reset (cmdtp, flag, argc, argv); } if (image_get_comp (fdt_hdr) != IH_COMP_NONE) { - puts ("ERROR: uImage is compressed - " - "must RESET the board to recover.\n"); + fdt_error ("uImage is compressed"); do_reset (cmdtp, flag, argc, argv); } if (fdt_check_header (of_flat_tree + image_get_header_size ()) != 0) { - puts ("ERROR: uImage data is not a fdt - " - "must RESET the board to recover.\n"); + fdt_error ("uImage data is not a fdt"); do_reset (cmdtp, flag, argc, argv); } @@ -310,8 +306,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, of_flat_tree = (char *)image_get_load (fdt_hdr); } else { - puts ("Did not find a flat Flat Device Tree.\n" - "Must RESET the board to recover.\n"); + fdt_error ("Did not find a Flattened Device Tree"); do_reset (cmdtp, flag, argc, argv); } printf (" Booting using the fdt at 0x%x\n", @@ -331,14 +326,12 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, #endif if (fdt_check_header (of_flat_tree) != 0) { - puts ("ERROR: image is not a fdt - " - "must RESET the board to recover.\n"); + fdt_error ("image is not a fdt"); do_reset (cmdtp, flag, argc, argv); } if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != fdt_len) { - puts ("ERROR: fdt size != image size - " - "must RESET the board to recover.\n"); + fdt_error ("fdt size != image size"); do_reset (cmdtp, flag, argc, argv); } } @@ -428,8 +421,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, of_start, of_start + of_len - 1); err = fdt_open_into((void *)of_data, (void *)of_start, of_len); if (err != 0) { - puts ("ERROR: fdt move failed - " - "must RESET the board to recover.\n"); + fdt_error ("fdt move failed"); do_reset (cmdtp, flag, argc, argv); } puts ("OK\n"); @@ -440,21 +432,18 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, */ if (of_flat_tree) { if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) { - puts ("ERROR: /chosen node create failed - " - "must RESET the board to recover.\n"); + fdt_error ("/chosen node create failed"); do_reset (cmdtp, flag, argc, argv); } #ifdef CONFIG_OF_HAS_UBOOT_ENV if (fdt_env(of_flat_tree) < 0) { - puts ("ERROR: /u-boot-env node create failed - " - "must RESET the board to recover.\n"); + fdt_error ("/u-boot-env node create failed"); do_reset (cmdtp, flag, argc, argv); } #endif #ifdef CONFIG_OF_HAS_BD_T if (fdt_bd_t(of_flat_tree) < 0) { - puts ("ERROR: /bd_t node create failed - " - "must RESET the board to recover.\n"); + fdt_error ("/bd_t node create failed"); do_reset (cmdtp, flag, argc, argv); } #endif @@ -499,3 +488,12 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); /* does not return */ } + +#if defined(CONFIG_OF_LIBFDT) +static void fdt_error (const char *msg) +{ + puts ("ERROR: "); + puts (msg); + puts (" - must RESET the board to recover.\n"); +} +#endif -- cgit v1.2.1 From 5ad03eb3854c162684222a718b44c0716ea0db03 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:55:39 +0100 Subject: [new uImage] Factor out common image_get_ramdisk() routine Architecture specific do_bootm_linux() routines share common ramdisk image processing code. Move this code to a common helper routine. Signed-off-by: Marian Balakowicz --- lib_ppc/bootm.c | 94 ++++++--------------------------------------------------- 1 file changed, 9 insertions(+), 85 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 36e67763b9..65edcdb588 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -68,8 +68,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, ulong initrd_high; int initrd_copy_to_ram = 1; ulong initrd_start, initrd_end; - ulong rd_data, rd_len; - image_header_t *rd_hdr; + ulong rd_data_start, rd_data_end, rd_len; ulong cmd_start, cmd_end; char *cmdline; @@ -171,81 +170,9 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr); - /* - * Check if there is an initrd image - */ - -#if defined(CONFIG_OF_LIBFDT) - /* Look for a '-' which indicates to ignore the ramdisk argument */ - if (argc >= 3 && strcmp(argv[2], "-") == 0) { - debug ("Skipping initrd\n"); - rd_len = rd_data = 0; - } - else -#endif - if (argc >= 3) { - debug ("Not skipping initrd\n"); - show_boot_progress (9); - - rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); - printf ("## Loading RAMDisk Image at %08lx ...\n", (ulong)rd_hdr); - - if (!image_check_magic (rd_hdr)) { - puts ("Bad Magic Number\n"); - show_boot_progress (-10); - do_reset (cmdtp, flag, argc, argv); - } - - if (!image_check_hcrc (rd_hdr)) { - puts ("Bad Header Checksum\n"); - show_boot_progress (-11); - do_reset (cmdtp, flag, argc, argv); - } - show_boot_progress (10); - - print_image_hdr (rd_hdr); - - if (verify) { - puts (" Verifying Checksum ... "); - - if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) { - puts ("Bad Data CRC\n"); - show_boot_progress (-12); - do_reset (cmdtp, flag, argc, argv); - } - puts ("OK\n"); - } - - show_boot_progress (11); - - if (!image_check_os (rd_hdr, IH_OS_LINUX) || - !image_check_arch (rd_hdr, IH_ARCH_PPC) || - !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { - puts ("No Linux PPC Ramdisk Image\n"); - show_boot_progress (-13); - do_reset (cmdtp, flag, argc, argv); - } - - rd_data = image_get_data (rd_hdr); - rd_len = image_get_data_size (rd_hdr); - - /* - * Now check if we have a multifile image - */ - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { - /* - * Get second entry data start address and len - */ - image_multi_getimg (hdr, 1, &rd_data, &rd_len); - show_boot_progress (13); - } else { - /* - * No initrd image - */ - show_boot_progress (14); - - rd_len = rd_data = 0; - } + get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, + IH_ARCH_PPC, &rd_data_start, &rd_data_end); + rd_len = rd_data_end - rd_data_start; #if defined(CONFIG_OF_LIBFDT) if(argc > 3) { @@ -337,14 +264,11 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, } } #endif - if (!rd_data) { - debug ("No initrd\n"); - } - if (rd_data) { + if (rd_data_start) { if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ - initrd_start = rd_data; - initrd_end = initrd_start + rd_len; + initrd_start = rd_data_start; + initrd_end = rd_data_end; } else { initrd_start = (ulong)kbd - rd_len; initrd_start &= ~(4096 - 1); /* align on page */ @@ -376,14 +300,14 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, show_boot_progress (12); debug ("## initrd at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - rd_data, rd_data + rd_len - 1, rd_len, rd_len); + rd_data_start, rd_data_end - 1, rd_len, rd_len); initrd_end = initrd_start + rd_len; printf (" Loading Ramdisk to %08lx, end %08lx ... ", initrd_start, initrd_end); memmove_wd((void *)initrd_start, - (void *)rd_data, rd_len, CHUNKSZ); + (void *)rd_data_start, rd_len, CHUNKSZ); puts ("OK\n"); } -- cgit v1.2.1 From ceaed2b1e54ebf14d600e02fef016c8df5cc4d40 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:57:17 +0100 Subject: [new uImage] Move ramdisk loading to a common routine Ramdisk loading code, including initrd_high variable handling, was duplicated for PPC and M68K platforms. This patch creates common helper routine that is being called from both platform do_bootm_linux() routines. Signed-off-by: Marian Balakowicz --- lib_ppc/bootm.c | 112 +++++++++++++------------------------------------------- 1 file changed, 26 insertions(+), 86 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 65edcdb588..d73d2fda79 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -43,10 +43,6 @@ static void fdt_error (const char *msg); #endif -#ifdef CONFIG_LOGBUFFER -#include -#endif - #ifdef CFG_INIT_RAM_LOCK #include #endif @@ -54,9 +50,10 @@ static void fdt_error (const char *msg); DECLARE_GLOBAL_DATA_PTR; extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +static ulong get_sp (void); #if defined(CONFIG_CMD_BDI) -extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +extern int do_bdinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #endif void __attribute__((noinline)) @@ -65,15 +62,13 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, image_header_t *hdr, int verify) { - ulong initrd_high; - int initrd_copy_to_ram = 1; ulong initrd_start, initrd_end; ulong rd_data_start, rd_data_end, rd_len; ulong cmd_start, cmd_end; char *cmdline; - ulong sp; + ulong sp_limit; char *s; bd_t *kbd; void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); @@ -84,25 +79,6 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, ulong of_data = 0; #endif - if ((s = getenv ("initrd_high")) != NULL) { - /* a value of "no" or a similar string will act like 0, - * turning the "load high" feature off. This is intentional. - */ - initrd_high = simple_strtoul(s, NULL, 16); - if (initrd_high == ~0) - initrd_copy_to_ram = 0; - } else { /* not set, no restrictions to load high */ - initrd_high = ~0; - } - -#ifdef CONFIG_LOGBUFFER - kbd=gd->bd; - /* Prevent initrd from overwriting logbuffer */ - if (initrd_high < (kbd->bi_memsize-LOGBUFF_LEN-LOGBUFF_OVERHEAD)) - initrd_high = kbd->bi_memsize-LOGBUFF_LEN-LOGBUFF_OVERHEAD; - debug ("## Logbuffer at 0x%08lX ", kbd->bi_memsize-LOGBUFF_LEN); -#endif - /* * Booting a (Linux) kernel image * @@ -113,18 +89,17 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, * pointer. */ - asm( "mr %0,1": "=r"(sp) : ); - - debug ("## Current stack ends at 0x%08lX ", sp); + sp_limit = get_sp(); + debug ("## Current stack ends at 0x%08lX ", sp_limit); - sp -= 2048; /* just to be sure */ - if (sp > CFG_BOOTMAPSZ) - sp = CFG_BOOTMAPSZ; - sp &= ~0xF; + sp_limit -= 2048; /* just to be sure */ + if (sp_limit > CFG_BOOTMAPSZ) + sp_limit = CFG_BOOTMAPSZ; + sp_limit &= ~0xF; - debug ("=> set upper limit to 0x%08lX\n", sp); + debug ("=> set upper limit to 0x%08lX\n", sp_limit); - cmdline = (char *)((sp - CFG_BARGSIZE) & ~0xF); + cmdline = (char *)((sp_limit - CFG_BARGSIZE) & ~0xF); kbd = (bd_t *)(((ulong)cmdline - sizeof(bd_t)) & ~0xF); if ((s = getenv("bootargs")) == NULL) @@ -168,13 +143,20 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, #endif /* CONFIG_MPC5xxx */ } + /* find kernel */ kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr); + /* find ramdisk */ get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, IH_ARCH_PPC, &rd_data_start, &rd_data_end); + rd_len = rd_data_end - rd_data_start; + ramdisk_high (rd_data_start, rd_len, kbd, sp_limit, get_sp (), + &initrd_start, &initrd_end); + #if defined(CONFIG_OF_LIBFDT) + /* find flattened device tree */ if(argc > 3) { of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16); fdt_hdr = (image_header_t *)of_flat_tree; @@ -265,56 +247,6 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, } #endif - if (rd_data_start) { - if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ - initrd_start = rd_data_start; - initrd_end = rd_data_end; - } else { - initrd_start = (ulong)kbd - rd_len; - initrd_start &= ~(4096 - 1); /* align on page */ - - if (initrd_high) { - ulong nsp; - - /* - * the inital ramdisk does not need to be within - * CFG_BOOTMAPSZ as it is not accessed until after - * the mm system is initialised. - * - * do the stack bottom calculation again and see if - * the initrd will fit just below the monitor stack - * bottom without overwriting the area allocated - * above for command line args and board info. - */ - asm( "mr %0,1": "=r"(nsp) : ); - nsp -= 2048; /* just to be sure */ - nsp &= ~0xF; - if (nsp > initrd_high) /* limit as specified */ - nsp = initrd_high; - nsp -= rd_len; - nsp &= ~(4096 - 1); /* align on page */ - if (nsp >= sp) - initrd_start = nsp; - } - - show_boot_progress (12); - - debug ("## initrd at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - rd_data_start, rd_data_end - 1, rd_len, rd_len); - - initrd_end = initrd_start + rd_len; - printf (" Loading Ramdisk to %08lx, end %08lx ... ", - initrd_start, initrd_end); - - memmove_wd((void *)initrd_start, - (void *)rd_data_start, rd_len, CHUNKSZ); - - puts ("OK\n"); - } - } else { - initrd_start = 0; - initrd_end = 0; - } #if defined(CONFIG_OF_LIBFDT) @@ -413,6 +345,14 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, /* does not return */ } +static ulong get_sp (void) +{ + ulong sp; + + asm( "mr %0,1": "=r"(sp) : ); + return sp; +} + #if defined(CONFIG_OF_LIBFDT) static void fdt_error (const char *msg) { -- cgit v1.2.1 From b6b0fe6460b7063ac60b9a3531ef210aedb31451 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:58:13 +0100 Subject: [new uImage] Cleanup do_botm_linux() boot allocations This patch moves common pre-boot allocation steps shared between PPC and M68K to a helper routines: common: - get_boot_sp_limit() - get_boot_cmline() - get_boot_kbd() platform: - set_clocks_in_mhz() Signed-off-by: Marian Balakowicz --- lib_ppc/bootm.c | 106 +++++++++++++++++++++++--------------------------------- 1 file changed, 44 insertions(+), 62 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index d73d2fda79..7eb8712102 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -51,10 +51,7 @@ DECLARE_GLOBAL_DATA_PTR; extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); static ulong get_sp (void); - -#if defined(CONFIG_CMD_BDI) -extern int do_bdinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); -#endif +static void set_clocks_in_mhz (bd_t *kbd); void __attribute__((noinline)) do_bootm_linux(cmd_tbl_t *cmdtp, int flag, @@ -62,14 +59,12 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, image_header_t *hdr, int verify) { + ulong sp, sp_limit, alloc_current; + ulong initrd_start, initrd_end; ulong rd_data_start, rd_data_end, rd_len; ulong cmd_start, cmd_end; - char *cmdline; - - ulong sp_limit; - char *s; bd_t *kbd; void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); @@ -88,60 +83,18 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, * memory, which means far enough below the current stack * pointer. */ + sp = get_sp(); + debug ("## Current stack ends at 0x%08lx ", sp); - sp_limit = get_sp(); - debug ("## Current stack ends at 0x%08lX ", sp_limit); - - sp_limit -= 2048; /* just to be sure */ - if (sp_limit > CFG_BOOTMAPSZ) - sp_limit = CFG_BOOTMAPSZ; - sp_limit &= ~0xF; - - debug ("=> set upper limit to 0x%08lX\n", sp_limit); + alloc_current = sp_limit = get_boot_sp_limit(sp); + debug ("=> set upper limit to 0x%08lx\n", sp_limit); - cmdline = (char *)((sp_limit - CFG_BARGSIZE) & ~0xF); - kbd = (bd_t *)(((ulong)cmdline - sizeof(bd_t)) & ~0xF); + /* allocate space and init command line */ + alloc_current = get_boot_cmdline (alloc_current, &cmd_start, &cmd_end); - if ((s = getenv("bootargs")) == NULL) - s = ""; - - strcpy (cmdline, s); - - cmd_start = (ulong)&cmdline[0]; - cmd_end = cmd_start + strlen(cmdline); - - *kbd = *(gd->bd); - -#ifdef DEBUG - printf ("## cmdline at 0x%08lX ... 0x%08lX\n", cmd_start, cmd_end); - -#if defined(CONFIG_CMD_BDI) - do_bdinfo (NULL, 0, 0, NULL); -#endif -#endif - - if ((s = getenv ("clocks_in_mhz")) != NULL) { - /* convert all clock information to MHz */ - kbd->bi_intfreq /= 1000000L; - kbd->bi_busfreq /= 1000000L; -#if defined(CONFIG_MPC8220) - kbd->bi_inpfreq /= 1000000L; - kbd->bi_pcifreq /= 1000000L; - kbd->bi_pevfreq /= 1000000L; - kbd->bi_flbfreq /= 1000000L; - kbd->bi_vcofreq /= 1000000L; -#endif -#if defined(CONFIG_CPM2) - kbd->bi_cpmfreq /= 1000000L; - kbd->bi_brgfreq /= 1000000L; - kbd->bi_sccfreq /= 1000000L; - kbd->bi_vco /= 1000000L; -#endif -#if defined(CONFIG_MPC5xxx) - kbd->bi_ipbfreq /= 1000000L; - kbd->bi_pcifreq /= 1000000L; -#endif /* CONFIG_MPC5xxx */ - } + /* allocate space for kernel copy of board info */ + alloc_current = get_boot_kbd (alloc_current, &kbd); + set_clocks_in_mhz(kbd); /* find kernel */ kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr); @@ -152,7 +105,8 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, rd_len = rd_data_end - rd_data_start; - ramdisk_high (rd_data_start, rd_len, kbd, sp_limit, get_sp (), + alloc_current = ramdisk_high (alloc_current, rd_data_start, rd_len, + kbd, sp_limit, get_sp (), &initrd_start, &initrd_end); #if defined(CONFIG_OF_LIBFDT) @@ -266,8 +220,8 @@ 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 kbd */ - of_start = (ulong)kbd - of_len; + /* position on a 4K boundary before the alloc_current */ + of_start = alloc_current - of_len; 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); @@ -353,6 +307,34 @@ static ulong get_sp (void) return sp; } +static void set_clocks_in_mhz (bd_t *kbd) +{ + char *s; + + if ((s = getenv ("clocks_in_mhz")) != NULL) { + /* convert all clock information to MHz */ + kbd->bi_intfreq /= 1000000L; + kbd->bi_busfreq /= 1000000L; +#if defined(CONFIG_MPC8220) + kbd->bi_inpfreq /= 1000000L; + kbd->bi_pcifreq /= 1000000L; + kbd->bi_pevfreq /= 1000000L; + kbd->bi_flbfreq /= 1000000L; + kbd->bi_vcofreq /= 1000000L; +#endif +#if defined(CONFIG_CPM2) + kbd->bi_cpmfreq /= 1000000L; + kbd->bi_brgfreq /= 1000000L; + kbd->bi_sccfreq /= 1000000L; + kbd->bi_vco /= 1000000L; +#endif +#if defined(CONFIG_MPC5xxx) + kbd->bi_ipbfreq /= 1000000L; + kbd->bi_pcifreq /= 1000000L; +#endif /* CONFIG_MPC5xxx */ + } +} + #if defined(CONFIG_OF_LIBFDT) static void fdt_error (const char *msg) { -- cgit v1.2.1 From 7b325454fd231d4273de3fe373850f777fb086bf Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:58:20 +0100 Subject: [new uImage] Cleanup FDT handling in PPC do_boot_linux() Move FDT blob finding and relocation to a dedicated get_fdt() routine. It increases code readability and will make adding support for new uImage format easier. Signed-off-by: Marian Balakowicz --- lib_ppc/bootm.c | 285 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 158 insertions(+), 127 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 7eb8712102..69ec459105 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -41,6 +41,9 @@ #include static void fdt_error (const char *msg); +static ulong get_fdt (ulong alloc_current, cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + image_header_t *hdr, char **of_flat_tree); #endif #ifdef CFG_INIT_RAM_LOCK @@ -69,9 +72,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); #if defined(CONFIG_OF_LIBFDT) - image_header_t *fdt_hdr; - char *of_flat_tree = NULL; - ulong of_data = 0; + char *of_flat_tree; #endif /* @@ -111,131 +112,9 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, #if defined(CONFIG_OF_LIBFDT) /* find flattened device tree */ - if(argc > 3) { - of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16); - fdt_hdr = (image_header_t *)of_flat_tree; - - if (fdt_check_header (of_flat_tree) == 0) { -#ifndef CFG_NO_FLASH - if (addr2info((ulong)of_flat_tree) != NULL) - of_data = (ulong)of_flat_tree; -#endif - } else if (image_check_magic (fdt_hdr)) { - ulong image_start, image_end; - ulong load_start, load_end; - - printf ("## Flat Device Tree at %08lX\n", fdt_hdr); - print_image_hdr (fdt_hdr); - - 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"); - do_reset (cmdtp, flag, argc, argv); - } - - puts (" Verifying Checksum ... "); - if (!image_check_hcrc (fdt_hdr)) { - fdt_error ("fdt header checksum invalid"); - do_reset (cmdtp, flag, argc, argv); - } - - if (!image_check_dcrc (fdt_hdr)) { - fdt_error ("fdt checksum invalid"); - do_reset (cmdtp, flag, argc, argv); - } - puts ("OK\n"); - - if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) { - fdt_error ("uImage is not a fdt"); - do_reset (cmdtp, flag, argc, argv); - } - if (image_get_comp (fdt_hdr) != IH_COMP_NONE) { - fdt_error ("uImage is compressed"); - do_reset (cmdtp, flag, argc, argv); - } - if (fdt_check_header (of_flat_tree + image_get_header_size ()) != 0) { - fdt_error ("uImage data is not a fdt"); - do_reset (cmdtp, flag, argc, argv); - } - - memmove ((void *)image_get_load (fdt_hdr), - (void *)(of_flat_tree + image_get_header_size ()), - image_get_data_size (fdt_hdr)); - - of_flat_tree = (char *)image_get_load (fdt_hdr); - } else { - fdt_error ("Did not find a Flattened Device Tree"); - do_reset (cmdtp, flag, argc, argv); - } - printf (" Booting using the fdt at 0x%x\n", - of_flat_tree); - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { - ulong fdt_data, fdt_len; - - image_multi_getimg (hdr, 2, &fdt_data, &fdt_len); - if (fdt_len) { - - of_flat_tree = (char *)fdt_data; - -#ifndef CFG_NO_FLASH - /* move the blob if it is in flash (set of_data to !null) */ - if (addr2info ((ulong)of_flat_tree) != NULL) - of_data = (ulong)of_flat_tree; -#endif - - if (fdt_check_header (of_flat_tree) != 0) { - fdt_error ("image is not a fdt"); - do_reset (cmdtp, flag, argc, argv); - } - - if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != fdt_len) { - fdt_error ("fdt size != image size"); - do_reset (cmdtp, flag, argc, argv); - } - } - } -#endif - - -#if defined(CONFIG_OF_LIBFDT) - -#ifdef CFG_BOOTMAPSZ - /* - * The blob must be within CFG_BOOTMAPSZ, - * so we flag it to be copied if it is not. - */ - if (of_flat_tree >= (char *)CFG_BOOTMAPSZ) - of_data = (ulong)of_flat_tree; -#endif - - /* move of_flat_tree if needed */ - if (of_data) { - int err; - ulong of_start, of_len; - - of_len = be32_to_cpu(fdt_totalsize(of_data)); - - /* position on a 4K boundary before the alloc_current */ - of_start = alloc_current - of_len; - 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); + alloc_current = get_fdt (alloc_current, + cmdtp, flag, argc, argv, hdr, &of_flat_tree); - 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_data, (void *)of_start, of_len); - if (err != 0) { - fdt_error ("fdt move failed"); - do_reset (cmdtp, flag, argc, argv); - } - puts ("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). @@ -342,4 +221,156 @@ static void fdt_error (const char *msg) puts (msg); puts (" - must RESET the board to recover.\n"); } + +static ulong get_fdt (ulong alloc_current, + cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + image_header_t *hdr, char **of_flat_tree) +{ + image_header_t *fdt_hdr; + ulong fdt_relocate = 0; + char *fdt = NULL; + ulong new_alloc_current; + + if(argc > 3) { + fdt = (char *)simple_strtoul (argv[3], NULL, 16); + fdt_hdr = (image_header_t *)fdt; + + if (fdt_check_header (fdt) == 0) { + printf ("## Flattened Device Tree blob at %08lx\n", fdt); +#ifndef CFG_NO_FLASH + if (addr2info ((ulong)fdt) != NULL) + fdt_relocate = 1; +#endif + } else if (image_check_magic (fdt_hdr)) { + ulong image_start, image_end; + ulong load_start, load_end; + + printf ("## Flattened Device Tree Image at %08lx\n", + fdt_hdr); + + print_image_hdr (fdt_hdr); + + 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"); + do_reset (cmdtp, flag, argc, argv); + } + + puts (" Verifying Checksum ... "); + if (!image_check_hcrc (fdt_hdr)) { + fdt_error ("fdt header checksum invalid"); + do_reset (cmdtp, flag, argc, argv); + } + + if (!image_check_dcrc (fdt_hdr)) { + fdt_error ("fdt checksum invalid"); + do_reset (cmdtp, flag, argc, argv); + } + puts ("OK\n"); + + if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) { + fdt_error ("uImage is not a fdt"); + do_reset (cmdtp, flag, argc, argv); + } + if (image_get_comp (fdt_hdr) != IH_COMP_NONE) { + fdt_error ("uImage is compressed"); + do_reset (cmdtp, flag, argc, argv); + } + if (fdt_check_header ((char *)image_get_data (fdt_hdr)) != 0) { + fdt_error ("uImage data is not a fdt"); + do_reset (cmdtp, flag, argc, argv); + } + + memmove ((void *)image_get_load (fdt_hdr), + (void *)image_get_data (fdt_hdr), + image_get_data_size (fdt_hdr)); + + fdt = (char *)image_get_load (fdt_hdr); + } else { + fdt_error ("Did not find a Flattened Device Tree"); + do_reset (cmdtp, flag, argc, argv); + } + printf (" Booting using the fdt at 0x%x\n", + fdt); + } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + ulong fdt_data, fdt_len; + + printf ("## Flattened Device Tree from multi " + "component Image at %08lX\n", (ulong)hdr); + + image_multi_getimg (hdr, 2, &fdt_data, &fdt_len); + if (fdt_len) { + + fdt = (char *)fdt_data; + printf (" Booting using the fdt at 0x%x\n", fdt); + +#ifndef CFG_NO_FLASH + /* move the blob if it is in flash (set of_relocte) */ + if (addr2info ((ulong)fdt) != NULL) + fdt_relocate = 1; +#endif + + if (fdt_check_header (fdt) != 0) { + fdt_error ("image is not a fdt"); + do_reset (cmdtp, flag, argc, argv); + } + + if (be32_to_cpu (fdt_totalsize (fdt)) != fdt_len) { + fdt_error ("fdt size != image size"); + do_reset (cmdtp, flag, argc, argv); + } + } else { + debug (" Did not find a Flattened Device Tree"); + } + } + +#ifdef CFG_BOOTMAPSZ + /* + * The blob must be within CFG_BOOTMAPSZ, + * so we flag it to be copied if it is not. + */ + if (fdt >= (char *)CFG_BOOTMAPSZ) + fdt_relocate = 1; +#endif + + /* move flattend device tree if needed */ + if (fdt_relocate) { + int err; + ulong of_start, of_len; + + of_len = be32_to_cpu (fdt_totalsize (fdt)); + + /* position on a 4K boundary before the alloc_current */ + of_start = alloc_current - of_len; + of_start &= ~(4096 - 1); /* align on page */ + + debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", + (ulong)fdt, (ulong)fdt + of_len - 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, (void *)of_start, of_len); + if (err != 0) { + fdt_error ("fdt move failed"); + do_reset (cmdtp, flag, argc, argv); + } + puts ("OK\n"); + + *of_flat_tree = (char *)of_start; + new_alloc_current = of_start; + } else { + *of_flat_tree = fdt; + new_alloc_current = alloc_current; + } + + return new_alloc_current; +} #endif -- cgit v1.2.1 From fff888a1997ff7de9b29e24050fc4a0fd403ba16 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 21 Feb 2008 17:20:19 +0100 Subject: [new uImage] Add gen_get_image() routine This routine assures that image (whether legacy or FIT) is not in a special dataflash storage. If image address is a dataflash address image is moved to system RAM. Signed-off-by: Marian Balakowicz --- lib_ppc/bootm.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 69ec459105..04a9665a9a 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -234,6 +234,11 @@ static ulong get_fdt (ulong alloc_current, if(argc > 3) { fdt = (char *)simple_strtoul (argv[3], NULL, 16); + + debug ("## Checking for 'FDT'/'FDT image' at %08lx\n", fdt); + + /* copy from dataflash if needed */ + fdt = (char *)gen_get_image ((ulong)fdt); fdt_hdr = (image_header_t *)fdt; if (fdt_check_header (fdt) == 0) { -- cgit v1.2.1 From 2242f5369822bc7780db95c47985bb408ea9157b Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 21 Feb 2008 17:27:41 +0100 Subject: [new uImage] Rename and move print_image_hdr() routine Signed-off-by: Marian Balakowicz --- lib_ppc/bootm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 04a9665a9a..d2ee3dc5cc 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -254,7 +254,7 @@ static ulong get_fdt (ulong alloc_current, printf ("## Flattened Device Tree Image at %08lx\n", fdt_hdr); - print_image_hdr (fdt_hdr); + image_print_contents (fdt_hdr); image_start = (ulong)fdt_hdr; image_end = image_get_image_end (fdt_hdr); -- cgit v1.2.1 From d5934ad7756f038a393a9cfab76a4fe306d9d930 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Mon, 4 Feb 2008 08:28:09 +0100 Subject: [new uImage] Add dual format uImage support framework This patch adds framework for dual format images. Format detection is added and the bootm controll flow is updated to include cases for new FIT format uImages. When the legacy (image_header based) format is detected appropriate legacy specific handling is invoked. For the new (FIT based) format uImages dual boot framework has a minial support, that will only print out a corresponding debug messages. Implementation of the FIT specific handling will be added in following patches. Signed-off-by: Marian Balakowicz --- lib_ppc/bootm.c | 178 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 131 insertions(+), 47 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index d2ee3dc5cc..a1bbfc6314 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -43,7 +43,7 @@ static void fdt_error (const char *msg); static ulong get_fdt (ulong alloc_current, cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, char **of_flat_tree); + bootm_headers_t *images, char **of_flat_tree); #endif #ifdef CFG_INIT_RAM_LOCK @@ -59,7 +59,7 @@ static void set_clocks_in_mhz (bd_t *kbd); void __attribute__((noinline)) do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, + bootm_headers_t *images, int verify) { ulong sp, sp_limit, alloc_current; @@ -69,6 +69,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, ulong cmd_start, cmd_end; bd_t *kbd; + ulong ep = 0; void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); #if defined(CONFIG_OF_LIBFDT) @@ -97,11 +98,22 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, alloc_current = get_boot_kbd (alloc_current, &kbd); set_clocks_in_mhz(kbd); - /* find kernel */ - kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr); + /* 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) { + fit_unsupported_reset ("PPC linux bootm"); + do_reset (cmdtp, flag, argc, argv); +#endif + } else { + puts ("Could not find kernel entry point!\n"); + do_reset (cmdtp, flag, argc, argv); + } + kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; /* find ramdisk */ - get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, + get_ramdisk (cmdtp, flag, argc, argv, images, verify, IH_ARCH_PPC, &rd_data_start, &rd_data_end); rd_len = rd_data_end - rd_data_start; @@ -113,7 +125,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, #if defined(CONFIG_OF_LIBFDT) /* find flattened device tree */ alloc_current = get_fdt (alloc_current, - cmdtp, flag, argc, argv, hdr, &of_flat_tree); + cmdtp, flag, argc, argv, images, &of_flat_tree); /* * Add the chosen node if it doesn't exist, add the env and bd_t @@ -225,33 +237,69 @@ static void fdt_error (const char *msg) static ulong get_fdt (ulong alloc_current, cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, char **of_flat_tree) + bootm_headers_t *images, char **of_flat_tree) { + ulong fdt_addr; image_header_t *fdt_hdr; + char *fdt_blob = NULL; ulong fdt_relocate = 0; - char *fdt = NULL; ulong new_alloc_current; + 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; +#endif - if(argc > 3) { - fdt = (char *)simple_strtoul (argv[3], NULL, 16); + if (argc > 3) { +#if defined(CONFIG_FIT) + /* + * 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); + } - debug ("## Checking for 'FDT'/'FDT image' at %08lx\n", fdt); + debug ("## Checking for 'FDT'/'FDT image' at %08lx\n", + fdt_addr); /* copy from dataflash if needed */ - fdt = (char *)gen_get_image ((ulong)fdt); - fdt_hdr = (image_header_t *)fdt; + fdt_addr = gen_get_image (fdt_addr); - if (fdt_check_header (fdt) == 0) { - printf ("## Flattened Device Tree blob at %08lx\n", fdt); -#ifndef CFG_NO_FLASH - if (addr2info ((ulong)fdt) != NULL) - fdt_relocate = 1; -#endif - } else if (image_check_magic (fdt_hdr)) { - ulong image_start, image_end; - ulong load_start, load_end; + /* + * 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 (gen_image_get_format ((void *)fdt_addr)) { + case IMAGE_FORMAT_LEGACY: + debug ("* fdt: legacy format image\n"); - printf ("## Flattened Device Tree Image at %08lx\n", + fdt_hdr = (image_header_t *)fdt_addr; + printf ("## Flattened Device Tree Legacy Image at %08lx\n", fdt_hdr); image_print_contents (fdt_hdr); @@ -296,51 +344,87 @@ static ulong get_fdt (ulong alloc_current, (void *)image_get_data (fdt_hdr), image_get_data_size (fdt_hdr)); - fdt = (char *)image_get_load (fdt_hdr); - } else { - fdt_error ("Did not find a Flattened Device Tree"); + fdt_blob = (char *)image_get_load (fdt_hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + + /* check FDT blob vs FIT hdr */ + if (fit_uname_config || fit_uname_fdt) { + /* + * FIT image + */ + fit_hdr = (void *)fdt_addr; + debug ("* fdt: FIT format image\n"); + fit_unsupported_reset ("PPC fdt"); + do_reset (cmdtp, flag, argc, argv); + } else { + /* + * FDT blob + */ + printf ("## Flattened Device Tree blob at %08lx\n", fdt_blob); + fdt_blob = (char *)fdt_addr; + } + break; +#endif + default: + fdt_error ("Did not find a cmdline Flattened Device Tree"); do_reset (cmdtp, flag, argc, argv); } - printf (" Booting using the fdt at 0x%x\n", - fdt); - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + + printf (" Booting using the fdt blob at 0x%x\n", fdt_blob); + + } else if (images->legacy_hdr_valid && + image_check_type (images->legacy_hdr_os, 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)hdr); + "component Image at %08lX\n", + (ulong)images->legacy_hdr_os); - image_multi_getimg (hdr, 2, &fdt_data, &fdt_len); + image_multi_getimg (images->legacy_hdr_os, 2, &fdt_data, &fdt_len); if (fdt_len) { - fdt = (char *)fdt_data; - printf (" Booting using the fdt at 0x%x\n", fdt); + fdt_blob = (char *)fdt_data; + printf (" Booting using the fdt at 0x%x\n", fdt_blob); -#ifndef CFG_NO_FLASH - /* move the blob if it is in flash (set of_relocte) */ - if (addr2info ((ulong)fdt) != NULL) - fdt_relocate = 1; -#endif - - if (fdt_check_header (fdt) != 0) { + if (fdt_check_header (fdt_blob) != 0) { fdt_error ("image is not a fdt"); do_reset (cmdtp, flag, argc, argv); } - if (be32_to_cpu (fdt_totalsize (fdt)) != fdt_len) { + if (be32_to_cpu (fdt_totalsize (fdt_blob)) != fdt_len) { fdt_error ("fdt size != image size"); do_reset (cmdtp, flag, argc, argv); } } else { - debug (" Did not find a Flattened Device Tree"); + fdt_error ("Did not find a Flattened Device Tree " + "in a legacy multi-component image"); + do_reset (cmdtp, flag, argc, argv); } + } else { + debug ("## No Flattened Device Tree\n"); + *of_flat_tree = NULL; + return alloc_current; } +#ifndef CFG_NO_FLASH + /* move the blob if it is in flash (set fdt_relocate) */ + if (addr2info ((ulong)fdt_blob) != NULL) + fdt_relocate = 1; +#endif + #ifdef CFG_BOOTMAPSZ /* * The blob must be within CFG_BOOTMAPSZ, * so we flag it to be copied if it is not. */ - if (fdt >= (char *)CFG_BOOTMAPSZ) + if (fdt_blob >= (char *)CFG_BOOTMAPSZ) fdt_relocate = 1; #endif @@ -349,20 +433,20 @@ static ulong get_fdt (ulong alloc_current, int err; ulong of_start, of_len; - of_len = be32_to_cpu (fdt_totalsize (fdt)); + of_len = be32_to_cpu (fdt_totalsize (fdt_blob)); /* position on a 4K boundary before the alloc_current */ of_start = alloc_current - of_len; of_start &= ~(4096 - 1); /* align on page */ debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - (ulong)fdt, (ulong)fdt + of_len - 1, + (ulong)fdt_blob, (ulong)fdt_blob + of_len - 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, (void *)of_start, of_len); + err = fdt_open_into (fdt_blob, (void *)of_start, of_len); if (err != 0) { fdt_error ("fdt move failed"); do_reset (cmdtp, flag, argc, argv); @@ -372,7 +456,7 @@ static ulong get_fdt (ulong alloc_current, *of_flat_tree = (char *)of_start; new_alloc_current = of_start; } else { - *of_flat_tree = fdt; + *of_flat_tree = fdt_blob; new_alloc_current = alloc_current; } -- cgit v1.2.1 From d2ced9eb19ec74f4a359949dbe353427fa6d55ca Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Mon, 4 Feb 2008 08:28:17 +0100 Subject: [new uImage] POWERPC: Split get_fdt() into get and relocate routines PPC specific FDT blob handling code is divided into two separate routines: get_fdt() - find and verify a FDT blob (either raw or image embedded) fdt_relocate() - move FDT blob to within BOOTMAP if needed Signed-off-by: Marian Balakowicz Acked-by: Kumar Gala --- lib_ppc/bootm.c | 61 ++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 18 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index a1bbfc6314..d5e019e3a4 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -41,9 +41,11 @@ #include static void fdt_error (const char *msg); -static ulong get_fdt (ulong alloc_current, cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - bootm_headers_t *images, char **of_flat_tree); +static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + bootm_headers_t *images, char **of_flat_tree, ulong *of_size); +static ulong fdt_relocate (ulong alloc_current, + cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + char **of_flat_tree, ulong *of_size); #endif #ifdef CFG_INIT_RAM_LOCK @@ -73,7 +75,8 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); #if defined(CONFIG_OF_LIBFDT) - char *of_flat_tree; + char *of_flat_tree = NULL; + ulong of_size = 0; #endif /* @@ -124,14 +127,16 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, #if defined(CONFIG_OF_LIBFDT) /* find flattened device tree */ - alloc_current = get_fdt (alloc_current, - cmdtp, flag, argc, argv, images, &of_flat_tree); + get_fdt (cmdtp, flag, argc, argv, images, &of_flat_tree, &of_size); + + alloc_current = fdt_relocate (alloc_current, + cmdtp, flag, argc, argv, &of_flat_tree, &of_size); /* * 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 (of_flat_tree) { + if (of_size) { if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) { fdt_error ("/chosen node create failed"); do_reset (cmdtp, flag, argc, argv); @@ -234,16 +239,12 @@ static void fdt_error (const char *msg) puts (" - must RESET the board to recover.\n"); } -static ulong get_fdt (ulong alloc_current, - cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - bootm_headers_t *images, char **of_flat_tree) +static void 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 fdt_relocate = 0; - ulong new_alloc_current; ulong image_start, image_end; ulong load_start, load_end; #if defined(CONFIG_FIT) @@ -410,13 +411,37 @@ static ulong get_fdt (ulong alloc_current, } else { debug ("## No Flattened Device Tree\n"); *of_flat_tree = NULL; + *of_size = 0; + return; + } + + *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); +} + +static ulong fdt_relocate (ulong alloc_current, + 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 new_alloc_current; + + /* nothing to do */ + if (*of_size == 0) return alloc_current; + + if (fdt_check_header (fdt_blob) != 0) { + fdt_error ("image is not a fdt"); + do_reset (cmdtp, flag, argc, argv); } #ifndef CFG_NO_FLASH - /* move the blob if it is in flash (set fdt_relocate) */ + /* move the blob if it is in flash (set relocate) */ if (addr2info ((ulong)fdt_blob) != NULL) - fdt_relocate = 1; + relocate = 1; #endif #ifdef CFG_BOOTMAPSZ @@ -425,15 +450,15 @@ static ulong get_fdt (ulong alloc_current, * so we flag it to be copied if it is not. */ if (fdt_blob >= (char *)CFG_BOOTMAPSZ) - fdt_relocate = 1; + relocate = 1; #endif /* move flattend device tree if needed */ - if (fdt_relocate) { + if (relocate) { int err; ulong of_start, of_len; - of_len = be32_to_cpu (fdt_totalsize (fdt_blob)); + of_len = *of_size; /* position on a 4K boundary before the alloc_current */ of_start = alloc_current - of_len; -- cgit v1.2.1 From 823afe7cefe00dafefc6696c1cc7aa828c394234 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 27 Feb 2008 11:00:47 +0100 Subject: [Makefile] Sort COBJS in lib_ Makefiles Signed-off-by: Marian Balakowicz --- lib_ppc/Makefile | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/Makefile b/lib_ppc/Makefile index 61507b038f..3d76b700e2 100644 --- a/lib_ppc/Makefile +++ b/lib_ppc/Makefile @@ -25,14 +25,21 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = ppccache.o ppcstring.o ticks.o - -COBJS = board.o \ - bat_rw.o cache.o extable.o kgdb.o time.o interrupts.o \ - bootm.o - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SOBJS-y += ppccache.o +SOBJS-y += ppcstring.o +SOBJS-y += ticks.o + +COBJS-y += bat_rw.o +COBJS-y += board.o +COBJS-y += bootm.o +COBJS-y += cache.o +COBJS-y += extable.o +COBJS-y += interrupts.o +COBJS-y += kgdb.o +COBJS-y += time.o + +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) -- cgit v1.2.1 From 8a5ea3e6168fe6a2780eeaf257a3b19f30dec658 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 27 Feb 2008 11:01:04 +0100 Subject: [new uImage] Move image verify flag to bootm_headers structure Do not pass image verification flag directly to related routines. Simplify argument passing and move it to the bootm_header structure which contains curently processed image specific data and is already being passed on the argument list. Signed-off-by: Marian Balakowicz Acked-by: Kumar Gala --- lib_ppc/bootm.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index d5e019e3a4..319d4ba411 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -59,10 +59,8 @@ static ulong get_sp (void); static void set_clocks_in_mhz (bd_t *kbd); void __attribute__((noinline)) -do_bootm_linux(cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - bootm_headers_t *images, - int verify) +do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + bootm_headers_t *images) { ulong sp, sp_limit, alloc_current; @@ -116,7 +114,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; /* find ramdisk */ - get_ramdisk (cmdtp, flag, argc, argv, images, verify, + get_ramdisk (cmdtp, flag, argc, argv, images, IH_ARCH_PPC, &rd_data_start, &rd_data_end); rd_len = rd_data_end - rd_data_start; -- cgit v1.2.1 From ff0734cff0fb5397ce2f4602f4f3e5ec9c8a36e8 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 27 Feb 2008 11:02:26 +0100 Subject: [new uImage] POWERPC: Add image_get_fdt() routine FDT blob may be passed either: (1) raw (2) or embedded in the legacy uImage (3) or embedded in the new uImage. For the (2) case embedding image must be verified before we get FDT from it. This patch factors out legacy image specific verification routine to the separate helper routine. Signed-off-by: Marian Balakowicz Acked-by: Kumar Gala --- lib_ppc/bootm.c | 76 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 32 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 319d4ba411..ad05bc5d8e 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -237,6 +237,39 @@ static void fdt_error (const char *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; +} + static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images, char **of_flat_tree, ulong *of_size) { @@ -297,12 +330,17 @@ static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], case IMAGE_FORMAT_LEGACY: debug ("* fdt: legacy format image\n"); - fdt_hdr = (image_header_t *)fdt_addr; + /* verify fdt_addr points to a valid image header */ printf ("## Flattened Device Tree Legacy Image at %08lx\n", - fdt_hdr); - - image_print_contents (fdt_hdr); + fdt_addr); + fdt_hdr = image_get_fdt (fdt_addr); + if (!fdt_hdr) + do_reset (cmdtp, flag, argc, argv); + /* + * 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); @@ -313,35 +351,9 @@ static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], fdt_error ("fdt overwritten"); do_reset (cmdtp, flag, argc, argv); } - - puts (" Verifying Checksum ... "); - if (!image_check_hcrc (fdt_hdr)) { - fdt_error ("fdt header checksum invalid"); - do_reset (cmdtp, flag, argc, argv); - } - - if (!image_check_dcrc (fdt_hdr)) { - fdt_error ("fdt checksum invalid"); - do_reset (cmdtp, flag, argc, argv); - } - puts ("OK\n"); - - if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) { - fdt_error ("uImage is not a fdt"); - do_reset (cmdtp, flag, argc, argv); - } - if (image_get_comp (fdt_hdr) != IH_COMP_NONE) { - fdt_error ("uImage is compressed"); - do_reset (cmdtp, flag, argc, argv); - } - if (fdt_check_header ((char *)image_get_data (fdt_hdr)) != 0) { - fdt_error ("uImage data is not a fdt"); - do_reset (cmdtp, flag, argc, argv); - } - memmove ((void *)image_get_load (fdt_hdr), - (void *)image_get_data (fdt_hdr), - image_get_data_size (fdt_hdr)); + (void *)image_get_data (fdt_hdr), + image_get_data_size (fdt_hdr)); fdt_blob = (char *)image_get_load (fdt_hdr); break; -- cgit v1.2.1 From 4efbe9dbb129f857f27856936112c8c02f016be6 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 27 Feb 2008 11:02:26 +0100 Subject: [new uImage] Correct raw FDT blob handlig when CONFIG_FIT is disabled Dual format image code must properly handle all three FDT passing methods: - raw FDT blob passed - FDT blob embedded in the legacy uImage - FDT blob embedded in the new uImage This patch enables proper raw FDT handling when no FIT imaeg support is compiled in. This is a bit tricky as we must dected FIT format even when FIT uImage handling is not enabled as both FIT uImages and raw FDT blobs use tha same low level format (libfdt). Signed-off-by: Marian Balakowicz --- lib_ppc/bootm.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index ad05bc5d8e..d80d69ab2e 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -357,11 +357,15 @@ static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], fdt_blob = (char *)image_get_load (fdt_hdr); break; -#if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: - - /* check FDT blob vs FIT hdr */ - if (fit_uname_config || fit_uname_fdt) { + /* + * 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 (0) { /* FIXME: call FIT format verification */ /* * FIT image */ @@ -369,15 +373,17 @@ static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], debug ("* fdt: FIT format image\n"); fit_unsupported_reset ("PPC fdt"); do_reset (cmdtp, flag, argc, argv); - } else { + } else +#endif + { /* * FDT blob */ + debug ("* fdt: raw FDT blob\n"); printf ("## Flattened Device Tree blob at %08lx\n", fdt_blob); fdt_blob = (char *)fdt_addr; } break; -#endif default: fdt_error ("Did not find a cmdline Flattened Device Tree"); do_reset (cmdtp, flag, argc, argv); -- cgit v1.2.1 From a6612bdfe7ef37b9787b66800cf02aaded05fbeb Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 27 Feb 2008 21:51:43 -0600 Subject: [new uImage] Don't pass kdb to ramdisk_high since we may not have one We don't actually need the kdb param as we are just using it to get bd->bi_memsize which we can get from gd->bd->bi_memsize. Also, if we boot via OF we might not actually fill out a kdb. Signed-off-by: Kumar Gala Acked-by: Marian Balakowicz --- lib_ppc/bootm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index d80d69ab2e..fa28b4314e 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -120,8 +120,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], rd_len = rd_data_end - rd_data_start; alloc_current = ramdisk_high (alloc_current, rd_data_start, rd_len, - kbd, sp_limit, get_sp (), - &initrd_start, &initrd_end); + sp_limit, get_sp (), &initrd_start, &initrd_end); #if defined(CONFIG_OF_LIBFDT) /* find flattened device tree */ -- cgit v1.2.1 From 27953493ef025fb698d68c5dee39b36f01f4d530 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 27 Feb 2008 21:51:44 -0600 Subject: [new uImage] ppc: Determine if we are booting an OF style If we are bootin OF style than we can skip setting up some things that are used for the old boot method. Signed-off-by: Kumar Gala Acked-by: Marian Balakowicz --- lib_ppc/bootm.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index fa28b4314e..3e89da1c46 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -71,10 +71,10 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bd_t *kbd; ulong ep = 0; void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); + ulong of_size = 0; #if defined(CONFIG_OF_LIBFDT) char *of_flat_tree = NULL; - ulong of_size = 0; #endif /* @@ -92,12 +92,19 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], alloc_current = sp_limit = get_boot_sp_limit(sp); debug ("=> set upper limit to 0x%08lx\n", sp_limit); - /* allocate space and init command line */ - alloc_current = get_boot_cmdline (alloc_current, &cmd_start, &cmd_end); +#if defined(CONFIG_OF_LIBFDT) + /* find flattened device tree */ + get_fdt (cmdtp, flag, argc, argv, images, &of_flat_tree, &of_size); +#endif - /* allocate space for kernel copy of board info */ - alloc_current = get_boot_kbd (alloc_current, &kbd); - set_clocks_in_mhz(kbd); + if (!of_size) { + /* allocate space and init command line */ + alloc_current = get_boot_cmdline (alloc_current, &cmd_start, &cmd_end); + + /* allocate space for kernel copy of board info */ + alloc_current = get_boot_kbd (alloc_current, &kbd); + set_clocks_in_mhz(kbd); + } /* find kernel entry point */ if (images->legacy_hdr_valid) { @@ -123,9 +130,6 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], sp_limit, get_sp (), &initrd_start, &initrd_end); #if defined(CONFIG_OF_LIBFDT) - /* find flattened device tree */ - get_fdt (cmdtp, flag, argc, argv, images, &of_flat_tree, &of_size); - alloc_current = fdt_relocate (alloc_current, cmdtp, flag, argc, argv, &of_flat_tree, &of_size); -- cgit v1.2.1 From d2bc095a639672def11d5d043b5688d0dbd692ec Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 27 Feb 2008 21:51:45 -0600 Subject: [new uImage] ppc: Re-order ramdisk/fdt handling sequence Doing the fdt before the ramdisk allows us to grow the fdt w/o concern however it does mean we have to go in and fixup the initrd info since we don't know where it will be. Signed-off-by: Kumar Gala --- lib_ppc/bootm.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 3e89da1c46..de6995ecf2 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -71,6 +71,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bd_t *kbd; ulong ep = 0; void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); + int ret; ulong of_size = 0; #if defined(CONFIG_OF_LIBFDT) @@ -126,9 +127,6 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], rd_len = rd_data_end - rd_data_start; - alloc_current = ramdisk_high (alloc_current, rd_data_start, rd_len, - sp_limit, get_sp (), &initrd_start, &initrd_end); - #if defined(CONFIG_OF_LIBFDT) alloc_current = fdt_relocate (alloc_current, cmdtp, flag, argc, argv, &of_flat_tree, &of_size); @@ -138,7 +136,8 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], * if the user wants it (the logic is in the subroutines). */ if (of_size) { - if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) { + /* pass in dummy initrd info, we'll fix up later */ + if (fdt_chosen(of_flat_tree, rd_data_start, rd_data_end, 0) < 0) { fdt_error ("/chosen node create failed"); do_reset (cmdtp, flag, argc, argv); } @@ -161,6 +160,38 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], } #endif /* CONFIG_OF_LIBFDT */ + alloc_current = ramdisk_high (alloc_current, rd_data_start, rd_len, + sp_limit, get_sp (), &initrd_start, &initrd_end); + +#if defined(CONFIG_OF_LIBFDT) + /* fixup the initrd now that we know where it should be */ + if ((of_flat_tree) && (initrd_start && initrd_end)) { + uint64_t addr, size; + int total = fdt_num_mem_rsv(of_flat_tree); + int j; + + /* 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) { + fdt_del_mem_rsv(of_flat_tree, j); + break; + } + } + + ret = fdt_add_mem_rsv(of_flat_tree, initrd_start, + initrd_end - initrd_start + 1); + if (ret < 0) { + printf("fdt_chosen: %s\n", fdt_strerror(ret)); + do_reset (cmdtp, flag, argc, argv); + } + + do_fixup_by_path_u32(of_flat_tree, "/chosen", + "linux,initrd-start", initrd_start, 0); + do_fixup_by_path_u32(of_flat_tree, "/chosen", + "linux,initrd-end", initrd_end, 0); + } +#endif debug ("## Transferring control to Linux (at address %08lx) ...\n", (ulong)kernel); -- cgit v1.2.1 From 274cea2bddbca10cdad7daa518951b75c44ef6bc Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 27 Feb 2008 21:51:46 -0600 Subject: [new uImage] rework error handling so common functions don't reset Changed image_get_ramdisk() to just return NULL on error and have get_ramdisk() propogate that error to the caller. It's left to the caller to call do_reset() if it wants to. Also moved calling do_reset() in get_fdt() and fdt_relocate() on ppc to a common location. In the future we will change get_fdt() and fdt_relocate() to return success/failure and not call do_reset() at all. Signed-off-by: Kumar Gala Acked-by: Marian Balakowicz --- lib_ppc/bootm.c | 61 ++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 20 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index de6995ecf2..9f48b8dd96 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -41,7 +41,7 @@ #include static void fdt_error (const char *msg); -static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], +static int get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images, char **of_flat_tree, ulong *of_size); static ulong fdt_relocate (ulong alloc_current, cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], @@ -95,7 +95,10 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], #if defined(CONFIG_OF_LIBFDT) /* find flattened device tree */ - get_fdt (cmdtp, flag, argc, argv, images, &of_flat_tree, &of_size); + ret = get_fdt (cmdtp, flag, argc, argv, images, &of_flat_tree, &of_size); + + if (ret) + goto error; #endif if (!of_size) { @@ -113,18 +116,21 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { fit_unsupported_reset ("PPC linux bootm"); - do_reset (cmdtp, flag, argc, argv); + goto error; #endif } else { puts ("Could not find kernel entry point!\n"); - do_reset (cmdtp, flag, argc, argv); + goto error; } kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; /* find ramdisk */ - get_ramdisk (cmdtp, flag, argc, argv, images, + ret = get_ramdisk (cmdtp, flag, argc, argv, images, IH_ARCH_PPC, &rd_data_start, &rd_data_end); + if (ret) + goto error; + rd_len = rd_data_end - rd_data_start; #if defined(CONFIG_OF_LIBFDT) @@ -139,18 +145,18 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], /* pass in dummy initrd info, we'll fix up later */ if (fdt_chosen(of_flat_tree, rd_data_start, rd_data_end, 0) < 0) { fdt_error ("/chosen node create failed"); - do_reset (cmdtp, flag, argc, argv); + goto error; } #ifdef CONFIG_OF_HAS_UBOOT_ENV if (fdt_env(of_flat_tree) < 0) { fdt_error ("/u-boot-env node create failed"); - do_reset (cmdtp, flag, argc, argv); + goto error; } #endif #ifdef CONFIG_OF_HAS_BD_T if (fdt_bd_t(of_flat_tree) < 0) { fdt_error ("/bd_t node create failed"); - do_reset (cmdtp, flag, argc, argv); + goto error; } #endif #ifdef CONFIG_OF_BOARD_SETUP @@ -183,7 +189,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], initrd_end - initrd_start + 1); if (ret < 0) { printf("fdt_chosen: %s\n", fdt_strerror(ret)); - do_reset (cmdtp, flag, argc, argv); + goto error; } do_fixup_by_path_u32(of_flat_tree, "/chosen", @@ -225,6 +231,11 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], */ (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); /* does not return */ + return ; + +error: + do_reset (cmdtp, flag, argc, argv); + return ; } static ulong get_sp (void) @@ -304,7 +315,7 @@ static image_header_t *image_get_fdt (ulong fdt_addr) return fdt_hdr; } -static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], +static int 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; @@ -369,7 +380,7 @@ static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], fdt_addr); fdt_hdr = image_get_fdt (fdt_addr); if (!fdt_hdr) - do_reset (cmdtp, flag, argc, argv); + goto error; /* * move image data to the load address, @@ -383,7 +394,7 @@ static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], if ((load_start < image_end) && (load_end > image_start)) { fdt_error ("fdt overwritten"); - do_reset (cmdtp, flag, argc, argv); + goto error; } memmove ((void *)image_get_load (fdt_hdr), (void *)image_get_data (fdt_hdr), @@ -406,7 +417,7 @@ static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], fit_hdr = (void *)fdt_addr; debug ("* fdt: FIT format image\n"); fit_unsupported_reset ("PPC fdt"); - do_reset (cmdtp, flag, argc, argv); + goto error; } else #endif { @@ -420,7 +431,7 @@ static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], break; default: fdt_error ("Did not find a cmdline Flattened Device Tree"); - do_reset (cmdtp, flag, argc, argv); + goto error; } printf (" Booting using the fdt blob at 0x%x\n", fdt_blob); @@ -446,29 +457,35 @@ static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], if (fdt_check_header (fdt_blob) != 0) { fdt_error ("image is not a fdt"); - do_reset (cmdtp, flag, argc, argv); + goto error; } if (be32_to_cpu (fdt_totalsize (fdt_blob)) != fdt_len) { fdt_error ("fdt size != image size"); - do_reset (cmdtp, flag, argc, argv); + goto error; } } else { fdt_error ("Did not find a Flattened Device Tree " "in a legacy multi-component image"); - do_reset (cmdtp, flag, argc, argv); + goto error; } } else { debug ("## No Flattened Device Tree\n"); *of_flat_tree = NULL; *of_size = 0; - return; + 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 ulong fdt_relocate (ulong alloc_current, @@ -485,7 +502,7 @@ static ulong fdt_relocate (ulong alloc_current, if (fdt_check_header (fdt_blob) != 0) { fdt_error ("image is not a fdt"); - do_reset (cmdtp, flag, argc, argv); + goto error; } #ifndef CFG_NO_FLASH @@ -524,7 +541,7 @@ static ulong fdt_relocate (ulong alloc_current, err = fdt_open_into (fdt_blob, (void *)of_start, of_len); if (err != 0) { fdt_error ("fdt move failed"); - do_reset (cmdtp, flag, argc, argv); + goto error; } puts ("OK\n"); @@ -536,5 +553,9 @@ static ulong fdt_relocate (ulong alloc_current, } return new_alloc_current; + +error: + do_reset (cmdtp, flag, argc, argv); + return 1; } #endif -- cgit v1.2.1 From 4648c2e7a173b0d7f17bef4adaa0623090c9e904 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 19 Feb 2008 22:03:47 -0600 Subject: [new uImage] ppc: Allow boards to specify effective amount of memory For historical reasons we limited the stack to 256M because some boards could only map that much via BATS. However newer boards are capable of mapping more memory (for example 85xx is capable of doing up to 2G). Signed-off-by: Kumar Gala Acked-by: Marian Balakowicz --- lib_ppc/board.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/board.c b/lib_ppc/board.c index 45d1328f21..fbf1c5d25a 100644 --- a/lib_ppc/board.c +++ b/lib_ppc/board.c @@ -361,6 +361,20 @@ init_fnc_t *init_sequence[] = { NULL, /* Terminate this list */ }; +#ifndef CONFIG_MAX_MEM_MAPPED +#define CONFIG_MAX_MEM_MAPPED (256 << 20) +#endif +ulong get_effective_memsize(void) +{ +#ifndef CONFIG_VERY_BIG_RAM + return gd->ram_size; +#else + /* limit stack to what we can reasonable map */ + return ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ? + CONFIG_MAX_MEM_MAPPED : gd->ram_size); +#endif +} + /************************************************************************ * * This is the first part of the initialization sequence that is @@ -419,13 +433,7 @@ void board_init_f (ulong bootflag) */ len = (ulong)&_end - CFG_MONITOR_BASE; -#ifndef CONFIG_VERY_BIG_RAM - addr = CFG_SDRAM_BASE + gd->ram_size; -#else - /* only allow stack below 256M */ - addr = CFG_SDRAM_BASE + - (gd->ram_size > 256 << 20) ? 256 << 20 : gd->ram_size; -#endif + addr = CFG_SDRAM_BASE + get_effective_memsize(); #ifdef CONFIG_LOGBUFFER /* reserve kernel log buffer */ -- cgit v1.2.1 From e822d7fc4dd4755d4d0a22f05e33f33d1a0481da Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 27 Feb 2008 21:51:49 -0600 Subject: [new uImage] Use lmb for bootm allocations Convert generic ramdisk_high(), get_boot_cmdline(), get_boot_kbd() functions over to using lmb for allocation of the ramdisk, command line and kernel bd info. Convert PPC specific fdt_relocate() to use lmb for allocation of the device tree. Provided a weak function that board code can call to do additional lmb reserves if needed. Also introduce the concept of bootmap_base to specify the offset in physical memory that the bootmap is located at. This is used for allocations of the cmdline, kernel bd, and device tree as they should be contained within bootmap_base and bootmap_base + CFG_BOOTMAPSZ. Signed-off-by: Kumar Gala --- lib_ppc/bootm.c | 65 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 25 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 9f48b8dd96..d74a3f46f6 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -43,7 +43,7 @@ static void fdt_error (const char *msg); static int get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images, char **of_flat_tree, ulong *of_size); -static ulong fdt_relocate (ulong alloc_current, +static int fdt_relocate (struct lmb *lmb, ulong bootmap_base, cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], char **of_flat_tree, ulong *of_size); #endif @@ -55,6 +55,7 @@ static ulong fdt_relocate (ulong alloc_current, DECLARE_GLOBAL_DATA_PTR; extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +extern ulong get_effective_memsize(void); static ulong get_sp (void); static void set_clocks_in_mhz (bd_t *kbd); @@ -62,22 +63,25 @@ void __attribute__((noinline)) do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images) { - ulong sp, sp_limit, alloc_current; + ulong sp; ulong initrd_start, initrd_end; ulong rd_data_start, rd_data_end, rd_len; - ulong cmd_start, cmd_end; + ulong cmd_start, cmd_end, bootmap_base; bd_t *kbd; ulong ep = 0; void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); int ret; ulong of_size = 0; + struct lmb *lmb = images->lmb; #if defined(CONFIG_OF_LIBFDT) char *of_flat_tree = NULL; #endif + bootmap_base = 0; + /* * Booting a (Linux) kernel image * @@ -90,8 +94,9 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], sp = get_sp(); debug ("## Current stack ends at 0x%08lx ", sp); - alloc_current = sp_limit = get_boot_sp_limit(sp); - debug ("=> set upper limit to 0x%08lx\n", sp_limit); + /* adjust sp by 1K to be safe */ + sp -= 1024; + lmb_reserve(lmb, sp, (CFG_SDRAM_BASE + get_effective_memsize() - sp)); #if defined(CONFIG_OF_LIBFDT) /* find flattened device tree */ @@ -103,10 +108,18 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], if (!of_size) { /* allocate space and init command line */ - alloc_current = get_boot_cmdline (alloc_current, &cmd_start, &cmd_end); + ret = get_boot_cmdline (lmb, &cmd_start, &cmd_end, bootmap_base); + if (ret) { + puts("ERROR with allocation of cmdline\n"); + goto error; + } /* allocate space for kernel copy of board info */ - alloc_current = get_boot_kbd (alloc_current, &kbd); + ret = get_boot_kbd (lmb, &kbd, bootmap_base); + if (ret) { + puts("ERROR with allocation of kernel bd\n"); + goto error; + } set_clocks_in_mhz(kbd); } @@ -134,8 +147,8 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], rd_len = rd_data_end - rd_data_start; #if defined(CONFIG_OF_LIBFDT) - alloc_current = fdt_relocate (alloc_current, - cmdtp, flag, argc, argv, &of_flat_tree, &of_size); + ret = fdt_relocate (lmb, bootmap_base, + cmdtp, flag, argc, argv, &of_flat_tree, &of_size); /* * Add the chosen node if it doesn't exist, add the env and bd_t @@ -166,8 +179,9 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], } #endif /* CONFIG_OF_LIBFDT */ - alloc_current = ramdisk_high (alloc_current, rd_data_start, rd_len, - sp_limit, get_sp (), &initrd_start, &initrd_end); + ret = ramdisk_high (lmb, rd_data_start, rd_len, &initrd_start, &initrd_end); + if (ret) + goto error; #if defined(CONFIG_OF_LIBFDT) /* fixup the initrd now that we know where it should be */ @@ -488,17 +502,17 @@ error: return 1; } -static ulong fdt_relocate (ulong alloc_current, +static int fdt_relocate (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 new_alloc_current; + ulong of_len = 0; /* nothing to do */ if (*of_size == 0) - return alloc_current; + return 0; if (fdt_check_header (fdt_blob) != 0) { fdt_error ("image is not a fdt"); @@ -511,25 +525,28 @@ static ulong fdt_relocate (ulong alloc_current, relocate = 1; #endif -#ifdef CFG_BOOTMAPSZ /* * The blob must be within CFG_BOOTMAPSZ, * so we flag it to be copied if it is not. */ if (fdt_blob >= (char *)CFG_BOOTMAPSZ) relocate = 1; -#endif + + of_len = be32_to_cpu (fdt_totalsize (fdt)); /* move flattend device tree if needed */ if (relocate) { int err; - ulong of_start, of_len; - - of_len = *of_size; + ulong of_start; /* position on a 4K boundary before the alloc_current */ - of_start = alloc_current - of_len; - of_start &= ~(4096 - 1); /* align on page */ + of_start = 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_len - 1, @@ -546,16 +563,14 @@ static ulong fdt_relocate (ulong alloc_current, puts ("OK\n"); *of_flat_tree = (char *)of_start; - new_alloc_current = of_start; } else { *of_flat_tree = fdt_blob; - new_alloc_current = alloc_current; + lmb_reserve(lmb, (ulong)fdt, of_len); } - return new_alloc_current; + return 0; error: - do_reset (cmdtp, flag, argc, argv); return 1; } #endif -- cgit v1.2.1 From d3f2fa0d278467b2232e4eb2372f905c3febfbeb Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 27 Feb 2008 21:51:50 -0600 Subject: [new uImage] Provide ability to restrict region used for boot images Allow the user to set 'bootm_low' and 'bootm_size' env vars as a way to restrict what memory range is used for bootm. Signed-off-by: Kumar Gala Acked-by: Marian Balakowicz --- lib_ppc/bootm.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index d74a3f46f6..59cc2a4471 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -59,6 +59,10 @@ extern ulong get_effective_memsize(void); static ulong get_sp (void); static void set_clocks_in_mhz (bd_t *kbd); +#ifndef CFG_LINUX_LOWMEM_MAX_SIZE +#define CFG_LINUX_LOWMEM_MAX_SIZE (768*1024*1024) +#endif + void __attribute__((noinline)) do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images) @@ -67,6 +71,7 @@ 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; ulong cmd_start, cmd_end, bootmap_base; bd_t *kbd; @@ -80,7 +85,24 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], char *of_flat_tree = NULL; #endif - bootmap_base = 0; + bootmap_base = getenv_bootm_low(); + size = getenv_bootm_size(); + +#ifdef DEBUG + if (((u64)bootmap_base + 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()) + puts("WARNING: bootm_low + bootm_size exceed eff. memory\n"); +#endif + + size = min(size, get_effective_memsize()); + size = min(size, CFG_LINUX_LOWMEM_MAX_SIZE); + + if (size < getenv_bootm_size()) { + ulong base = bootmap_base + size; + printf("WARNING: adjusting available memory to %x\n", size); + lmb_reserve(lmb, base, getenv_bootm_size() - size); + } /* * Booting a (Linux) kernel image @@ -92,7 +114,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], * pointer. */ sp = get_sp(); - debug ("## Current stack ends at 0x%08lx ", sp); + debug ("## Current stack ends at 0x%08lx\n", sp); /* adjust sp by 1K to be safe */ sp -= 1024; -- cgit v1.2.1 From 75fa002c47171b73fb4c1f2c2fe4d6391c136276 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 27 Feb 2008 21:51:51 -0600 Subject: [new uImage] Respect autostart setting in linux bootm Signed-off-by: Kumar Gala Acked-by: Marian Balakowicz --- lib_ppc/bootm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 59cc2a4471..1afef46df7 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -242,6 +242,8 @@ 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 */ @@ -270,7 +272,8 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], return ; error: - do_reset (cmdtp, flag, argc, argv); + if (images->autostart) + do_reset (cmdtp, flag, argc, argv); return ; } -- cgit v1.2.1 From 9a4daad0a35eb5143037eea9f786a3e9d672bdd6 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Fri, 29 Feb 2008 14:58:34 +0100 Subject: [new uImage] Update naming convention for bootm/uImage related code This patch introduces the following prefix convention for the image format handling and bootm related code: genimg_ - dual format shared code image_ - legacy uImage format specific code fit_ - new uImage format specific code boot_ - booting process related code Related routines are renamed and a few pieces of code are moved around and re-grouped. Signed-off-by: Marian Balakowicz --- lib_ppc/bootm.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 1afef46df7..8974ccd81c 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -41,9 +41,9 @@ #include static void fdt_error (const char *msg); -static int get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], +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 fdt_relocate (struct lmb *lmb, ulong bootmap_base, +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 @@ -122,7 +122,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], #if defined(CONFIG_OF_LIBFDT) /* find flattened device tree */ - ret = get_fdt (cmdtp, flag, argc, argv, images, &of_flat_tree, &of_size); + ret = boot_get_fdt (cmdtp, flag, argc, argv, images, &of_flat_tree, &of_size); if (ret) goto error; @@ -130,14 +130,14 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], if (!of_size) { /* allocate space and init command line */ - ret = get_boot_cmdline (lmb, &cmd_start, &cmd_end, bootmap_base); + ret = boot_get_cmdline (lmb, &cmd_start, &cmd_end, bootmap_base); if (ret) { puts("ERROR with allocation of cmdline\n"); goto error; } /* allocate space for kernel copy of board info */ - ret = get_boot_kbd (lmb, &kbd, bootmap_base); + ret = boot_get_kbd (lmb, &kbd, bootmap_base); if (ret) { puts("ERROR with allocation of kernel bd\n"); goto error; @@ -160,7 +160,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; /* find ramdisk */ - ret = get_ramdisk (cmdtp, flag, argc, argv, images, + ret = boot_get_ramdisk (cmdtp, flag, argc, argv, images, IH_ARCH_PPC, &rd_data_start, &rd_data_end); if (ret) @@ -169,7 +169,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], rd_len = rd_data_end - rd_data_start; #if defined(CONFIG_OF_LIBFDT) - ret = fdt_relocate (lmb, bootmap_base, + ret = boot_relocate_fdt (lmb, bootmap_base, cmdtp, flag, argc, argv, &of_flat_tree, &of_size); /* @@ -201,7 +201,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], } #endif /* CONFIG_OF_LIBFDT */ - ret = ramdisk_high (lmb, rd_data_start, rd_len, &initrd_start, &initrd_end); + ret = boot_ramdisk_high (lmb, rd_data_start, rd_len, &initrd_start, &initrd_end); if (ret) goto error; @@ -354,7 +354,7 @@ static image_header_t *image_get_fdt (ulong fdt_addr) return fdt_hdr; } -static int get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], +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; @@ -403,14 +403,14 @@ static int get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], fdt_addr); /* copy from dataflash if needed */ - fdt_addr = gen_get_image (fdt_addr); + 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 (gen_image_get_format ((void *)fdt_addr)) { + switch (genimg_get_format ((void *)fdt_addr)) { case IMAGE_FORMAT_LEGACY: debug ("* fdt: legacy format image\n"); @@ -527,7 +527,7 @@ error: return 1; } -static int fdt_relocate (struct lmb *lmb, ulong bootmap_base, +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) { -- cgit v1.2.1 From 05e07b1ea22844e946cfcf7d5e8a0199d18d2a95 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Fri, 29 Feb 2008 22:22:46 +0100 Subject: [new uImage] Fix FDT blob totalsize calculation in boot_relocate_fdt() Do not use global fdt blob pointer, calculate blob size from routine argument blob pointer. Signed-off-by: Marian Balakowicz --- lib_ppc/bootm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 8974ccd81c..797715773d 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -557,7 +557,7 @@ static int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, if (fdt_blob >= (char *)CFG_BOOTMAPSZ) relocate = 1; - of_len = be32_to_cpu (fdt_totalsize (fdt)); + of_len = be32_to_cpu (fdt_totalsize (fdt_blob)); /* move flattend device tree if needed */ if (relocate) { -- cgit v1.2.1 From d985c8498c4e47095820da97aa722381d39172c5 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 10:14:38 +0100 Subject: [new uImage] Remove unnecessary arguments passed to ramdisk routines boot_get_ramdisk() and image_get_ramdisk() do not need all cmdtp, flag, argc and argv arguments. Simplify routines definition. Signed-off-by: Marian Balakowicz --- lib_ppc/bootm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 797715773d..ac06b2667e 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -160,9 +160,8 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; /* find ramdisk */ - ret = boot_get_ramdisk (cmdtp, flag, argc, argv, images, - IH_ARCH_PPC, &rd_data_start, &rd_data_end); - + ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_PPC, + &rd_data_start, &rd_data_end); if (ret) goto error; -- cgit v1.2.1 From bc8ed486b125452ba3bd8344f052f437329150c5 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 10:32:53 +0100 Subject: [new uImage] ppc: Add new uImage format support to FDT handling routines Support for new (FIT) format uImages is added to powerpc specific boot_get_fdt() routine which now recognizes, sanity checks FIT image and is able to access data sections of the requested component image. Signed-off-by: Marian Balakowicz --- lib_ppc/bootm.c | 174 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 151 insertions(+), 23 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index ac06b2667e..60bc04b413 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -254,20 +254,24 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], * r6: NULL * r7: NULL */ + debug (" Booting using OF flat tree...\n"); (*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0); /* does not return */ - } + } else #endif - /* - * Linux Kernel Parameters (passing board info data): - * r3: ptr to board info data - * r4: initrd_start or 0 if no initrd - * r5: initrd_end - unused if r4 is 0 - * r6: Start of command line string - * r7: End of command line string - */ - (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); - /* does not return */ + { + /* + * Linux Kernel Parameters (passing board info data): + * r3: ptr to board info data + * r4: initrd_start or 0 if no initrd + * r5: initrd_end - unused if r4 is 0 + * r6: Start of command line string + * r7: End of command line string + */ + debug (" Booting using board info...\n"); + (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); + /* does not return */ + } return ; error: @@ -353,6 +357,47 @@ static image_header_t *image_get_fdt (ulong fdt_addr) 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) { @@ -366,8 +411,15 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], const char *fit_uname_config = NULL; const char *fit_uname_fdt = NULL; ulong default_addr; + int conf_noffset; + int fdt_noffset; + const void *data; + size_t size; #endif + *of_flat_tree = NULL; + *of_size = 0; + if (argc > 3) { #if defined(CONFIG_FIT) /* @@ -398,7 +450,7 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], fdt_addr); } - debug ("## Checking for 'FDT'/'FDT image' at %08lx\n", + debug ("## Checking for 'FDT'/'FDT Image' at %08lx\n", fdt_addr); /* copy from dataflash if needed */ @@ -411,10 +463,8 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], */ switch (genimg_get_format ((void *)fdt_addr)) { case IMAGE_FORMAT_LEGACY: - debug ("* fdt: legacy format image\n"); - /* verify fdt_addr points to a valid image header */ - printf ("## Flattened Device Tree Legacy Image at %08lx\n", + printf ("## Flattened Device Tree from Legacy Image at %08lx\n", fdt_addr); fdt_hdr = image_get_fdt (fdt_addr); if (!fdt_hdr) @@ -434,11 +484,15 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], fdt_error ("fdt overwritten"); goto error; } - memmove ((void *)image_get_load (fdt_hdr), + + 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 *)image_get_load (fdt_hdr); + fdt_blob = (char *)load_start; break; case IMAGE_FORMAT_FIT: /* @@ -448,14 +502,90 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], */ #if defined(CONFIG_FIT) /* check FDT blob vs FIT blob */ - if (0) { /* FIXME: call FIT format verification */ + if (fit_check_format ((const void *)fdt_addr)) { /* * FIT image */ fit_hdr = (void *)fdt_addr; - debug ("* fdt: FIT format image\n"); - fit_unsupported_reset ("PPC fdt"); - goto error; + 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 + */ + conf_noffset = fit_conf_get_node (fit_hdr, + fit_uname_config); + if (conf_noffset < 0) + goto error; + + fdt_noffset = fit_conf_get_fdt_node (fit_hdr, + conf_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) + 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; + break; } else #endif { @@ -509,8 +639,6 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], } } else { debug ("## No Flattened Device Tree\n"); - *of_flat_tree = NULL; - *of_size = 0; return 0; } -- cgit v1.2.1 From 3dfe110149311425919e6d6a14b561b4207498f1 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 10:32:59 +0100 Subject: [new uImage] Add node offsets for FIT images listed in struct bootm_headers This patch adds new node offset fields to struct bootm_headers and updates bootm_headers processing code to make use of them. Saved node offsets allow to avoid repeating fit_image_get_node() calls. Signed-off-by: Marian Balakowicz --- lib_ppc/bootm.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 60bc04b413..4d8ef35526 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -585,6 +585,7 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], images->fit_hdr_fdt = fit_hdr; images->fit_uname_fdt = fit_uname_fdt; + images->fit_noffset_fdt = fdt_noffset; break; } else #endif -- cgit v1.2.1 From cd7c596e9f561dbbc17b717277438aee78cde14f Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 10:33:00 +0100 Subject: [new uImage] Add new uImage format support to arch specific do_bootm_linux() routines This patch updates architecture specific implementations of do_bootm_linux() adding new uImage format handling for operations like get kernel entry point address, get kernel image data start address. Signed-off-by: Marian Balakowicz --- lib_ppc/bootm.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 4d8ef35526..86e104cdcc 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -150,8 +150,12 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ep = image_get_ep (images->legacy_hdr_os); #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { - fit_unsupported_reset ("PPC linux bootm"); - goto error; + 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"); -- cgit v1.2.1 From f773bea8e11f4a11c388dcee956b2444203e6b65 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 10:35:46 +0100 Subject: [new uImage] Add proper ramdisk/FDT handling when FIT configuration is used Save FIT configuration provied in the first bootm argument and use it when to get ramdisk/FDT subimages when second and third (ramdisk/FDT) arguments are not specified. Signed-off-by: Marian Balakowicz --- lib_ppc/bootm.c | 104 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 73 insertions(+), 31 deletions(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 86e104cdcc..8cdace2859 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -415,7 +415,7 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], const char *fit_uname_config = NULL; const char *fit_uname_fdt = NULL; ulong default_addr; - int conf_noffset; + int cfg_noffset; int fdt_noffset; const void *data; size_t size; @@ -424,35 +424,67 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], *of_flat_tree = NULL; *of_size = 0; - if (argc > 3) { + if (argc > 3 || genimg_has_config (images)) { #if defined(CONFIG_FIT) - /* - * 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 + 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); + { + 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); @@ -522,13 +554,21 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], * fit_conf_get_node() will try to * find default config node */ - conf_noffset = fit_conf_get_node (fit_hdr, + cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); - if (conf_noffset < 0) + + 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, - conf_noffset); + cfg_noffset); fit_uname_fdt = fit_get_name (fit_hdr, fdt_noffset, NULL); } else { @@ -536,8 +576,10 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], fdt_noffset = fit_image_get_node (fit_hdr, fit_uname_fdt); } - if (fdt_noffset < 0) + if (fdt_noffset < 0) { + fdt_error ("Could not find subimage node\n"); goto error; + } printf (" Trying '%s' FDT blob subimage\n", fit_uname_fdt); -- cgit v1.2.1 From dafaede8a46c7159310239e036c93e31c6374487 Mon Sep 17 00:00:00 2001 From: Bartlomiej Sieka Date: Thu, 20 Mar 2008 23:20:31 +0100 Subject: [new uImage] Disable debuging output in preparation for merge with master Signed-off-by: Bartlomiej Sieka --- lib_ppc/bootm.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib_ppc') diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 8cdace2859..89463e342f 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -23,7 +23,6 @@ * MA 02111-1307 USA */ -#define DEBUG #include #include -- cgit v1.2.1