123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- /*
- * (C) Copyright 2008 - 2013 Tensilica Inc.
- * (C) Copyright 2014 Cadence Design Systems Inc.
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
- #include <common.h>
- #include <command.h>
- #include <u-boot/zlib.h>
- #include <asm/byteorder.h>
- #include <asm/addrspace.h>
- #include <asm/bootparam.h>
- #include <asm/cache.h>
- #include <image.h>
- DECLARE_GLOBAL_DATA_PTR;
- /*
- * Setup boot-parameters.
- */
- static struct bp_tag *setup_first_tag(struct bp_tag *params)
- {
- params->id = BP_TAG_FIRST;
- params->size = sizeof(long);
- *(unsigned long *)¶ms->data = BP_VERSION;
- return bp_tag_next(params);
- }
- static struct bp_tag *setup_last_tag(struct bp_tag *params)
- {
- params->id = BP_TAG_LAST;
- params->size = 0;
- return bp_tag_next(params);
- }
- static struct bp_tag *setup_memory_tag(struct bp_tag *params)
- {
- struct bd_info *bd = gd->bd;
- struct meminfo *mem;
- params->id = BP_TAG_MEMORY;
- params->size = sizeof(struct meminfo);
- mem = (struct meminfo *)params->data;
- mem->type = MEMORY_TYPE_CONVENTIONAL;
- mem->start = bd->bi_memstart;
- mem->end = bd->bi_memstart + bd->bi_memsize;
- printf(" MEMORY: tag:0x%04x, type:0X%lx, start:0X%lx, end:0X%lx\n",
- BP_TAG_MEMORY, mem->type, mem->start, mem->end);
- return bp_tag_next(params);
- }
- static struct bp_tag *setup_commandline_tag(struct bp_tag *params,
- char *cmdline)
- {
- int len;
- if (!cmdline)
- return params;
- len = strlen(cmdline);
- params->id = BP_TAG_COMMAND_LINE;
- params->size = (len + 3) & -4;
- strcpy((char *)params->data, cmdline);
- printf(" COMMAND_LINE: tag:0x%04x, size:%u, data:'%s'\n",
- BP_TAG_COMMAND_LINE, params->size, cmdline);
- return bp_tag_next(params);
- }
- static struct bp_tag *setup_ramdisk_tag(struct bp_tag *params,
- unsigned long rd_start,
- unsigned long rd_end)
- {
- struct meminfo *mem;
- if (rd_start == rd_end)
- return params;
- /* Add a single banked memory */
- params->id = BP_TAG_INITRD;
- params->size = sizeof(struct meminfo);
- mem = (struct meminfo *)params->data;
- mem->type = MEMORY_TYPE_CONVENTIONAL;
- mem->start = PHYSADDR(rd_start);
- mem->end = PHYSADDR(rd_end);
- printf(" INITRD: tag:0x%x, type:0X%04lx, start:0X%lx, end:0X%lx\n",
- BP_TAG_INITRD, mem->type, mem->start, mem->end);
- return bp_tag_next(params);
- }
- static struct bp_tag *setup_serial_tag(struct bp_tag *params)
- {
- params->id = BP_TAG_SERIAL_BAUDRATE;
- params->size = sizeof(unsigned long);
- params->data[0] = gd->baudrate;
- printf(" SERIAL_BAUDRATE: tag:0x%04x, size:%u, baudrate:%lu\n",
- BP_TAG_SERIAL_BAUDRATE, params->size, params->data[0]);
- return bp_tag_next(params);
- }
- #ifdef CONFIG_OF_LIBFDT
- static struct bp_tag *setup_fdt_tag(struct bp_tag *params, void *fdt_start)
- {
- params->id = BP_TAG_FDT;
- params->size = sizeof(unsigned long);
- params->data[0] = (unsigned long)fdt_start;
- printf(" FDT: tag:0x%04x, size:%u, start:0x%lx\n",
- BP_TAG_FDT, params->size, params->data[0]);
- return bp_tag_next(params);
- }
- #endif
- /*
- * Boot Linux.
- */
- int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
- {
- struct bp_tag *params, *params_start;
- ulong initrd_start, initrd_end;
- char *commandline = getenv("bootargs");
- if (!(flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)))
- return 0;
- show_boot_progress(15);
- if (images->rd_start) {
- initrd_start = images->rd_start;
- initrd_end = images->rd_end;
- } else {
- initrd_start = 0;
- initrd_end = 0;
- }
- params_start = (struct bp_tag *)gd->bd->bi_boot_params;
- params = params_start;
- params = setup_first_tag(params);
- params = setup_memory_tag(params);
- params = setup_commandline_tag(params, commandline);
- params = setup_serial_tag(params);
- if (initrd_start)
- params = setup_ramdisk_tag(params, initrd_start, initrd_end);
- #ifdef CONFIG_OF_LIBFDT
- if (images->ft_addr)
- params = setup_fdt_tag(params, images->ft_addr);
- #endif
- printf("\n");
- params = setup_last_tag(params);
- show_boot_progress(15);
- printf("Transferring Control to Linux @0x%08lx ...\n\n",
- (ulong)images->ep);
- flush_dcache_range((unsigned long)params_start, (unsigned long)params);
- if (flag & BOOTM_STATE_OS_FAKE_GO)
- return 0;
- /*
- * _start() in vmlinux expects boot params in register a2.
- * NOTE:
- * Disable/delete your u-boot breakpoints before stepping into linux.
- */
- asm volatile ("mov a2, %0\n\t"
- "jx %1\n\t"
- : : "a" (params_start), "a" (images->ep)
- : "a2");
- /* Does not return */
- return 1;
- }
|