xref: /rk3399_rockchip-uboot/arch/nds32/lib/bootm.c (revision f5076f869855045e527de7f1367c65f55a2b1448)
1 /*
2  * Copyright (C) 2011 Andes Technology Corporation
3  * Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com>
4  * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
5  *
6  * SPDX-License-Identifier:	GPL-2.0+
7  */
8 
9 #include <common.h>
10 #include <command.h>
11 #include <image.h>
12 #include <u-boot/zlib.h>
13 #include <asm/byteorder.h>
14 
15 DECLARE_GLOBAL_DATA_PTR;
16 
17 int arch_fixup_fdt(void *blob)
18 {
19 	return 0;
20 }
21 
22 
23 #if defined(CONFIG_SETUP_MEMORY_TAGS) || \
24 	defined(CONFIG_CMDLINE_TAG) || \
25 	defined(CONFIG_INITRD_TAG) || \
26 	defined(CONFIG_SERIAL_TAG) || \
27 	defined(CONFIG_REVISION_TAG)
28 static void setup_start_tag(bd_t *bd);
29 
30 # ifdef CONFIG_SETUP_MEMORY_TAGS
31 static void setup_memory_tags(bd_t *bd);
32 # endif
33 static void setup_commandline_tag(bd_t *bd, char *commandline);
34 
35 # ifdef CONFIG_INITRD_TAG
36 static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong initrd_end);
37 # endif
38 static void setup_end_tag(bd_t *bd);
39 
40 static struct tag *params;
41 #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
42 
43 int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
44 {
45 	bd_t	*bd = gd->bd;
46 	char	*s;
47 	int	machid = bd->bi_arch_number;
48 	void	(*theKernel)(int zero, int arch, uint params);
49 
50 #ifdef CONFIG_CMDLINE_TAG
51 	char *commandline = getenv("bootargs");
52 #endif
53 
54 	/*
55 	 * allow the PREP bootm subcommand, it is required for bootm to work
56 	 */
57 	if (flag & BOOTM_STATE_OS_PREP)
58 		return 0;
59 
60 	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
61 		return 1;
62 
63 	theKernel = (void (*)(int, int, uint))images->ep;
64 
65 	s = getenv("machid");
66 	if (s) {
67 		machid = simple_strtoul(s, NULL, 16);
68 		printf("Using machid 0x%x from environment\n", machid);
69 	}
70 
71 	bootstage_mark(BOOTSTAGE_ID_RUN_OS);
72 
73 	debug("## Transferring control to Linux (at address %08lx) ...\n",
74 	       (ulong)theKernel);
75 
76 #if defined(CONFIG_SETUP_MEMORY_TAGS) || \
77 	defined(CONFIG_CMDLINE_TAG) || \
78 	defined(CONFIG_INITRD_TAG) || \
79 	defined(CONFIG_SERIAL_TAG) || \
80 	defined(CONFIG_REVISION_TAG)
81 	setup_start_tag(bd);
82 #ifdef CONFIG_SERIAL_TAG
83 	setup_serial_tag(&params);
84 #endif
85 #ifdef CONFIG_REVISION_TAG
86 	setup_revision_tag(&params);
87 #endif
88 #ifdef CONFIG_SETUP_MEMORY_TAGS
89 	setup_memory_tags(bd);
90 #endif
91 #ifdef CONFIG_CMDLINE_TAG
92 	setup_commandline_tag(bd, commandline);
93 #endif
94 #ifdef CONFIG_INITRD_TAG
95 	if (images->rd_start && images->rd_end)
96 		setup_initrd_tag(bd, images->rd_start, images->rd_end);
97 #endif
98 	setup_end_tag(bd);
99 #endif
100 
101 	/* we assume that the kernel is in place */
102 	printf("\nStarting kernel ...\n\n");
103 
104 #ifdef CONFIG_USB_DEVICE
105 	{
106 		extern void udc_disconnect(void);
107 		udc_disconnect();
108 	}
109 #endif
110 
111 	cleanup_before_linux();
112 
113 	theKernel(0, machid, bd->bi_boot_params);
114 	/* does not return */
115 
116 	return 1;
117 }
118 
119 
120 #if defined(CONFIG_SETUP_MEMORY_TAGS) || \
121 	defined(CONFIG_CMDLINE_TAG) || \
122 	defined(CONFIG_INITRD_TAG) || \
123 	defined(CONFIG_SERIAL_TAG) || \
124 	defined(CONFIG_REVISION_TAG)
125 static void setup_start_tag(bd_t *bd)
126 {
127 	params = (struct tag *)bd->bi_boot_params;
128 
129 	params->hdr.tag = ATAG_CORE;
130 	params->hdr.size = tag_size(tag_core);
131 
132 	params->u.core.flags = 0;
133 	params->u.core.pagesize = 0;
134 	params->u.core.rootdev = 0;
135 
136 	params = tag_next(params);
137 }
138 
139 
140 #ifdef CONFIG_SETUP_MEMORY_TAGS
141 static void setup_memory_tags(bd_t *bd)
142 {
143 	int i;
144 
145 	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
146 		params->hdr.tag = ATAG_MEM;
147 		params->hdr.size = tag_size(tag_mem32);
148 
149 		params->u.mem.start = bd->bi_dram[i].start;
150 		params->u.mem.size = bd->bi_dram[i].size;
151 
152 		params = tag_next(params);
153 	}
154 }
155 #endif /* CONFIG_SETUP_MEMORY_TAGS */
156 
157 
158 static void setup_commandline_tag(bd_t *bd, char *commandline)
159 {
160 	char *p;
161 
162 	if (!commandline)
163 		return;
164 
165 	/* eat leading white space */
166 	for (p = commandline; *p == ' '; p++)
167 		;
168 
169 	/* skip non-existent command lines so the kernel will still
170 	 * use its default command line.
171 	 */
172 	if (*p == '\0')
173 		return;
174 
175 	params->hdr.tag = ATAG_CMDLINE;
176 	params->hdr.size =
177 		(sizeof(struct tag_header) + strlen(p) + 1 + 4) >> 2;
178 
179 	strcpy(params->u.cmdline.cmdline, p)
180 		;
181 
182 	params = tag_next(params);
183 }
184 
185 
186 #ifdef CONFIG_INITRD_TAG
187 static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong initrd_end)
188 {
189 	/* an ATAG_INITRD node tells the kernel where the compressed
190 	 * ramdisk can be found. ATAG_RDIMG is a better name, actually.
191 	 */
192 	params->hdr.tag = ATAG_INITRD2;
193 	params->hdr.size = tag_size(tag_initrd);
194 
195 	params->u.initrd.start = initrd_start;
196 	params->u.initrd.size = initrd_end - initrd_start;
197 
198 	params = tag_next(params);
199 }
200 #endif /* CONFIG_INITRD_TAG */
201 
202 #ifdef CONFIG_SERIAL_TAG
203 void setup_serial_tag(struct tag **tmp)
204 {
205 	struct tag *params = *tmp;
206 	struct tag_serialnr serialnr;
207 	void get_board_serial(struct tag_serialnr *serialnr);
208 
209 	get_board_serial(&serialnr);
210 	params->hdr.tag = ATAG_SERIAL;
211 	params->hdr.size = tag_size(tag_serialnr);
212 	params->u.serialnr.low = serialnr.low;
213 	params->u.serialnr.high = serialnr.high;
214 	params = tag_next(params);
215 	*tmp = params;
216 }
217 #endif
218 
219 #ifdef CONFIG_REVISION_TAG
220 void setup_revision_tag(struct tag **in_params)
221 {
222 	u32 rev = 0;
223 	u32 get_board_rev(void);
224 
225 	rev = get_board_rev();
226 	params->hdr.tag = ATAG_REVISION;
227 	params->hdr.size = tag_size(tag_revision);
228 	params->u.revision.rev = rev;
229 	params = tag_next(params);
230 }
231 #endif  /* CONFIG_REVISION_TAG */
232 
233 
234 static void setup_end_tag(bd_t *bd)
235 {
236 	params->hdr.tag = ATAG_NONE;
237 	params->hdr.size = 0;
238 }
239 
240 #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
241