708025b207133525a2863dca1bd0a82b7e9ebcf6
[platform/kernel/u-boot.git] / arch / x86 / lib / zimage.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2011 The Chromium OS Authors.
4  * (C) Copyright 2002
5  * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
6  */
7
8 /*
9  * Linux x86 zImage and bzImage loading
10  *
11  * based on the procdure described in
12  * linux/Documentation/i386/boot.txt
13  */
14
15 #define LOG_CATEGORY    LOGC_BOOT
16
17 #include <common.h>
18 #include <bootm.h>
19 #include <command.h>
20 #include <env.h>
21 #include <irq_func.h>
22 #include <log.h>
23 #include <malloc.h>
24 #include <acpi/acpi_table.h>
25 #include <asm/io.h>
26 #include <asm/ptrace.h>
27 #include <asm/zimage.h>
28 #include <asm/byteorder.h>
29 #include <asm/bootm.h>
30 #include <asm/bootparam.h>
31 #ifdef CONFIG_SYS_COREBOOT
32 #include <asm/arch/timestamp.h>
33 #endif
34 #include <linux/compiler.h>
35 #include <linux/ctype.h>
36 #include <linux/libfdt.h>
37
38 /*
39  * Memory lay-out:
40  *
41  * relative to setup_base (which is 0x90000 currently)
42  *
43  *      0x0000-0x7FFF   Real mode kernel
44  *      0x8000-0x8FFF   Stack and heap
45  *      0x9000-0x90FF   Kernel command line
46  */
47 #define DEFAULT_SETUP_BASE      0x90000
48 #define COMMAND_LINE_OFFSET     0x9000
49 #define HEAP_END_OFFSET         0x8e00
50
51 #define COMMAND_LINE_SIZE       2048
52
53 /**
54  * struct zboot_state - Current state of the boot
55  *
56  * @bzimage_addr: Address of the bzImage to boot
57  * @bzimage_size: Size of the bzImage, or 0 to detect this
58  * @initrd_addr: Address of the initial ramdisk, or 0 if none
59  * @initrd_size: Size of the initial ramdisk, or 0 if none
60  * @load_address: Address where the bzImage is moved before booting, either
61  *      BZIMAGE_LOAD_ADDR or ZIMAGE_LOAD_ADDR
62  * @base_ptr: Pointer to the boot parameters, typically at address
63  *      DEFAULT_SETUP_BASE
64  * @cmdline: Environment variable containing the 'override' command line, or
65  *      NULL to use the one in the setup block
66  */
67 struct zboot_state {
68         ulong bzimage_addr;
69         ulong bzimage_size;
70         ulong initrd_addr;
71         ulong initrd_size;
72         ulong load_address;
73         struct boot_params *base_ptr;
74         char *cmdline;
75 } state;
76
77 enum {
78         ZBOOT_STATE_START       = BIT(0),
79         ZBOOT_STATE_LOAD        = BIT(1),
80         ZBOOT_STATE_SETUP       = BIT(2),
81         ZBOOT_STATE_INFO        = BIT(3),
82         ZBOOT_STATE_GO          = BIT(4),
83
84         /* This one doesn't execute automatically, so stop the count before 5 */
85         ZBOOT_STATE_DUMP        = BIT(5),
86         ZBOOT_STATE_COUNT       = 5,
87 };
88
89 static void build_command_line(char *command_line, int auto_boot)
90 {
91         char *env_command_line;
92
93         command_line[0] = '\0';
94
95         env_command_line =  env_get("bootargs");
96
97         /* set console= argument if we use a serial console */
98         if (!strstr(env_command_line, "console=")) {
99                 if (!strcmp(env_get("stdout"), "serial")) {
100
101                         /* We seem to use serial console */
102                         sprintf(command_line, "console=ttyS0,%s ",
103                                 env_get("baudrate"));
104                 }
105         }
106
107         if (auto_boot)
108                 strcat(command_line, "auto ");
109
110         if (env_command_line)
111                 strcat(command_line, env_command_line);
112
113         printf("Kernel command line: \"%s\"\n", command_line);
114 }
115
116 static int kernel_magic_ok(struct setup_header *hdr)
117 {
118         if (KERNEL_MAGIC != hdr->boot_flag) {
119                 printf("Error: Invalid Boot Flag "
120                         "(found 0x%04x, expected 0x%04x)\n",
121                         hdr->boot_flag, KERNEL_MAGIC);
122                 return 0;
123         } else {
124                 printf("Valid Boot Flag\n");
125                 return 1;
126         }
127 }
128
129 static int get_boot_protocol(struct setup_header *hdr, bool verbose)
130 {
131         if (hdr->header == KERNEL_V2_MAGIC) {
132                 if (verbose)
133                         printf("Magic signature found\n");
134                 return hdr->version;
135         } else {
136                 /* Very old kernel */
137                 if (verbose)
138                         printf("Magic signature not found\n");
139                 return 0x0100;
140         }
141 }
142
143 static int setup_device_tree(struct setup_header *hdr, const void *fdt_blob)
144 {
145         int bootproto = get_boot_protocol(hdr, false);
146         struct setup_data *sd;
147         int size;
148
149         if (bootproto < 0x0209)
150                 return -ENOTSUPP;
151
152         if (!fdt_blob)
153                 return 0;
154
155         size = fdt_totalsize(fdt_blob);
156         if (size < 0)
157                 return -EINVAL;
158
159         size += sizeof(struct setup_data);
160         sd = (struct setup_data *)malloc(size);
161         if (!sd) {
162                 printf("Not enough memory for DTB setup data\n");
163                 return -ENOMEM;
164         }
165
166         sd->next = hdr->setup_data;
167         sd->type = SETUP_DTB;
168         sd->len = fdt_totalsize(fdt_blob);
169         memcpy(sd->data, fdt_blob, sd->len);
170         hdr->setup_data = (unsigned long)sd;
171
172         return 0;
173 }
174
175 static const char *get_kernel_version(struct boot_params *params,
176                                       void *kernel_base)
177 {
178         struct setup_header *hdr = &params->hdr;
179         int bootproto;
180         const char *s, *end;
181
182         bootproto = get_boot_protocol(hdr, false);
183         if (bootproto < 0x0200 || hdr->setup_sects < 15)
184                 return NULL;
185
186         /* sanity-check the kernel version in case it is missing */
187         for (s = kernel_base + hdr->kernel_version + 0x200, end = s + 0x100; *s;
188              s++) {
189                 if (!isprint(*s))
190                         return NULL;
191         }
192
193         return kernel_base + hdr->kernel_version + 0x200;
194 }
195
196 struct boot_params *load_zimage(char *image, unsigned long kernel_size,
197                                 ulong *load_addressp)
198 {
199         struct boot_params *setup_base;
200         const char *version;
201         int setup_size;
202         int bootproto;
203         int big_image;
204
205         struct boot_params *params = (struct boot_params *)image;
206         struct setup_header *hdr = &params->hdr;
207
208         /* base address for real-mode segment */
209         setup_base = (struct boot_params *)DEFAULT_SETUP_BASE;
210
211         if (!kernel_magic_ok(hdr))
212                 return 0;
213
214         /* determine size of setup */
215         if (0 == hdr->setup_sects) {
216                 log_warning("Setup Sectors = 0 (defaulting to 4)\n");
217                 setup_size = 5 * 512;
218         } else {
219                 setup_size = (hdr->setup_sects + 1) * 512;
220         }
221
222         log_debug("Setup Size = 0x%8.8lx\n", (ulong)setup_size);
223
224         if (setup_size > SETUP_MAX_SIZE)
225                 printf("Error: Setup is too large (%d bytes)\n", setup_size);
226
227         /* determine boot protocol version */
228         bootproto = get_boot_protocol(hdr, true);
229
230         log_debug("Using boot protocol version %x.%02x\n",
231                   (bootproto & 0xff00) >> 8, bootproto & 0xff);
232
233         version = get_kernel_version(params, image);
234         if (version)
235                 printf("Linux kernel version %s\n", version);
236         else
237                 printf("Setup Sectors < 15 - Cannot print kernel version\n");
238
239         /* Determine image type */
240         big_image = (bootproto >= 0x0200) &&
241                     (hdr->loadflags & BIG_KERNEL_FLAG);
242
243         /* Determine load address */
244         if (big_image)
245                 *load_addressp = BZIMAGE_LOAD_ADDR;
246         else
247                 *load_addressp = ZIMAGE_LOAD_ADDR;
248
249         printf("Building boot_params at 0x%8.8lx\n", (ulong)setup_base);
250         memset(setup_base, 0, sizeof(*setup_base));
251         setup_base->hdr = params->hdr;
252
253         if (bootproto >= 0x0204)
254                 kernel_size = hdr->syssize * 16;
255         else
256                 kernel_size -= setup_size;
257
258         if (bootproto == 0x0100) {
259                 /*
260                  * A very old kernel MUST have its real-mode code
261                  * loaded at 0x90000
262                  */
263                 if ((ulong)setup_base != 0x90000) {
264                         /* Copy the real-mode kernel */
265                         memmove((void *)0x90000, setup_base, setup_size);
266
267                         /* Copy the command line */
268                         memmove((void *)0x99000,
269                                 (u8 *)setup_base + COMMAND_LINE_OFFSET,
270                                 COMMAND_LINE_SIZE);
271
272                          /* Relocated */
273                         setup_base = (struct boot_params *)0x90000;
274                 }
275
276                 /* It is recommended to clear memory up to the 32K mark */
277                 memset((u8 *)0x90000 + setup_size, 0,
278                        SETUP_MAX_SIZE - setup_size);
279         }
280
281         if (big_image) {
282                 if (kernel_size > BZIMAGE_MAX_SIZE) {
283                         printf("Error: bzImage kernel too big! "
284                                 "(size: %ld, max: %d)\n",
285                                 kernel_size, BZIMAGE_MAX_SIZE);
286                         return 0;
287                 }
288         } else if ((kernel_size) > ZIMAGE_MAX_SIZE) {
289                 printf("Error: zImage kernel too big! (size: %ld, max: %d)\n",
290                        kernel_size, ZIMAGE_MAX_SIZE);
291                 return 0;
292         }
293
294         printf("Loading %s at address %lx (%ld bytes)\n",
295                big_image ? "bzImage" : "zImage", *load_addressp, kernel_size);
296
297         memmove((void *)*load_addressp, image + setup_size, kernel_size);
298
299         return setup_base;
300 }
301
302 int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot,
303                  ulong initrd_addr, ulong initrd_size, ulong cmdline_force)
304 {
305         struct setup_header *hdr = &setup_base->hdr;
306         int bootproto = get_boot_protocol(hdr, false);
307
308         log_debug("Setup E820 entries\n");
309         setup_base->e820_entries = install_e820_map(
310                 ARRAY_SIZE(setup_base->e820_map), setup_base->e820_map);
311
312         if (bootproto == 0x0100) {
313                 setup_base->screen_info.cl_magic = COMMAND_LINE_MAGIC;
314                 setup_base->screen_info.cl_offset = COMMAND_LINE_OFFSET;
315         }
316         if (bootproto >= 0x0200) {
317                 hdr->type_of_loader = 0x80;     /* U-Boot version 0 */
318                 if (initrd_addr) {
319                         printf("Initial RAM disk at linear address "
320                                "0x%08lx, size %ld bytes\n",
321                                initrd_addr, initrd_size);
322
323                         hdr->ramdisk_image = initrd_addr;
324                         hdr->ramdisk_size = initrd_size;
325                 }
326         }
327
328         if (bootproto >= 0x0201) {
329                 hdr->heap_end_ptr = HEAP_END_OFFSET;
330                 hdr->loadflags |= HEAP_FLAG;
331         }
332
333         if (cmd_line) {
334                 int max_size = 0xff;
335                 int ret;
336
337                 log_debug("Setup cmdline\n");
338                 if (bootproto >= 0x0206)
339                         max_size = hdr->cmdline_size;
340                 if (bootproto >= 0x0202) {
341                         hdr->cmd_line_ptr = (uintptr_t)cmd_line;
342                 } else if (bootproto >= 0x0200) {
343                         setup_base->screen_info.cl_magic = COMMAND_LINE_MAGIC;
344                         setup_base->screen_info.cl_offset =
345                                 (uintptr_t)cmd_line - (uintptr_t)setup_base;
346
347                         hdr->setup_move_size = 0x9100;
348                 }
349
350                 /* build command line at COMMAND_LINE_OFFSET */
351                 if (cmdline_force)
352                         strcpy(cmd_line, (char *)cmdline_force);
353                 else
354                         build_command_line(cmd_line, auto_boot);
355                 ret = bootm_process_cmdline(cmd_line, max_size, BOOTM_CL_ALL);
356                 if (ret) {
357                         printf("Cmdline setup failed (err=%d)\n", ret);
358                         return ret;
359                 }
360                 printf("Kernel command line: \"");
361                 puts(cmd_line);
362                 printf("\"\n");
363         }
364
365         if (IS_ENABLED(CONFIG_INTEL_MID) && bootproto >= 0x0207)
366                 hdr->hardware_subarch = X86_SUBARCH_INTEL_MID;
367
368         if (IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE))
369                 setup_base->acpi_rsdp_addr = acpi_get_rsdp_addr();
370
371         log_debug("Setup devicetree\n");
372         setup_device_tree(hdr, (const void *)env_get_hex("fdtaddr", 0));
373         setup_video(&setup_base->screen_info);
374
375         if (IS_ENABLED(CONFIG_EFI_STUB))
376                 setup_efi_info(&setup_base->efi_info);
377
378         return 0;
379 }
380
381 static int do_zboot_start(struct cmd_tbl *cmdtp, int flag, int argc,
382                           char *const argv[])
383 {
384         const char *s;
385
386         memset(&state, '\0', sizeof(state));
387         if (argc >= 2) {
388                 /* argv[1] holds the address of the bzImage */
389                 s = argv[1];
390         } else {
391                 s = env_get("fileaddr");
392         }
393
394         if (s)
395                 state.bzimage_addr = simple_strtoul(s, NULL, 16);
396
397         if (argc >= 3) {
398                 /* argv[2] holds the size of the bzImage */
399                 state.bzimage_size = simple_strtoul(argv[2], NULL, 16);
400         }
401
402         if (argc >= 4)
403                 state.initrd_addr = simple_strtoul(argv[3], NULL, 16);
404         if (argc >= 5)
405                 state.initrd_size = simple_strtoul(argv[4], NULL, 16);
406         if (argc >= 6) {
407                 /*
408                  * When the base_ptr is passed in, we assume that the image is
409                  * already loaded at the address given by argv[1] and therefore
410                  * the original bzImage is somewhere else, or not accessible.
411                  * In any case, we don't need access to the bzImage since all
412                  * the processing is assumed to be done.
413                  *
414                  * So set the base_ptr to the given address, use this arg as the
415                  * load address and set bzimage_addr to 0 so we know that it
416                  * cannot be proceesed (or processed again).
417                  */
418                 state.base_ptr = (void *)simple_strtoul(argv[5], NULL, 16);
419                 state.load_address = state.bzimage_addr;
420                 state.bzimage_addr = 0;
421         }
422         if (argc >= 7)
423                 state.cmdline = env_get(argv[6]);
424
425         return 0;
426 }
427
428 static int do_zboot_load(struct cmd_tbl *cmdtp, int flag, int argc,
429                          char *const argv[])
430 {
431         struct boot_params *base_ptr;
432
433         if (state.base_ptr) {
434                 struct boot_params *from = (struct boot_params *)state.base_ptr;
435
436                 base_ptr = (struct boot_params *)DEFAULT_SETUP_BASE;
437                 log_debug("Building boot_params at 0x%8.8lx\n",
438                           (ulong)base_ptr);
439                 memset(base_ptr, '\0', sizeof(*base_ptr));
440                 base_ptr->hdr = from->hdr;
441         } else {
442                 base_ptr = load_zimage((void *)state.bzimage_addr, state.bzimage_size,
443                                        &state.load_address);
444                 if (!base_ptr) {
445                         puts("## Kernel loading failed ...\n");
446                         return CMD_RET_FAILURE;
447                 }
448         }
449         state.base_ptr = base_ptr;
450         if (env_set_hex("zbootbase", (ulong)base_ptr) ||
451             env_set_hex("zbootaddr", state.load_address))
452                 return CMD_RET_FAILURE;
453
454         return 0;
455 }
456
457 static int do_zboot_setup(struct cmd_tbl *cmdtp, int flag, int argc,
458                           char *const argv[])
459 {
460         struct boot_params *base_ptr = state.base_ptr;
461         int ret;
462
463         if (!base_ptr) {
464                 printf("base is not set: use 'zboot load' first\n");
465                 return CMD_RET_FAILURE;
466         }
467         ret = setup_zimage(base_ptr, (char *)base_ptr + COMMAND_LINE_OFFSET,
468                            0, state.initrd_addr, state.initrd_size,
469                            (ulong)state.cmdline);
470         if (ret) {
471                 puts("Setting up boot parameters failed ...\n");
472                 return CMD_RET_FAILURE;
473         }
474
475         return 0;
476 }
477
478 static int do_zboot_info(struct cmd_tbl *cmdtp, int flag, int argc,
479                          char *const argv[])
480 {
481         printf("Kernel loaded at %08lx, setup_base=%p\n",
482                state.load_address, state.base_ptr);
483
484         return 0;
485 }
486
487 static int do_zboot_go(struct cmd_tbl *cmdtp, int flag, int argc,
488                        char *const argv[])
489 {
490         int ret;
491
492         disable_interrupts();
493
494         /* we assume that the kernel is in place */
495         ret = boot_linux_kernel((ulong)state.base_ptr, state.load_address,
496                                 false);
497         printf("Kernel returned! (err=%d)\n", ret);
498
499         return CMD_RET_FAILURE;
500 }
501
502 static void print_num(const char *name, ulong value)
503 {
504         printf("%-20s: %lx\n", name, value);
505 }
506
507 static void print_num64(const char *name, u64 value)
508 {
509         printf("%-20s: %llx\n", name, value);
510 }
511
512 static const char *const e820_type_name[E820_COUNT] = {
513         [E820_RAM] = "RAM",
514         [E820_RESERVED] = "Reserved",
515         [E820_ACPI] = "ACPI",
516         [E820_NVS] = "ACPI NVS",
517         [E820_UNUSABLE] = "Unusable",
518 };
519
520 static const char *const bootloader_id[] = {
521         "LILO",
522         "Loadlin",
523         "bootsect-loader",
524         "Syslinux",
525         "Etherboot/gPXE/iPXE",
526         "ELILO",
527         "undefined",
528         "GRUB",
529         "U-Boot",
530         "Xen",
531         "Gujin",
532         "Qemu",
533         "Arcturus Networks uCbootloader",
534         "kexec-tools",
535         "Extended",
536         "Special",
537         "Reserved",
538         "Minimal Linux Bootloader",
539         "OVMF UEFI virtualization stack",
540 };
541
542 struct flag_info {
543         uint bit;
544         const char *name;
545 };
546
547 static struct flag_info load_flags[] = {
548         { LOADED_HIGH, "loaded-high" },
549         { QUIET_FLAG, "quiet" },
550         { KEEP_SEGMENTS, "keep-segments" },
551         { CAN_USE_HEAP, "can-use-heap" },
552 };
553
554 static struct flag_info xload_flags[] = {
555         { XLF_KERNEL_64, "64-bit-entry" },
556         { XLF_CAN_BE_LOADED_ABOVE_4G, "can-load-above-4gb" },
557         { XLF_EFI_HANDOVER_32, "32-efi-handoff" },
558         { XLF_EFI_HANDOVER_64, "64-efi-handoff" },
559         { XLF_EFI_KEXEC, "kexec-efi-runtime" },
560 };
561
562 static void print_flags(struct flag_info *flags, int count, uint value)
563 {
564         int i;
565
566         printf("%-20s:", "");
567         for (i = 0; i < count; i++) {
568                 uint mask = flags[i].bit;
569
570                 if (value & mask)
571                         printf(" %s", flags[i].name);
572         }
573         printf("\n");
574 }
575
576 static void show_loader(struct setup_header *hdr)
577 {
578         bool version_valid = false;
579         int type, version;
580         const char *name;
581
582         type = hdr->type_of_loader >> 4;
583         version = hdr->type_of_loader & 0xf;
584         if (type == 0xe)
585                 type = 0x10 + hdr->ext_loader_type;
586         version |= hdr->ext_loader_ver << 4;
587         if (!hdr->type_of_loader) {
588                 name = "pre-2.00 bootloader";
589         } else if (hdr->type_of_loader == 0xff) {
590                 name = "unknown";
591         } else if (type < ARRAY_SIZE(bootloader_id)) {
592                 name = bootloader_id[type];
593                 version_valid = true;
594         } else {
595                 name = "undefined";
596         }
597         printf("%20s  %s", "", name);
598         if (version_valid)
599                 printf(", version %x", version);
600         printf("\n");
601 }
602
603 int do_zboot_dump(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
604 {
605         struct boot_params *base_ptr = state.base_ptr;
606         struct setup_header *hdr;
607         const char *version;
608         int i;
609
610         if (argc > 1)
611                 base_ptr = (void *)simple_strtoul(argv[1], NULL, 16);
612         if (!base_ptr) {
613                 printf("No zboot setup_base\n");
614                 return CMD_RET_FAILURE;
615         }
616         printf("Setup located at %p:\n\n", base_ptr);
617         print_num64("ACPI RSDP addr", base_ptr->acpi_rsdp_addr);
618
619         printf("E820: %d entries\n", base_ptr->e820_entries);
620         if (base_ptr->e820_entries) {
621                 printf("%18s  %16s  %s\n", "Addr", "Size", "Type");
622                 for (i = 0; i < base_ptr->e820_entries; i++) {
623                         struct e820_entry *entry = &base_ptr->e820_map[i];
624
625                         printf("%12llx  %10llx  %s\n", entry->addr, entry->size,
626                                entry->type < E820_COUNT ?
627                                e820_type_name[entry->type] :
628                                simple_itoa(entry->type));
629                 }
630         }
631
632         hdr = &base_ptr->hdr;
633         print_num("Setup sectors", hdr->setup_sects);
634         print_num("Root flags", hdr->root_flags);
635         print_num("Sys size", hdr->syssize);
636         print_num("RAM size", hdr->ram_size);
637         print_num("Video mode", hdr->vid_mode);
638         print_num("Root dev", hdr->root_dev);
639         print_num("Boot flag", hdr->boot_flag);
640         print_num("Jump", hdr->jump);
641         print_num("Header", hdr->header);
642         if (hdr->header == KERNEL_V2_MAGIC)
643                 printf("%-20s  %s\n", "", "Kernel V2");
644         else
645                 printf("%-20s  %s\n", "", "Ancient kernel, using version 100");
646         print_num("Version", hdr->version);
647         print_num("Real mode switch", hdr->realmode_swtch);
648         print_num("Start sys", hdr->start_sys);
649         print_num("Kernel version", hdr->kernel_version);
650         version = get_kernel_version(base_ptr, (void *)state.bzimage_addr);
651         if (version)
652                 printf("   @%p: %s\n", version, version);
653         print_num("Type of loader", hdr->type_of_loader);
654         show_loader(hdr);
655         print_num("Load flags", hdr->loadflags);
656         print_flags(load_flags, ARRAY_SIZE(load_flags), hdr->loadflags);
657         print_num("Setup move size", hdr->setup_move_size);
658         print_num("Code32 start", hdr->code32_start);
659         print_num("Ramdisk image", hdr->ramdisk_image);
660         print_num("Ramdisk size", hdr->ramdisk_size);
661         print_num("Bootsect kludge", hdr->bootsect_kludge);
662         print_num("Heap end ptr", hdr->heap_end_ptr);
663         print_num("Ext loader ver", hdr->ext_loader_ver);
664         print_num("Ext loader type", hdr->ext_loader_type);
665         print_num("Command line ptr", hdr->cmd_line_ptr);
666         if (hdr->cmd_line_ptr) {
667                 printf("   ");
668                 /* Use puts() to avoid limits from CONFIG_SYS_PBSIZE */
669                 puts((char *)(ulong)hdr->cmd_line_ptr);
670                 printf("\n");
671         }
672         print_num("Initrd addr max", hdr->initrd_addr_max);
673         print_num("Kernel alignment", hdr->kernel_alignment);
674         print_num("Relocatable kernel", hdr->relocatable_kernel);
675         print_num("Min alignment", hdr->min_alignment);
676         if (hdr->min_alignment)
677                 printf("%-20s: %x\n", "", 1 << hdr->min_alignment);
678         print_num("Xload flags", hdr->xloadflags);
679         print_flags(xload_flags, ARRAY_SIZE(xload_flags), hdr->xloadflags);
680         print_num("Cmdline size", hdr->cmdline_size);
681         print_num("Hardware subarch", hdr->hardware_subarch);
682         print_num64("HW subarch data", hdr->hardware_subarch_data);
683         print_num("Payload offset", hdr->payload_offset);
684         print_num("Payload length", hdr->payload_length);
685         print_num64("Setup data", hdr->setup_data);
686         print_num64("Pref address", hdr->pref_address);
687         print_num("Init size", hdr->init_size);
688         print_num("Handover offset", hdr->handover_offset);
689         if (get_boot_protocol(hdr, false) >= 0x215)
690                 print_num("Kernel info offset", hdr->kernel_info_offset);
691
692         return 0;
693 }
694
695 /* Note: This defines the complete_zboot() function */
696 U_BOOT_SUBCMDS(zboot,
697         U_BOOT_CMD_MKENT(start, 8, 1, do_zboot_start, "", ""),
698         U_BOOT_CMD_MKENT(load, 1, 1, do_zboot_load, "", ""),
699         U_BOOT_CMD_MKENT(setup, 1, 1, do_zboot_setup, "", ""),
700         U_BOOT_CMD_MKENT(info, 1, 1, do_zboot_info, "", ""),
701         U_BOOT_CMD_MKENT(go, 1, 1, do_zboot_go, "", ""),
702         U_BOOT_CMD_MKENT(dump, 2, 1, do_zboot_dump, "", ""),
703 )
704
705 int do_zboot_states(struct cmd_tbl *cmdtp, int flag, int argc,
706                     char *const argv[], int state_mask)
707 {
708         int i;
709
710         for (i = 0; i < ZBOOT_STATE_COUNT; i++) {
711                 struct cmd_tbl *cmd = &zboot_subcmds[i];
712                 int mask = 1 << i;
713                 int ret;
714
715                 if (mask & state_mask) {
716                         ret = cmd->cmd(cmd, flag, argc, argv);
717                         if (ret)
718                                 return ret;
719                 }
720         }
721
722         return 0;
723 }
724
725 int do_zboot_parent(struct cmd_tbl *cmdtp, int flag, int argc,
726                     char *const argv[], int *repeatable)
727 {
728         /* determine if we have a sub command */
729         if (argc > 1) {
730                 char *endp;
731
732                 simple_strtoul(argv[1], &endp, 16);
733                 /*
734                  * endp pointing to nul means that argv[1] was just a valid
735                  * number, so pass it along to the normal processing
736                  */
737                 if (*endp)
738                         return do_zboot(cmdtp, flag, argc, argv, repeatable);
739         }
740
741         do_zboot_states(cmdtp, flag, argc, argv, ZBOOT_STATE_START |
742                         ZBOOT_STATE_LOAD | ZBOOT_STATE_SETUP |
743                         ZBOOT_STATE_INFO | ZBOOT_STATE_GO);
744
745         return CMD_RET_FAILURE;
746 }
747
748 U_BOOT_CMDREP_COMPLETE(
749         zboot, 8, do_zboot_parent, "Boot bzImage",
750         "[addr] [size] [initrd addr] [initrd size] [setup] [cmdline]\n"
751         "      addr -        The optional starting address of the bzimage.\n"
752         "                    If not set it defaults to the environment\n"
753         "                    variable \"fileaddr\".\n"
754         "      size -        The optional size of the bzimage. Defaults to\n"
755         "                    zero.\n"
756         "      initrd addr - The address of the initrd image to use, if any.\n"
757         "      initrd size - The size of the initrd image to use, if any.\n"
758         "      setup -       The address of the kernel setup region, if this\n"
759         "                    is not at addr\n"
760         "      cmdline -     Environment variable containing the kernel\n"
761         "                    command line, to override U-Boot's normal\n"
762         "                    cmdline generation\n"
763         "\n"
764         "Sub-commands to do part of the zboot sequence:\n"
765         "\tstart [addr [arg ...]] - specify arguments\n"
766         "\tload   - load OS image\n"
767         "\tsetup  - set up table\n"
768         "\tinfo   - show summary info\n"
769         "\tgo     - start OS\n"
770         "\tdump [addr]    - dump info (optional address of boot params)",
771         complete_zboot
772 );