xref: /OK3568_Linux_fs/u-boot/common/bootm_os.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * (C) Copyright 2000-2009
3*4882a593Smuzhiyun  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <common.h>
9*4882a593Smuzhiyun #include <bootm.h>
10*4882a593Smuzhiyun #include <fdt_support.h>
11*4882a593Smuzhiyun #include <linux/libfdt.h>
12*4882a593Smuzhiyun #include <malloc.h>
13*4882a593Smuzhiyun #include <vxworks.h>
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
16*4882a593Smuzhiyun 
do_bootm_standalone(int flag,int argc,char * const argv[],bootm_headers_t * images)17*4882a593Smuzhiyun static int do_bootm_standalone(int flag, int argc, char * const argv[],
18*4882a593Smuzhiyun 			       bootm_headers_t *images)
19*4882a593Smuzhiyun {
20*4882a593Smuzhiyun 	char *s;
21*4882a593Smuzhiyun 	int (*appl)(int, char *const[]);
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun 	/* Don't start if "autostart" is set to "no" */
24*4882a593Smuzhiyun 	s = env_get("autostart");
25*4882a593Smuzhiyun 	if ((s != NULL) && !strcmp(s, "no")) {
26*4882a593Smuzhiyun 		env_set_hex("filesize", images->os.image_len);
27*4882a593Smuzhiyun 		return 0;
28*4882a593Smuzhiyun 	}
29*4882a593Smuzhiyun 	appl = (int (*)(int, char * const []))images->ep;
30*4882a593Smuzhiyun 	appl(argc, argv);
31*4882a593Smuzhiyun 	return 0;
32*4882a593Smuzhiyun }
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun /*******************************************************************/
35*4882a593Smuzhiyun /* OS booting routines */
36*4882a593Smuzhiyun /*******************************************************************/
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun #if defined(CONFIG_BOOTM_NETBSD) || defined(CONFIG_BOOTM_PLAN9)
copy_args(char * dest,int argc,char * const argv[],char delim)39*4882a593Smuzhiyun static void copy_args(char *dest, int argc, char * const argv[], char delim)
40*4882a593Smuzhiyun {
41*4882a593Smuzhiyun 	int i;
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun 	for (i = 0; i < argc; i++) {
44*4882a593Smuzhiyun 		if (i > 0)
45*4882a593Smuzhiyun 			*dest++ = delim;
46*4882a593Smuzhiyun 		strcpy(dest, argv[i]);
47*4882a593Smuzhiyun 		dest += strlen(argv[i]);
48*4882a593Smuzhiyun 	}
49*4882a593Smuzhiyun }
50*4882a593Smuzhiyun #endif
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun #ifdef CONFIG_BOOTM_NETBSD
do_bootm_netbsd(int flag,int argc,char * const argv[],bootm_headers_t * images)53*4882a593Smuzhiyun static int do_bootm_netbsd(int flag, int argc, char * const argv[],
54*4882a593Smuzhiyun 			    bootm_headers_t *images)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun 	void (*loader)(bd_t *, image_header_t *, char *, char *);
57*4882a593Smuzhiyun 	image_header_t *os_hdr, *hdr;
58*4882a593Smuzhiyun 	ulong kernel_data, kernel_len;
59*4882a593Smuzhiyun 	char *cmdline;
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	if (flag != BOOTM_STATE_OS_GO)
62*4882a593Smuzhiyun 		return 0;
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun #if defined(CONFIG_FIT)
65*4882a593Smuzhiyun 	if (!images->legacy_hdr_valid) {
66*4882a593Smuzhiyun 		fit_unsupported_reset("NetBSD");
67*4882a593Smuzhiyun 		return 1;
68*4882a593Smuzhiyun 	}
69*4882a593Smuzhiyun #endif
70*4882a593Smuzhiyun 	hdr = images->legacy_hdr_os;
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 	/*
73*4882a593Smuzhiyun 	 * Booting a (NetBSD) kernel image
74*4882a593Smuzhiyun 	 *
75*4882a593Smuzhiyun 	 * This process is pretty similar to a standalone application:
76*4882a593Smuzhiyun 	 * The (first part of an multi-) image must be a stage-2 loader,
77*4882a593Smuzhiyun 	 * which in turn is responsible for loading & invoking the actual
78*4882a593Smuzhiyun 	 * kernel.  The only differences are the parameters being passed:
79*4882a593Smuzhiyun 	 * besides the board info strucure, the loader expects a command
80*4882a593Smuzhiyun 	 * line, the name of the console device, and (optionally) the
81*4882a593Smuzhiyun 	 * address of the original image header.
82*4882a593Smuzhiyun 	 */
83*4882a593Smuzhiyun 	os_hdr = NULL;
84*4882a593Smuzhiyun 	if (image_check_type(&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
85*4882a593Smuzhiyun 		image_multi_getimg(hdr, 1, &kernel_data, &kernel_len);
86*4882a593Smuzhiyun 		if (kernel_len)
87*4882a593Smuzhiyun 			os_hdr = hdr;
88*4882a593Smuzhiyun 	}
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	if (argc > 0) {
91*4882a593Smuzhiyun 		ulong len;
92*4882a593Smuzhiyun 		int   i;
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 		for (i = 0, len = 0; i < argc; i += 1)
95*4882a593Smuzhiyun 			len += strlen(argv[i]) + 1;
96*4882a593Smuzhiyun 		cmdline = malloc(len);
97*4882a593Smuzhiyun 		copy_args(cmdline, argc, argv, ' ');
98*4882a593Smuzhiyun 	} else {
99*4882a593Smuzhiyun 		cmdline = env_get("bootargs");
100*4882a593Smuzhiyun 		if (cmdline == NULL)
101*4882a593Smuzhiyun 			cmdline = "";
102*4882a593Smuzhiyun 	}
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	loader = (void (*)(bd_t *, image_header_t *, char *, char *))images->ep;
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun 	printf("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n",
107*4882a593Smuzhiyun 	       (ulong)loader);
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun 	bootstage_mark(BOOTSTAGE_ID_RUN_OS);
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 	/*
112*4882a593Smuzhiyun 	 * NetBSD Stage-2 Loader Parameters:
113*4882a593Smuzhiyun 	 *   arg[0]: pointer to board info data
114*4882a593Smuzhiyun 	 *   arg[1]: image load address
115*4882a593Smuzhiyun 	 *   arg[2]: char pointer to the console device to use
116*4882a593Smuzhiyun 	 *   arg[3]: char pointer to the boot arguments
117*4882a593Smuzhiyun 	 */
118*4882a593Smuzhiyun 	(*loader)(gd->bd, os_hdr, "", cmdline);
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	return 1;
121*4882a593Smuzhiyun }
122*4882a593Smuzhiyun #endif /* CONFIG_BOOTM_NETBSD*/
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun #ifdef CONFIG_LYNXKDI
do_bootm_lynxkdi(int flag,int argc,char * const argv[],bootm_headers_t * images)125*4882a593Smuzhiyun static int do_bootm_lynxkdi(int flag, int argc, char * const argv[],
126*4882a593Smuzhiyun 			     bootm_headers_t *images)
127*4882a593Smuzhiyun {
128*4882a593Smuzhiyun 	image_header_t *hdr = &images->legacy_hdr_os_copy;
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	if (flag != BOOTM_STATE_OS_GO)
131*4882a593Smuzhiyun 		return 0;
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun #if defined(CONFIG_FIT)
134*4882a593Smuzhiyun 	if (!images->legacy_hdr_valid) {
135*4882a593Smuzhiyun 		fit_unsupported_reset("Lynx");
136*4882a593Smuzhiyun 		return 1;
137*4882a593Smuzhiyun 	}
138*4882a593Smuzhiyun #endif
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 	lynxkdi_boot((image_header_t *)hdr);
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	return 1;
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun #endif /* CONFIG_LYNXKDI */
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun #ifdef CONFIG_BOOTM_RTEMS
do_bootm_rtems(int flag,int argc,char * const argv[],bootm_headers_t * images)147*4882a593Smuzhiyun static int do_bootm_rtems(int flag, int argc, char * const argv[],
148*4882a593Smuzhiyun 			   bootm_headers_t *images)
149*4882a593Smuzhiyun {
150*4882a593Smuzhiyun 	void (*entry_point)(bd_t *);
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	if (flag != BOOTM_STATE_OS_GO)
153*4882a593Smuzhiyun 		return 0;
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun #if defined(CONFIG_FIT)
156*4882a593Smuzhiyun 	if (!images->legacy_hdr_valid) {
157*4882a593Smuzhiyun 		fit_unsupported_reset("RTEMS");
158*4882a593Smuzhiyun 		return 1;
159*4882a593Smuzhiyun 	}
160*4882a593Smuzhiyun #endif
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 	entry_point = (void (*)(bd_t *))images->ep;
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun 	printf("## Transferring control to RTEMS (at address %08lx) ...\n",
165*4882a593Smuzhiyun 	       (ulong)entry_point);
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	bootstage_mark(BOOTSTAGE_ID_RUN_OS);
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	/*
170*4882a593Smuzhiyun 	 * RTEMS Parameters:
171*4882a593Smuzhiyun 	 *   r3: ptr to board info data
172*4882a593Smuzhiyun 	 */
173*4882a593Smuzhiyun 	(*entry_point)(gd->bd);
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	return 1;
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun #endif /* CONFIG_BOOTM_RTEMS */
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun #if defined(CONFIG_BOOTM_OSE)
do_bootm_ose(int flag,int argc,char * const argv[],bootm_headers_t * images)180*4882a593Smuzhiyun static int do_bootm_ose(int flag, int argc, char * const argv[],
181*4882a593Smuzhiyun 			   bootm_headers_t *images)
182*4882a593Smuzhiyun {
183*4882a593Smuzhiyun 	void (*entry_point)(void);
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	if (flag != BOOTM_STATE_OS_GO)
186*4882a593Smuzhiyun 		return 0;
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun #if defined(CONFIG_FIT)
189*4882a593Smuzhiyun 	if (!images->legacy_hdr_valid) {
190*4882a593Smuzhiyun 		fit_unsupported_reset("OSE");
191*4882a593Smuzhiyun 		return 1;
192*4882a593Smuzhiyun 	}
193*4882a593Smuzhiyun #endif
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun 	entry_point = (void (*)(void))images->ep;
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	printf("## Transferring control to OSE (at address %08lx) ...\n",
198*4882a593Smuzhiyun 	       (ulong)entry_point);
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	bootstage_mark(BOOTSTAGE_ID_RUN_OS);
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 	/*
203*4882a593Smuzhiyun 	 * OSE Parameters:
204*4882a593Smuzhiyun 	 *   None
205*4882a593Smuzhiyun 	 */
206*4882a593Smuzhiyun 	(*entry_point)();
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 	return 1;
209*4882a593Smuzhiyun }
210*4882a593Smuzhiyun #endif /* CONFIG_BOOTM_OSE */
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun #if defined(CONFIG_BOOTM_PLAN9)
do_bootm_plan9(int flag,int argc,char * const argv[],bootm_headers_t * images)213*4882a593Smuzhiyun static int do_bootm_plan9(int flag, int argc, char * const argv[],
214*4882a593Smuzhiyun 			   bootm_headers_t *images)
215*4882a593Smuzhiyun {
216*4882a593Smuzhiyun 	void (*entry_point)(void);
217*4882a593Smuzhiyun 	char *s;
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	if (flag != BOOTM_STATE_OS_GO)
220*4882a593Smuzhiyun 		return 0;
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun #if defined(CONFIG_FIT)
223*4882a593Smuzhiyun 	if (!images->legacy_hdr_valid) {
224*4882a593Smuzhiyun 		fit_unsupported_reset("Plan 9");
225*4882a593Smuzhiyun 		return 1;
226*4882a593Smuzhiyun 	}
227*4882a593Smuzhiyun #endif
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	/* See README.plan9 */
230*4882a593Smuzhiyun 	s = env_get("confaddr");
231*4882a593Smuzhiyun 	if (s != NULL) {
232*4882a593Smuzhiyun 		char *confaddr = (char *)simple_strtoul(s, NULL, 16);
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 		if (argc > 0) {
235*4882a593Smuzhiyun 			copy_args(confaddr, argc, argv, '\n');
236*4882a593Smuzhiyun 		} else {
237*4882a593Smuzhiyun 			s = env_get("bootargs");
238*4882a593Smuzhiyun 			if (s != NULL)
239*4882a593Smuzhiyun 				strcpy(confaddr, s);
240*4882a593Smuzhiyun 		}
241*4882a593Smuzhiyun 	}
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun 	entry_point = (void (*)(void))images->ep;
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	printf("## Transferring control to Plan 9 (at address %08lx) ...\n",
246*4882a593Smuzhiyun 	       (ulong)entry_point);
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	bootstage_mark(BOOTSTAGE_ID_RUN_OS);
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	/*
251*4882a593Smuzhiyun 	 * Plan 9 Parameters:
252*4882a593Smuzhiyun 	 *   None
253*4882a593Smuzhiyun 	 */
254*4882a593Smuzhiyun 	(*entry_point)();
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	return 1;
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun #endif /* CONFIG_BOOTM_PLAN9 */
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun #if defined(CONFIG_BOOTM_VXWORKS) && \
261*4882a593Smuzhiyun 	(defined(CONFIG_PPC) || defined(CONFIG_ARM))
262*4882a593Smuzhiyun 
do_bootvx_fdt(bootm_headers_t * images)263*4882a593Smuzhiyun void do_bootvx_fdt(bootm_headers_t *images)
264*4882a593Smuzhiyun {
265*4882a593Smuzhiyun #if defined(CONFIG_OF_LIBFDT)
266*4882a593Smuzhiyun 	int ret;
267*4882a593Smuzhiyun 	char *bootline;
268*4882a593Smuzhiyun 	ulong of_size = images->ft_len;
269*4882a593Smuzhiyun 	char **of_flat_tree = &images->ft_addr;
270*4882a593Smuzhiyun 	struct lmb *lmb = &images->lmb;
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	if (*of_flat_tree) {
273*4882a593Smuzhiyun 		boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun 		ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
276*4882a593Smuzhiyun 		if (ret)
277*4882a593Smuzhiyun 			return;
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun 		/* Update ethernet nodes */
280*4882a593Smuzhiyun 		fdt_fixup_ethernet(*of_flat_tree);
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun 		ret = fdt_add_subnode(*of_flat_tree, 0, "chosen");
283*4882a593Smuzhiyun 		if ((ret >= 0 || ret == -FDT_ERR_EXISTS)) {
284*4882a593Smuzhiyun 			bootline = env_get("bootargs");
285*4882a593Smuzhiyun 			if (bootline) {
286*4882a593Smuzhiyun 				ret = fdt_find_and_setprop(*of_flat_tree,
287*4882a593Smuzhiyun 						"/chosen", "bootargs",
288*4882a593Smuzhiyun 						bootline,
289*4882a593Smuzhiyun 						strlen(bootline) + 1, 1);
290*4882a593Smuzhiyun 				if (ret < 0) {
291*4882a593Smuzhiyun 					printf("## ERROR: %s : %s\n", __func__,
292*4882a593Smuzhiyun 					       fdt_strerror(ret));
293*4882a593Smuzhiyun 					return;
294*4882a593Smuzhiyun 				}
295*4882a593Smuzhiyun 			}
296*4882a593Smuzhiyun 		} else {
297*4882a593Smuzhiyun 			printf("## ERROR: %s : %s\n", __func__,
298*4882a593Smuzhiyun 			       fdt_strerror(ret));
299*4882a593Smuzhiyun 			return;
300*4882a593Smuzhiyun 		}
301*4882a593Smuzhiyun 	}
302*4882a593Smuzhiyun #endif
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun 	boot_prep_vxworks(images);
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 	bootstage_mark(BOOTSTAGE_ID_RUN_OS);
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun #if defined(CONFIG_OF_LIBFDT)
309*4882a593Smuzhiyun 	printf("## Starting vxWorks at 0x%08lx, device tree at 0x%08lx ...\n",
310*4882a593Smuzhiyun 	       (ulong)images->ep, (ulong)*of_flat_tree);
311*4882a593Smuzhiyun #else
312*4882a593Smuzhiyun 	printf("## Starting vxWorks at 0x%08lx\n", (ulong)images->ep);
313*4882a593Smuzhiyun #endif
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 	boot_jump_vxworks(images);
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 	puts("## vxWorks terminated\n");
318*4882a593Smuzhiyun }
319*4882a593Smuzhiyun 
do_bootm_vxworks(int flag,int argc,char * const argv[],bootm_headers_t * images)320*4882a593Smuzhiyun static int do_bootm_vxworks(int flag, int argc, char * const argv[],
321*4882a593Smuzhiyun 			     bootm_headers_t *images)
322*4882a593Smuzhiyun {
323*4882a593Smuzhiyun 	if (flag != BOOTM_STATE_OS_GO)
324*4882a593Smuzhiyun 		return 0;
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun #if defined(CONFIG_FIT)
327*4882a593Smuzhiyun 	if (!images->legacy_hdr_valid) {
328*4882a593Smuzhiyun 		fit_unsupported_reset("VxWorks");
329*4882a593Smuzhiyun 		return 1;
330*4882a593Smuzhiyun 	}
331*4882a593Smuzhiyun #endif
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 	do_bootvx_fdt(images);
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun 	return 1;
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun #endif
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun #if defined(CONFIG_CMD_ELF)
do_bootm_qnxelf(int flag,int argc,char * const argv[],bootm_headers_t * images)340*4882a593Smuzhiyun static int do_bootm_qnxelf(int flag, int argc, char * const argv[],
341*4882a593Smuzhiyun 			    bootm_headers_t *images)
342*4882a593Smuzhiyun {
343*4882a593Smuzhiyun 	char *local_args[2];
344*4882a593Smuzhiyun 	char str[16];
345*4882a593Smuzhiyun 	int dcache;
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 	if (flag != BOOTM_STATE_OS_GO)
348*4882a593Smuzhiyun 		return 0;
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun #if defined(CONFIG_FIT)
351*4882a593Smuzhiyun 	if (!images->legacy_hdr_valid) {
352*4882a593Smuzhiyun 		fit_unsupported_reset("QNX");
353*4882a593Smuzhiyun 		return 1;
354*4882a593Smuzhiyun 	}
355*4882a593Smuzhiyun #endif
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun 	sprintf(str, "%lx", images->ep); /* write entry-point into string */
358*4882a593Smuzhiyun 	local_args[0] = argv[0];
359*4882a593Smuzhiyun 	local_args[1] = str;	/* and provide it via the arguments */
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun 	/*
362*4882a593Smuzhiyun 	 * QNX images require the data cache is disabled.
363*4882a593Smuzhiyun 	 */
364*4882a593Smuzhiyun 	dcache = dcache_status();
365*4882a593Smuzhiyun 	if (dcache)
366*4882a593Smuzhiyun 		dcache_disable();
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun 	do_bootelf(NULL, 0, 2, local_args);
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun 	if (dcache)
371*4882a593Smuzhiyun 		dcache_enable();
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 	return 1;
374*4882a593Smuzhiyun }
375*4882a593Smuzhiyun #endif
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun #ifdef CONFIG_INTEGRITY
do_bootm_integrity(int flag,int argc,char * const argv[],bootm_headers_t * images)378*4882a593Smuzhiyun static int do_bootm_integrity(int flag, int argc, char * const argv[],
379*4882a593Smuzhiyun 			   bootm_headers_t *images)
380*4882a593Smuzhiyun {
381*4882a593Smuzhiyun 	void (*entry_point)(void);
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 	if (flag != BOOTM_STATE_OS_GO)
384*4882a593Smuzhiyun 		return 0;
385*4882a593Smuzhiyun 
386*4882a593Smuzhiyun #if defined(CONFIG_FIT)
387*4882a593Smuzhiyun 	if (!images->legacy_hdr_valid) {
388*4882a593Smuzhiyun 		fit_unsupported_reset("INTEGRITY");
389*4882a593Smuzhiyun 		return 1;
390*4882a593Smuzhiyun 	}
391*4882a593Smuzhiyun #endif
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun 	entry_point = (void (*)(void))images->ep;
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun 	printf("## Transferring control to INTEGRITY (at address %08lx) ...\n",
396*4882a593Smuzhiyun 	       (ulong)entry_point);
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun 	bootstage_mark(BOOTSTAGE_ID_RUN_OS);
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun 	/*
401*4882a593Smuzhiyun 	 * INTEGRITY Parameters:
402*4882a593Smuzhiyun 	 *   None
403*4882a593Smuzhiyun 	 */
404*4882a593Smuzhiyun 	(*entry_point)();
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun 	return 1;
407*4882a593Smuzhiyun }
408*4882a593Smuzhiyun #endif
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun #ifdef CONFIG_BOOTM_OPENRTOS
do_bootm_openrtos(int flag,int argc,char * const argv[],bootm_headers_t * images)411*4882a593Smuzhiyun static int do_bootm_openrtos(int flag, int argc, char * const argv[],
412*4882a593Smuzhiyun 			   bootm_headers_t *images)
413*4882a593Smuzhiyun {
414*4882a593Smuzhiyun 	void (*entry_point)(void);
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun 	if (flag != BOOTM_STATE_OS_GO)
417*4882a593Smuzhiyun 		return 0;
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun 	entry_point = (void (*)(void))images->ep;
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	printf("## Transferring control to OpenRTOS (at address %08lx) ...\n",
422*4882a593Smuzhiyun 		(ulong)entry_point);
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 	bootstage_mark(BOOTSTAGE_ID_RUN_OS);
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun 	/*
427*4882a593Smuzhiyun 	 * OpenRTOS Parameters:
428*4882a593Smuzhiyun 	 *   None
429*4882a593Smuzhiyun 	 */
430*4882a593Smuzhiyun 	(*entry_point)();
431*4882a593Smuzhiyun 
432*4882a593Smuzhiyun 	return 1;
433*4882a593Smuzhiyun }
434*4882a593Smuzhiyun #endif
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun static boot_os_fn *boot_os[] = {
437*4882a593Smuzhiyun 	[IH_OS_U_BOOT] = do_bootm_standalone,
438*4882a593Smuzhiyun #ifdef CONFIG_BOOTM_LINUX
439*4882a593Smuzhiyun 	[IH_OS_LINUX] = do_bootm_linux,
440*4882a593Smuzhiyun #endif
441*4882a593Smuzhiyun #ifdef CONFIG_BOOTM_NETBSD
442*4882a593Smuzhiyun 	[IH_OS_NETBSD] = do_bootm_netbsd,
443*4882a593Smuzhiyun #endif
444*4882a593Smuzhiyun #ifdef CONFIG_LYNXKDI
445*4882a593Smuzhiyun 	[IH_OS_LYNXOS] = do_bootm_lynxkdi,
446*4882a593Smuzhiyun #endif
447*4882a593Smuzhiyun #ifdef CONFIG_BOOTM_RTEMS
448*4882a593Smuzhiyun 	[IH_OS_RTEMS] = do_bootm_rtems,
449*4882a593Smuzhiyun #endif
450*4882a593Smuzhiyun #if defined(CONFIG_BOOTM_OSE)
451*4882a593Smuzhiyun 	[IH_OS_OSE] = do_bootm_ose,
452*4882a593Smuzhiyun #endif
453*4882a593Smuzhiyun #if defined(CONFIG_BOOTM_PLAN9)
454*4882a593Smuzhiyun 	[IH_OS_PLAN9] = do_bootm_plan9,
455*4882a593Smuzhiyun #endif
456*4882a593Smuzhiyun #if defined(CONFIG_BOOTM_VXWORKS) && \
457*4882a593Smuzhiyun 	(defined(CONFIG_PPC) || defined(CONFIG_ARM))
458*4882a593Smuzhiyun 	[IH_OS_VXWORKS] = do_bootm_vxworks,
459*4882a593Smuzhiyun #endif
460*4882a593Smuzhiyun #if defined(CONFIG_CMD_ELF)
461*4882a593Smuzhiyun 	[IH_OS_QNX] = do_bootm_qnxelf,
462*4882a593Smuzhiyun #endif
463*4882a593Smuzhiyun #ifdef CONFIG_INTEGRITY
464*4882a593Smuzhiyun 	[IH_OS_INTEGRITY] = do_bootm_integrity,
465*4882a593Smuzhiyun #endif
466*4882a593Smuzhiyun #ifdef CONFIG_BOOTM_OPENRTOS
467*4882a593Smuzhiyun 	[IH_OS_OPENRTOS] = do_bootm_openrtos,
468*4882a593Smuzhiyun #endif
469*4882a593Smuzhiyun };
470*4882a593Smuzhiyun 
471*4882a593Smuzhiyun /* Allow for arch specific config before we boot */
arch_preboot_os(uint32_t bootm_state,bootm_headers_t * images)472*4882a593Smuzhiyun __weak void arch_preboot_os(uint32_t bootm_state, bootm_headers_t *images)
473*4882a593Smuzhiyun {
474*4882a593Smuzhiyun 	/* please define platform specific arch_preboot_os() */
475*4882a593Smuzhiyun }
476*4882a593Smuzhiyun 
boot_selected_os(int argc,char * const argv[],int state,bootm_headers_t * images,boot_os_fn * boot_fn)477*4882a593Smuzhiyun int boot_selected_os(int argc, char * const argv[], int state,
478*4882a593Smuzhiyun 		     bootm_headers_t *images, boot_os_fn *boot_fn)
479*4882a593Smuzhiyun {
480*4882a593Smuzhiyun 	arch_preboot_os(state, images);
481*4882a593Smuzhiyun 	boot_fn(state, argc, argv, images);
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun 	/* Stand-alone may return when 'autostart' is 'no' */
484*4882a593Smuzhiyun 	if (images->os.type == IH_TYPE_STANDALONE ||
485*4882a593Smuzhiyun 	    IS_ENABLED(CONFIG_SANDBOX) ||
486*4882a593Smuzhiyun 	    state == BOOTM_STATE_OS_FAKE_GO) /* We expect to return */
487*4882a593Smuzhiyun 		return 0;
488*4882a593Smuzhiyun 	bootstage_error(BOOTSTAGE_ID_BOOT_OS_RETURNED);
489*4882a593Smuzhiyun 	debug("\n## Control returned to monitor - resetting...\n");
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun 	return BOOTM_ERR_RESET;
492*4882a593Smuzhiyun }
493*4882a593Smuzhiyun 
bootm_os_get_boot_func(int os)494*4882a593Smuzhiyun boot_os_fn *bootm_os_get_boot_func(int os)
495*4882a593Smuzhiyun {
496*4882a593Smuzhiyun #ifdef CONFIG_NEEDS_MANUAL_RELOC
497*4882a593Smuzhiyun 	static bool relocated;
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun 	if (!relocated) {
500*4882a593Smuzhiyun 		int i;
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun 		/* relocate boot function table */
503*4882a593Smuzhiyun 		for (i = 0; i < ARRAY_SIZE(boot_os); i++)
504*4882a593Smuzhiyun 			if (boot_os[i] != NULL)
505*4882a593Smuzhiyun 				boot_os[i] += gd->reloc_off;
506*4882a593Smuzhiyun 
507*4882a593Smuzhiyun 		relocated = true;
508*4882a593Smuzhiyun 	}
509*4882a593Smuzhiyun #endif
510*4882a593Smuzhiyun 	return boot_os[os];
511*4882a593Smuzhiyun }
512