diff options
Diffstat (limited to 'common/cmd_bootm.c')
-rw-r--r-- | common/cmd_bootm.c | 143 |
1 files changed, 114 insertions, 29 deletions
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 7aae8a6..a6499e8 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -34,7 +34,12 @@ #include <environment.h> #include <asm/byteorder.h> -#ifdef CONFIG_OF_FLAT_TREE +#if defined(CONFIG_OF_LIBFDT) +#include <fdt.h> +#include <libfdt.h> +#include <fdt_support.h> +#endif +#if defined(CONFIG_OF_FLAT_TREE) #include <ft_build.h> #endif @@ -242,26 +247,26 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) len_ptr = (ulong *)data; -#if defined(__PPC__) - if (hdr->ih_arch != IH_CPU_PPC) -#elif defined(__ARM__) +#if defined(__ARM__) if (hdr->ih_arch != IH_CPU_ARM) +#elif defined(__avr32__) + if (hdr->ih_arch != IH_CPU_AVR32) +#elif defined(__bfin__) + if (hdr->ih_arch != IH_CPU_BLACKFIN) #elif defined(__I386__) if (hdr->ih_arch != IH_CPU_I386) -#elif defined(__mips__) - if (hdr->ih_arch != IH_CPU_MIPS) -#elif defined(__nios__) - if (hdr->ih_arch != IH_CPU_NIOS) #elif defined(__M68K__) if (hdr->ih_arch != IH_CPU_M68K) #elif defined(__microblaze__) if (hdr->ih_arch != IH_CPU_MICROBLAZE) +#elif defined(__mips__) + if (hdr->ih_arch != IH_CPU_MIPS) +#elif defined(__nios__) + if (hdr->ih_arch != IH_CPU_NIOS) #elif defined(__nios2__) if (hdr->ih_arch != IH_CPU_NIOS2) -#elif defined(__blackfin__) - if (hdr->ih_arch != IH_CPU_BLACKFIN) -#elif defined(__avr32__) - if (hdr->ih_arch != IH_CPU_AVR32) +#elif defined(__PPC__) + if (hdr->ih_arch != IH_CPU_PPC) #else # error Unknown CPU type #endif @@ -467,7 +472,7 @@ U_BOOT_CMD( "[addr [arg ...]]\n - boot application image stored in memory\n" "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n" "\t'arg' can be the address of an initrd image\n" -#ifdef CONFIG_OF_FLAT_TREE +#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) "\tWhen booting a Linux kernel which requires a flat device-tree\n" "\ta third argument is required which is the address of the of the\n" "\tdevice-tree blob. To boot that kernel without an initrd image,\n" @@ -529,7 +534,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, bd_t *kbd; void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); image_header_t *hdr = &header; -#ifdef CONFIG_OF_FLAT_TREE +#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) char *of_flat_tree = NULL; ulong of_data = 0; #endif @@ -622,7 +627,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, * Check if there is an initrd image */ -#ifdef CONFIG_OF_FLAT_TREE +#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"); @@ -739,12 +744,15 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, len = data = 0; } -#ifdef CONFIG_OF_FLAT_TREE +#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 (*(ulong *)of_flat_tree == OF_DT_HEADER) { +#if defined(CONFIG_OF_LIBFDT) + if (fdt_check_header(of_flat_tree) == 0) { +#else + if (*(ulong *)of_flat_tree == OF_DT_HEADER) { +#endif #ifndef CFG_NO_FLASH if (addr2info((ulong)of_flat_tree) != NULL) of_data = (ulong)of_flat_tree; @@ -771,9 +779,8 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, checksum = ntohl(hdr->ih_dcrc); addr = (ulong)((uchar *)(hdr) + sizeof(image_header_t)); - len = ntohl(hdr->ih_size); - if(checksum != crc32(0, (uchar *)addr, len)) { + if(checksum != crc32(0, (uchar *)addr, ntohl(hdr->ih_size))) { printf("ERROR: Flat Device Tree checksum is invalid\n"); return; } @@ -787,7 +794,11 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, printf("ERROR: uImage is not uncompressed\n"); return; } +#if defined(CONFIG_OF_LIBFDT) + if (fdt_check_header(of_flat_tree + sizeof(image_header_t)) == 0) { +#else if (*((ulong *)(of_flat_tree + sizeof(image_header_t))) != OF_DT_HEADER) { +#endif printf ("ERROR: uImage data is not a flat device tree\n"); return; } @@ -824,12 +835,20 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, of_data += 4 - tail; } +#if defined(CONFIG_OF_LIBFDT) + if (fdt_check_header((void *)of_data) != 0) { +#else if (((struct boot_param_header *)of_data)->magic != OF_DT_HEADER) { +#endif printf ("ERROR: image is not a flat device tree\n"); return; } +#if defined(CONFIG_OF_LIBFDT) + if (be32_to_cpu(fdt_totalsize(of_data)) != ntohl(len_ptr[2])) { +#else if (((struct boot_param_header *)of_data)->totalsize != ntohl(len_ptr[2])) { +#endif printf ("ERROR: flat device tree size does not agree with image\n"); return; } @@ -913,7 +932,52 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, unlock_ram_in_cache(); #endif -#ifdef CONFIG_OF_FLAT_TREE +#if defined(CONFIG_OF_LIBFDT) + /* 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 initrd/kbd */ + if (initrd_start) + of_start = initrd_start - of_len; + else + 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_start, (void *)of_data, of_len); + if (err != 0) { + printf ("libfdt: %s " __FILE__ " %d\n", fdt_strerror(err), __LINE__); + } + /* + * Add the chosen node if it doesn't exist, add the env and bd_t + * if the user wants it (the logic is in the subroutines). + */ + if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) { + printf("Failed creating the /chosen node (0x%08X), aborting.\n", of_flat_tree); + return; + } +#ifdef CONFIG_OF_HAS_UBOOT_ENV + if (fdt_env(of_flat_tree) < 0) { + printf("Failed creating the /u-boot-env node, aborting.\n"); + return; + } +#endif +#ifdef CONFIG_OF_HAS_BD_T + if (fdt_bd_t(of_flat_tree) < 0) { + printf("Failed creating the /bd_t node, aborting.\n"); + return; + } +#endif + } +#endif +#if defined(CONFIG_OF_FLAT_TREE) /* move of_flat_tree if needed */ if (of_data) { ulong of_start, of_len; @@ -942,13 +1006,13 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, * r6: Start of command line string * r7: End of command line string */ -#ifdef CONFIG_OF_FLAT_TREE +#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) if (!of_flat_tree) /* no device tree; boot old style */ #endif (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); /* does not return */ -#ifdef CONFIG_OF_FLAT_TREE +#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) /* * Linux Kernel Parameters (passing device tree): * r3: ptr to OF flat tree, followed by the board info data @@ -957,8 +1021,28 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, * r6: NULL * r7: NULL */ +#if defined(CONFIG_OF_FLAT_TREE) ft_setup(of_flat_tree, kbd, initrd_start, initrd_end); /* ft_dump_blob(of_flat_tree); */ +#endif +#if defined(CONFIG_OF_LIBFDT) + if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) { + printf("Failed creating the /chosen node (0x%08X), aborting.\n", of_flat_tree); + return; + } +#ifdef CONFIG_OF_HAS_UBOOT_ENV + if (fdt_env(of_flat_tree) < 0) { + printf("Failed creating the /u-boot-env node, aborting.\n"); + return; + } +#endif +#ifdef CONFIG_OF_HAS_BD_T + if (fdt_bd_t(of_flat_tree) < 0) { + printf("Failed creating the /bd_t node, aborting.\n"); + return; + } +#endif +#endif /* if defined(CONFIG_OF_LIBFDT) */ (*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0); #endif @@ -1354,19 +1438,20 @@ print_type (image_header_t *hdr) case IH_CPU_ALPHA: arch = "Alpha"; break; case IH_CPU_ARM: arch = "ARM"; break; case IH_CPU_AVR32: arch = "AVR32"; break; + case IH_CPU_BLACKFIN: arch = "Blackfin"; break; case IH_CPU_I386: arch = "Intel x86"; break; case IH_CPU_IA64: arch = "IA64"; break; - case IH_CPU_MIPS: arch = "MIPS"; break; + case IH_CPU_M68K: arch = "M68K"; break; + case IH_CPU_MICROBLAZE: arch = "Microblaze"; break; case IH_CPU_MIPS64: arch = "MIPS 64 Bit"; break; + case IH_CPU_MIPS: arch = "MIPS"; break; + case IH_CPU_NIOS2: arch = "Nios-II"; break; + case IH_CPU_NIOS: arch = "Nios"; break; case IH_CPU_PPC: arch = "PowerPC"; break; case IH_CPU_S390: arch = "IBM S390"; break; case IH_CPU_SH: arch = "SuperH"; break; - case IH_CPU_SPARC: arch = "SPARC"; break; case IH_CPU_SPARC64: arch = "SPARC 64 Bit"; break; - case IH_CPU_M68K: arch = "M68K"; break; - case IH_CPU_MICROBLAZE: arch = "Microblaze"; break; - case IH_CPU_NIOS: arch = "Nios"; break; - case IH_CPU_NIOS2: arch = "Nios-II"; break; + case IH_CPU_SPARC: arch = "SPARC"; break; default: arch = "Unknown Architecture"; break; } |