blob: e635c72709ccd5a19e06a8a8897bcb87ddc7ddfd [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glass3b5866d2014-06-12 07:24:46 -06002/*
3 * (C) Copyright 2000-2009
4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
Simon Glass3b5866d2014-06-12 07:24:46 -06005 */
6
7#include <common.h>
8#include <bootm.h>
Simon Glass1ea97892020-05-10 11:40:00 -06009#include <bootstage.h>
Simon Glass1d91ba72019-11-14 12:57:37 -070010#include <cpu_func.h>
Cristian Ciocaltea6aca5982019-12-24 18:05:39 +020011#include <efi_loader.h>
Simon Glass313112a2019-08-01 09:46:46 -060012#include <env.h>
Simon Glass3b5866d2014-06-12 07:24:46 -060013#include <fdt_support.h>
Simon Glass2dc9c342020-05-10 11:40:01 -060014#include <image.h>
15#include <lmb.h>
Simon Glass0f2af882020-05-10 11:40:05 -060016#include <log.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060017#include <asm/global_data.h>
Masahiro Yamada75f82d02018-03-05 01:20:11 +090018#include <linux/libfdt.h>
Simon Glass3b5866d2014-06-12 07:24:46 -060019#include <malloc.h>
Cristian Ciocaltea6aca5982019-12-24 18:05:39 +020020#include <mapmem.h>
Simon Glass3b5866d2014-06-12 07:24:46 -060021#include <vxworks.h>
Bryan O'Donoghue04ca8152018-03-13 16:50:36 +000022#include <tee/optee.h>
Simon Glass3b5866d2014-06-12 07:24:46 -060023
24DECLARE_GLOBAL_DATA_PTR;
25
Simon Glassed38aef2020-05-10 11:40:03 -060026static int do_bootm_standalone(int flag, int argc, char *const argv[],
Simon Glass3b5866d2014-06-12 07:24:46 -060027 bootm_headers_t *images)
28{
29 char *s;
30 int (*appl)(int, char *const[]);
31
32 /* Don't start if "autostart" is set to "no" */
Simon Glass64b723f2017-08-03 12:22:12 -060033 s = env_get("autostart");
Simon Glass3b5866d2014-06-12 07:24:46 -060034 if ((s != NULL) && !strcmp(s, "no")) {
Simon Glass4d949a22017-08-03 12:22:10 -060035 env_set_hex("filesize", images->os.image_len);
Simon Glass3b5866d2014-06-12 07:24:46 -060036 return 0;
37 }
38 appl = (int (*)(int, char * const []))images->ep;
39 appl(argc, argv);
40 return 0;
41}
42
43/*******************************************************************/
44/* OS booting routines */
45/*******************************************************************/
46
47#if defined(CONFIG_BOOTM_NETBSD) || defined(CONFIG_BOOTM_PLAN9)
Simon Glassed38aef2020-05-10 11:40:03 -060048static void copy_args(char *dest, int argc, char *const argv[], char delim)
Simon Glass3b5866d2014-06-12 07:24:46 -060049{
50 int i;
51
52 for (i = 0; i < argc; i++) {
53 if (i > 0)
54 *dest++ = delim;
55 strcpy(dest, argv[i]);
56 dest += strlen(argv[i]);
57 }
58}
59#endif
60
Simon Glass4a00af42021-09-25 19:43:32 -060061static void __maybe_unused fit_unsupported_reset(const char *msg)
62{
63 if (CONFIG_IS_ENABLED(FIT_VERBOSE)) {
64 printf("! FIT images not supported for '%s' - must reset board to recover!\n",
65 msg);
66 }
67}
68
Simon Glass3b5866d2014-06-12 07:24:46 -060069#ifdef CONFIG_BOOTM_NETBSD
Simon Glassed38aef2020-05-10 11:40:03 -060070static int do_bootm_netbsd(int flag, int argc, char *const argv[],
71 bootm_headers_t *images)
Simon Glass3b5866d2014-06-12 07:24:46 -060072{
Masahiro Yamadaf7ed78b2020-06-26 15:13:33 +090073 void (*loader)(struct bd_info *, image_header_t *, char *, char *);
Simon Glass3b5866d2014-06-12 07:24:46 -060074 image_header_t *os_hdr, *hdr;
75 ulong kernel_data, kernel_len;
Simon Glass3b5866d2014-06-12 07:24:46 -060076 char *cmdline;
77
78 if (flag != BOOTM_STATE_OS_GO)
79 return 0;
80
81#if defined(CONFIG_FIT)
82 if (!images->legacy_hdr_valid) {
83 fit_unsupported_reset("NetBSD");
84 return 1;
85 }
86#endif
87 hdr = images->legacy_hdr_os;
88
89 /*
90 * Booting a (NetBSD) kernel image
91 *
92 * This process is pretty similar to a standalone application:
93 * The (first part of an multi-) image must be a stage-2 loader,
94 * which in turn is responsible for loading & invoking the actual
95 * kernel. The only differences are the parameters being passed:
96 * besides the board info strucure, the loader expects a command
97 * line, the name of the console device, and (optionally) the
98 * address of the original image header.
99 */
100 os_hdr = NULL;
101 if (image_check_type(&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
102 image_multi_getimg(hdr, 1, &kernel_data, &kernel_len);
103 if (kernel_len)
104 os_hdr = hdr;
105 }
106
Simon Glass3b5866d2014-06-12 07:24:46 -0600107 if (argc > 0) {
108 ulong len;
109 int i;
110
111 for (i = 0, len = 0; i < argc; i += 1)
112 len += strlen(argv[i]) + 1;
113 cmdline = malloc(len);
114 copy_args(cmdline, argc, argv, ' ');
115 } else {
Simon Glass64b723f2017-08-03 12:22:12 -0600116 cmdline = env_get("bootargs");
Simon Glass3b5866d2014-06-12 07:24:46 -0600117 if (cmdline == NULL)
118 cmdline = "";
119 }
120
Masahiro Yamadaf7ed78b2020-06-26 15:13:33 +0900121 loader = (void (*)(struct bd_info *, image_header_t *, char *, char *))images->ep;
Simon Glass3b5866d2014-06-12 07:24:46 -0600122
123 printf("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n",
124 (ulong)loader);
125
126 bootstage_mark(BOOTSTAGE_ID_RUN_OS);
127
128 /*
129 * NetBSD Stage-2 Loader Parameters:
130 * arg[0]: pointer to board info data
131 * arg[1]: image load address
132 * arg[2]: char pointer to the console device to use
133 * arg[3]: char pointer to the boot arguments
134 */
Heiko Schocher65d94db2017-06-07 17:33:09 +0200135 (*loader)(gd->bd, os_hdr, "", cmdline);
Simon Glass3b5866d2014-06-12 07:24:46 -0600136
137 return 1;
138}
139#endif /* CONFIG_BOOTM_NETBSD*/
140
Simon Glass3b5866d2014-06-12 07:24:46 -0600141#ifdef CONFIG_BOOTM_RTEMS
Simon Glassed38aef2020-05-10 11:40:03 -0600142static int do_bootm_rtems(int flag, int argc, char *const argv[],
143 bootm_headers_t *images)
Simon Glass3b5866d2014-06-12 07:24:46 -0600144{
Masahiro Yamadaf7ed78b2020-06-26 15:13:33 +0900145 void (*entry_point)(struct bd_info *);
Simon Glass3b5866d2014-06-12 07:24:46 -0600146
147 if (flag != BOOTM_STATE_OS_GO)
148 return 0;
149
150#if defined(CONFIG_FIT)
151 if (!images->legacy_hdr_valid) {
152 fit_unsupported_reset("RTEMS");
153 return 1;
154 }
155#endif
156
Masahiro Yamadaf7ed78b2020-06-26 15:13:33 +0900157 entry_point = (void (*)(struct bd_info *))images->ep;
Simon Glass3b5866d2014-06-12 07:24:46 -0600158
159 printf("## Transferring control to RTEMS (at address %08lx) ...\n",
160 (ulong)entry_point);
161
162 bootstage_mark(BOOTSTAGE_ID_RUN_OS);
163
164 /*
165 * RTEMS Parameters:
166 * r3: ptr to board info data
167 */
168 (*entry_point)(gd->bd);
169
170 return 1;
171}
172#endif /* CONFIG_BOOTM_RTEMS */
173
174#if defined(CONFIG_BOOTM_OSE)
Simon Glassed38aef2020-05-10 11:40:03 -0600175static int do_bootm_ose(int flag, int argc, char *const argv[],
176 bootm_headers_t *images)
Simon Glass3b5866d2014-06-12 07:24:46 -0600177{
178 void (*entry_point)(void);
179
180 if (flag != BOOTM_STATE_OS_GO)
181 return 0;
182
183#if defined(CONFIG_FIT)
184 if (!images->legacy_hdr_valid) {
185 fit_unsupported_reset("OSE");
186 return 1;
187 }
188#endif
189
190 entry_point = (void (*)(void))images->ep;
191
192 printf("## Transferring control to OSE (at address %08lx) ...\n",
193 (ulong)entry_point);
194
195 bootstage_mark(BOOTSTAGE_ID_RUN_OS);
196
197 /*
198 * OSE Parameters:
199 * None
200 */
201 (*entry_point)();
202
203 return 1;
204}
205#endif /* CONFIG_BOOTM_OSE */
206
207#if defined(CONFIG_BOOTM_PLAN9)
Simon Glassed38aef2020-05-10 11:40:03 -0600208static int do_bootm_plan9(int flag, int argc, char *const argv[],
209 bootm_headers_t *images)
Simon Glass3b5866d2014-06-12 07:24:46 -0600210{
211 void (*entry_point)(void);
212 char *s;
213
214 if (flag != BOOTM_STATE_OS_GO)
215 return 0;
216
217#if defined(CONFIG_FIT)
218 if (!images->legacy_hdr_valid) {
219 fit_unsupported_reset("Plan 9");
220 return 1;
221 }
222#endif
223
224 /* See README.plan9 */
Simon Glass64b723f2017-08-03 12:22:12 -0600225 s = env_get("confaddr");
Simon Glass3b5866d2014-06-12 07:24:46 -0600226 if (s != NULL) {
Simon Glass3ff49ec2021-07-24 09:03:29 -0600227 char *confaddr = (char *)hextoul(s, NULL);
Simon Glass3b5866d2014-06-12 07:24:46 -0600228
229 if (argc > 0) {
230 copy_args(confaddr, argc, argv, '\n');
231 } else {
Simon Glass64b723f2017-08-03 12:22:12 -0600232 s = env_get("bootargs");
Simon Glass3b5866d2014-06-12 07:24:46 -0600233 if (s != NULL)
234 strcpy(confaddr, s);
235 }
236 }
237
238 entry_point = (void (*)(void))images->ep;
239
240 printf("## Transferring control to Plan 9 (at address %08lx) ...\n",
241 (ulong)entry_point);
242
243 bootstage_mark(BOOTSTAGE_ID_RUN_OS);
244
245 /*
246 * Plan 9 Parameters:
247 * None
248 */
249 (*entry_point)();
250
251 return 1;
252}
253#endif /* CONFIG_BOOTM_PLAN9 */
254
255#if defined(CONFIG_BOOTM_VXWORKS) && \
256 (defined(CONFIG_PPC) || defined(CONFIG_ARM))
257
Bin Mengb43c3222018-12-21 07:13:39 -0800258static void do_bootvx_fdt(bootm_headers_t *images)
Simon Glass3b5866d2014-06-12 07:24:46 -0600259{
260#if defined(CONFIG_OF_LIBFDT)
261 int ret;
262 char *bootline;
263 ulong of_size = images->ft_len;
264 char **of_flat_tree = &images->ft_addr;
265 struct lmb *lmb = &images->lmb;
266
267 if (*of_flat_tree) {
268 boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
269
270 ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
271 if (ret)
272 return;
273
Hannes Schmelzer51962ee2017-08-25 14:27:37 +0200274 /* Update ethernet nodes */
275 fdt_fixup_ethernet(*of_flat_tree);
276
Simon Glass3b5866d2014-06-12 07:24:46 -0600277 ret = fdt_add_subnode(*of_flat_tree, 0, "chosen");
278 if ((ret >= 0 || ret == -FDT_ERR_EXISTS)) {
Simon Glass64b723f2017-08-03 12:22:12 -0600279 bootline = env_get("bootargs");
Simon Glass3b5866d2014-06-12 07:24:46 -0600280 if (bootline) {
281 ret = fdt_find_and_setprop(*of_flat_tree,
282 "/chosen", "bootargs",
283 bootline,
284 strlen(bootline) + 1, 1);
285 if (ret < 0) {
286 printf("## ERROR: %s : %s\n", __func__,
287 fdt_strerror(ret));
288 return;
289 }
290 }
291 } else {
292 printf("## ERROR: %s : %s\n", __func__,
293 fdt_strerror(ret));
294 return;
295 }
296 }
297#endif
298
299 boot_prep_vxworks(images);
300
301 bootstage_mark(BOOTSTAGE_ID_RUN_OS);
302
303#if defined(CONFIG_OF_LIBFDT)
304 printf("## Starting vxWorks at 0x%08lx, device tree at 0x%08lx ...\n",
305 (ulong)images->ep, (ulong)*of_flat_tree);
306#else
307 printf("## Starting vxWorks at 0x%08lx\n", (ulong)images->ep);
308#endif
309
310 boot_jump_vxworks(images);
311
312 puts("## vxWorks terminated\n");
313}
314
Simon Glassed38aef2020-05-10 11:40:03 -0600315static int do_bootm_vxworks_legacy(int flag, int argc, char *const argv[],
Lihua Zhaodcda76e2019-11-15 00:21:17 -0800316 bootm_headers_t *images)
Simon Glass3b5866d2014-06-12 07:24:46 -0600317{
318 if (flag != BOOTM_STATE_OS_GO)
319 return 0;
320
321#if defined(CONFIG_FIT)
322 if (!images->legacy_hdr_valid) {
323 fit_unsupported_reset("VxWorks");
324 return 1;
325 }
326#endif
327
328 do_bootvx_fdt(images);
329
330 return 1;
331}
Lihua Zhaodcda76e2019-11-15 00:21:17 -0800332
Simon Glassed38aef2020-05-10 11:40:03 -0600333int do_bootm_vxworks(int flag, int argc, char *const argv[],
Lihua Zhaodcda76e2019-11-15 00:21:17 -0800334 bootm_headers_t *images)
335{
336 char *bootargs;
337 int pos;
338 unsigned long vxflags;
339 bool std_dtb = false;
340
341 /* get bootargs env */
342 bootargs = env_get("bootargs");
343
344 if (bootargs != NULL) {
345 for (pos = 0; pos < strlen(bootargs); pos++) {
346 /* find f=0xnumber flag */
347 if ((bootargs[pos] == '=') && (pos >= 1) &&
348 (bootargs[pos - 1] == 'f')) {
Simon Glass3ff49ec2021-07-24 09:03:29 -0600349 vxflags = hextoul(&bootargs[pos + 1], NULL);
Lihua Zhaodcda76e2019-11-15 00:21:17 -0800350 if (vxflags & VXWORKS_SYSFLG_STD_DTB)
351 std_dtb = true;
352 }
353 }
354 }
355
356 if (std_dtb) {
357 if (flag & BOOTM_STATE_OS_PREP)
358 printf(" Using standard DTB\n");
359 return do_bootm_linux(flag, argc, argv, images);
360 } else {
361 if (flag & BOOTM_STATE_OS_PREP)
362 printf(" !!! WARNING !!! Using legacy DTB\n");
363 return do_bootm_vxworks_legacy(flag, argc, argv, images);
364 }
365}
Simon Glass3b5866d2014-06-12 07:24:46 -0600366#endif
367
368#if defined(CONFIG_CMD_ELF)
Simon Glassed38aef2020-05-10 11:40:03 -0600369static int do_bootm_qnxelf(int flag, int argc, char *const argv[],
370 bootm_headers_t *images)
Simon Glass3b5866d2014-06-12 07:24:46 -0600371{
372 char *local_args[2];
373 char str[16];
Emmanuel Vadot9a922b42017-01-19 10:23:56 +0100374 int dcache;
Simon Glass3b5866d2014-06-12 07:24:46 -0600375
376 if (flag != BOOTM_STATE_OS_GO)
377 return 0;
378
379#if defined(CONFIG_FIT)
380 if (!images->legacy_hdr_valid) {
381 fit_unsupported_reset("QNX");
382 return 1;
383 }
384#endif
385
386 sprintf(str, "%lx", images->ep); /* write entry-point into string */
387 local_args[0] = argv[0];
388 local_args[1] = str; /* and provide it via the arguments */
Emmanuel Vadot9a922b42017-01-19 10:23:56 +0100389
390 /*
391 * QNX images require the data cache is disabled.
392 */
393 dcache = dcache_status();
394 if (dcache)
395 dcache_disable();
396
Simon Glass3b5866d2014-06-12 07:24:46 -0600397 do_bootelf(NULL, 0, 2, local_args);
398
Emmanuel Vadot9a922b42017-01-19 10:23:56 +0100399 if (dcache)
400 dcache_enable();
401
Simon Glass3b5866d2014-06-12 07:24:46 -0600402 return 1;
403}
404#endif
405
406#ifdef CONFIG_INTEGRITY
Simon Glassed38aef2020-05-10 11:40:03 -0600407static int do_bootm_integrity(int flag, int argc, char *const argv[],
408 bootm_headers_t *images)
Simon Glass3b5866d2014-06-12 07:24:46 -0600409{
410 void (*entry_point)(void);
411
412 if (flag != BOOTM_STATE_OS_GO)
413 return 0;
414
415#if defined(CONFIG_FIT)
416 if (!images->legacy_hdr_valid) {
417 fit_unsupported_reset("INTEGRITY");
418 return 1;
419 }
420#endif
421
422 entry_point = (void (*)(void))images->ep;
423
424 printf("## Transferring control to INTEGRITY (at address %08lx) ...\n",
425 (ulong)entry_point);
426
427 bootstage_mark(BOOTSTAGE_ID_RUN_OS);
428
429 /*
430 * INTEGRITY Parameters:
431 * None
432 */
433 (*entry_point)();
434
435 return 1;
436}
437#endif
438
Marek Vasut0e3b5122014-12-16 14:07:21 +0100439#ifdef CONFIG_BOOTM_OPENRTOS
Simon Glassed38aef2020-05-10 11:40:03 -0600440static int do_bootm_openrtos(int flag, int argc, char *const argv[],
441 bootm_headers_t *images)
Marek Vasut0e3b5122014-12-16 14:07:21 +0100442{
443 void (*entry_point)(void);
444
445 if (flag != BOOTM_STATE_OS_GO)
446 return 0;
447
448 entry_point = (void (*)(void))images->ep;
449
450 printf("## Transferring control to OpenRTOS (at address %08lx) ...\n",
451 (ulong)entry_point);
452
453 bootstage_mark(BOOTSTAGE_ID_RUN_OS);
454
455 /*
456 * OpenRTOS Parameters:
457 * None
458 */
459 (*entry_point)();
460
461 return 1;
462}
463#endif
464
Bryan O'Donoghue04ca8152018-03-13 16:50:36 +0000465#ifdef CONFIG_BOOTM_OPTEE
Simon Glassed38aef2020-05-10 11:40:03 -0600466static int do_bootm_tee(int flag, int argc, char *const argv[],
Bryan O'Donoghue04ca8152018-03-13 16:50:36 +0000467 bootm_headers_t *images)
468{
469 int ret;
470
471 /* Verify OS type */
472 if (images->os.os != IH_OS_TEE) {
473 return 1;
474 };
475
476 /* Validate OPTEE header */
477 ret = optee_verify_bootm_image(images->os.image_start,
478 images->os.load,
479 images->os.image_len);
480 if (ret)
481 return ret;
482
483 /* Locate FDT etc */
Tero Kristo06086942020-06-12 15:41:20 +0300484 ret = bootm_find_images(flag, argc, argv, 0, 0);
Bryan O'Donoghue04ca8152018-03-13 16:50:36 +0000485 if (ret)
486 return ret;
487
488 /* From here we can run the regular linux boot path */
489 return do_bootm_linux(flag, argc, argv, images);
490}
491#endif
492
Cristian Ciocaltea6aca5982019-12-24 18:05:39 +0200493#ifdef CONFIG_BOOTM_EFI
Simon Glassed38aef2020-05-10 11:40:03 -0600494static int do_bootm_efi(int flag, int argc, char *const argv[],
Cristian Ciocaltea6aca5982019-12-24 18:05:39 +0200495 bootm_headers_t *images)
496{
497 int ret;
498 efi_status_t efi_ret;
499 void *image_buf;
500
501 if (flag != BOOTM_STATE_OS_GO)
502 return 0;
503
504 /* Locate FDT, if provided */
Tero Kristo06086942020-06-12 15:41:20 +0300505 ret = bootm_find_images(flag, argc, argv, 0, 0);
Cristian Ciocaltea6aca5982019-12-24 18:05:39 +0200506 if (ret)
507 return ret;
508
509 /* Initialize EFI drivers */
510 efi_ret = efi_init_obj_list();
511 if (efi_ret != EFI_SUCCESS) {
512 printf("## Failed to initialize UEFI sub-system: r = %lu\n",
513 efi_ret & ~EFI_ERROR_MASK);
514 return 1;
515 }
516
517 /* Install device tree */
518 efi_ret = efi_install_fdt(images->ft_len
519 ? images->ft_addr : EFI_FDT_USE_INTERNAL);
520 if (efi_ret != EFI_SUCCESS) {
521 printf("## Failed to install device tree: r = %lu\n",
522 efi_ret & ~EFI_ERROR_MASK);
523 return 1;
524 }
525
526 /* Run EFI image */
527 printf("## Transferring control to EFI (at address %08lx) ...\n",
528 images->ep);
529 bootstage_mark(BOOTSTAGE_ID_RUN_OS);
530
Heinrich Schuchardtc663fa42020-07-18 10:54:26 +0200531 /* We expect to return */
532 images->os.type = IH_TYPE_STANDALONE;
533
Cristian Ciocaltea6aca5982019-12-24 18:05:39 +0200534 image_buf = map_sysmem(images->ep, images->os.image_len);
535
536 efi_ret = efi_run_image(image_buf, images->os.image_len);
Heinrich Schuchardtc663fa42020-07-18 10:54:26 +0200537 if (efi_ret != EFI_SUCCESS)
Cristian Ciocaltea6aca5982019-12-24 18:05:39 +0200538 return 1;
Cristian Ciocaltea6aca5982019-12-24 18:05:39 +0200539 return 0;
540}
541#endif
542
Simon Glass3b5866d2014-06-12 07:24:46 -0600543static boot_os_fn *boot_os[] = {
544 [IH_OS_U_BOOT] = do_bootm_standalone,
545#ifdef CONFIG_BOOTM_LINUX
546 [IH_OS_LINUX] = do_bootm_linux,
547#endif
548#ifdef CONFIG_BOOTM_NETBSD
549 [IH_OS_NETBSD] = do_bootm_netbsd,
550#endif
Simon Glass3b5866d2014-06-12 07:24:46 -0600551#ifdef CONFIG_BOOTM_RTEMS
552 [IH_OS_RTEMS] = do_bootm_rtems,
553#endif
554#if defined(CONFIG_BOOTM_OSE)
555 [IH_OS_OSE] = do_bootm_ose,
556#endif
557#if defined(CONFIG_BOOTM_PLAN9)
558 [IH_OS_PLAN9] = do_bootm_plan9,
559#endif
560#if defined(CONFIG_BOOTM_VXWORKS) && \
Bin Menge63488f2018-12-21 07:13:41 -0800561 (defined(CONFIG_PPC) || defined(CONFIG_ARM) || defined(CONFIG_RISCV))
Simon Glass3b5866d2014-06-12 07:24:46 -0600562 [IH_OS_VXWORKS] = do_bootm_vxworks,
563#endif
564#if defined(CONFIG_CMD_ELF)
565 [IH_OS_QNX] = do_bootm_qnxelf,
566#endif
567#ifdef CONFIG_INTEGRITY
568 [IH_OS_INTEGRITY] = do_bootm_integrity,
569#endif
Marek Vasut0e3b5122014-12-16 14:07:21 +0100570#ifdef CONFIG_BOOTM_OPENRTOS
571 [IH_OS_OPENRTOS] = do_bootm_openrtos,
572#endif
Bryan O'Donoghue04ca8152018-03-13 16:50:36 +0000573#ifdef CONFIG_BOOTM_OPTEE
574 [IH_OS_TEE] = do_bootm_tee,
575#endif
Cristian Ciocaltea6aca5982019-12-24 18:05:39 +0200576#ifdef CONFIG_BOOTM_EFI
577 [IH_OS_EFI] = do_bootm_efi,
578#endif
Simon Glass3b5866d2014-06-12 07:24:46 -0600579};
580
581/* Allow for arch specific config before we boot */
Jeroen Hofsteef7d4a492014-07-10 23:06:25 +0200582__weak void arch_preboot_os(void)
Simon Glass3b5866d2014-06-12 07:24:46 -0600583{
584 /* please define platform specific arch_preboot_os() */
585}
Simon Glass3b5866d2014-06-12 07:24:46 -0600586
Marek Vasut5b9fbd92018-10-04 21:16:31 +0200587/* Allow for board specific config before we boot */
588__weak void board_preboot_os(void)
589{
590 /* please define board specific board_preboot_os() */
591}
592
Simon Glassed38aef2020-05-10 11:40:03 -0600593int boot_selected_os(int argc, char *const argv[], int state,
Simon Glass3b5866d2014-06-12 07:24:46 -0600594 bootm_headers_t *images, boot_os_fn *boot_fn)
595{
596 arch_preboot_os();
Marek Vasut5b9fbd92018-10-04 21:16:31 +0200597 board_preboot_os();
Simon Glass3b5866d2014-06-12 07:24:46 -0600598 boot_fn(state, argc, argv, images);
599
600 /* Stand-alone may return when 'autostart' is 'no' */
601 if (images->os.type == IH_TYPE_STANDALONE ||
Simon Glass43cdb792016-07-03 09:40:35 -0600602 IS_ENABLED(CONFIG_SANDBOX) ||
Simon Glass3b5866d2014-06-12 07:24:46 -0600603 state == BOOTM_STATE_OS_FAKE_GO) /* We expect to return */
604 return 0;
605 bootstage_error(BOOTSTAGE_ID_BOOT_OS_RETURNED);
Lukasz Majewski9167e102016-05-08 08:52:21 +0200606 debug("\n## Control returned to monitor - resetting...\n");
607
Simon Glass3b5866d2014-06-12 07:24:46 -0600608 return BOOTM_ERR_RESET;
609}
610
611boot_os_fn *bootm_os_get_boot_func(int os)
612{
613#ifdef CONFIG_NEEDS_MANUAL_RELOC
614 static bool relocated;
615
616 if (!relocated) {
617 int i;
618
619 /* relocate boot function table */
620 for (i = 0; i < ARRAY_SIZE(boot_os); i++)
621 if (boot_os[i] != NULL)
622 boot_os[i] += gd->reloc_off;
623
624 relocated = true;
625 }
626#endif
627 return boot_os[os];
628}