1 // SPDX-License-Identifier: GPL-2.0+
3 * (C) Copyright 2008 - 2013 Tensilica Inc.
4 * (C) Copyright 2014 Cadence Design Systems Inc.
12 #include <u-boot/zlib.h>
13 #include <asm/byteorder.h>
14 #include <asm/addrspace.h>
15 #include <asm/bootparam.h>
16 #include <asm/cache.h>
19 DECLARE_GLOBAL_DATA_PTR;
22 * Setup boot-parameters.
25 static struct bp_tag *setup_first_tag(struct bp_tag *params)
27 params->id = BP_TAG_FIRST;
28 params->size = sizeof(long);
29 *(unsigned long *)¶ms->data = BP_VERSION;
31 return bp_tag_next(params);
34 static struct bp_tag *setup_last_tag(struct bp_tag *params)
36 params->id = BP_TAG_LAST;
39 return bp_tag_next(params);
42 static struct bp_tag *setup_memory_tag(struct bp_tag *params)
44 struct bd_info *bd = gd->bd;
47 params->id = BP_TAG_MEMORY;
48 params->size = sizeof(struct meminfo);
49 mem = (struct meminfo *)params->data;
50 mem->type = MEMORY_TYPE_CONVENTIONAL;
51 mem->start = bd->bi_memstart;
52 mem->end = bd->bi_memstart + bd->bi_memsize;
54 printf(" MEMORY: tag:0x%04x, type:0X%lx, start:0X%lx, end:0X%lx\n",
55 BP_TAG_MEMORY, mem->type, mem->start, mem->end);
57 return bp_tag_next(params);
60 static struct bp_tag *setup_commandline_tag(struct bp_tag *params,
68 len = strlen(cmdline);
70 params->id = BP_TAG_COMMAND_LINE;
71 params->size = (len + 3) & -4;
72 strcpy((char *)params->data, cmdline);
74 printf(" COMMAND_LINE: tag:0x%04x, size:%u, data:'%s'\n",
75 BP_TAG_COMMAND_LINE, params->size, cmdline);
77 return bp_tag_next(params);
80 static struct bp_tag *setup_ramdisk_tag(struct bp_tag *params,
81 unsigned long rd_start,
86 if (rd_start == rd_end)
89 /* Add a single banked memory */
91 params->id = BP_TAG_INITRD;
92 params->size = sizeof(struct meminfo);
94 mem = (struct meminfo *)params->data;
95 mem->type = MEMORY_TYPE_CONVENTIONAL;
96 mem->start = PHYSADDR(rd_start);
97 mem->end = PHYSADDR(rd_end);
99 printf(" INITRD: tag:0x%x, type:0X%04lx, start:0X%lx, end:0X%lx\n",
100 BP_TAG_INITRD, mem->type, mem->start, mem->end);
102 return bp_tag_next(params);
105 static struct bp_tag *setup_serial_tag(struct bp_tag *params)
107 params->id = BP_TAG_SERIAL_BAUDRATE;
108 params->size = sizeof(unsigned long);
109 params->data[0] = gd->baudrate;
111 printf(" SERIAL_BAUDRATE: tag:0x%04x, size:%u, baudrate:%lu\n",
112 BP_TAG_SERIAL_BAUDRATE, params->size, params->data[0]);
114 return bp_tag_next(params);
117 #ifdef CONFIG_OF_LIBFDT
119 static struct bp_tag *setup_fdt_tag(struct bp_tag *params, void *fdt_start)
121 params->id = BP_TAG_FDT;
122 params->size = sizeof(unsigned long);
123 params->data[0] = (unsigned long)fdt_start;
125 printf(" FDT: tag:0x%04x, size:%u, start:0x%lx\n",
126 BP_TAG_FDT, params->size, params->data[0]);
128 return bp_tag_next(params);
137 int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
139 struct bp_tag *params, *params_start;
140 ulong initrd_start, initrd_end;
141 char *commandline = env_get("bootargs");
143 if (!(flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)))
146 show_boot_progress(15);
148 if (images->rd_start) {
149 initrd_start = images->rd_start;
150 initrd_end = images->rd_end;
156 params_start = (struct bp_tag *)gd->bd->bi_boot_params;
157 params = params_start;
158 params = setup_first_tag(params);
159 params = setup_memory_tag(params);
160 params = setup_commandline_tag(params, commandline);
161 params = setup_serial_tag(params);
164 params = setup_ramdisk_tag(params, initrd_start, initrd_end);
166 #ifdef CONFIG_OF_LIBFDT
168 params = setup_fdt_tag(params, images->ft_addr);
173 params = setup_last_tag(params);
175 show_boot_progress(15);
177 printf("Transferring Control to Linux @0x%08lx ...\n\n",
180 flush_dcache_range((unsigned long)params_start, (unsigned long)params);
182 if (flag & BOOTM_STATE_OS_FAKE_GO)
186 * _start() in vmlinux expects boot params in register a2.
188 * Disable/delete your u-boot breakpoints before stepping into linux.
190 asm volatile ("mov a2, %0\n\t"
192 : : "a" (params_start), "a" (images->ep)
195 /* Does not return */