]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
8bbb2909 RC |
2 | /* |
3 | * Copyright (C) 2011 Andes Technology Corporation | |
4 | * Shawn Lin, Andes Technology Corporation <[email protected]> | |
5 | * Macpaul Lin, Andes Technology Corporation <[email protected]> | |
6 | * Rick Chen, Andes Technology Corporation <[email protected]> | |
8bbb2909 RC |
7 | */ |
8 | ||
9 | #include <common.h> | |
52f24238 | 10 | #include <bootstage.h> |
8bbb2909 | 11 | #include <command.h> |
c3b1a990 | 12 | #include <dm.h> |
807765b0 | 13 | #include <fdt_support.h> |
db41d65a | 14 | #include <hang.h> |
c3b1a990 | 15 | #include <dm/root.h> |
8bbb2909 | 16 | #include <image.h> |
8bbb2909 | 17 | #include <asm/byteorder.h> |
ed49ba4d | 18 | #include <asm/csr.h> |
f28ad250 | 19 | #include <asm/smp.h> |
b1893a9e BM |
20 | #include <dm/device.h> |
21 | #include <dm/root.h> | |
22 | #include <u-boot/zlib.h> | |
8bbb2909 RC |
23 | |
24 | DECLARE_GLOBAL_DATA_PTR; | |
25 | ||
b66babda AG |
26 | __weak void board_quiesce_devices(void) |
27 | { | |
28 | } | |
29 | ||
c3b1a990 LA |
30 | /** |
31 | * announce_and_cleanup() - Print message and prepare for kernel boot | |
32 | * | |
33 | * @fake: non-zero to do everything except actually boot | |
34 | */ | |
35 | static void announce_and_cleanup(int fake) | |
8bbb2909 | 36 | { |
c3b1a990 LA |
37 | printf("\nStarting kernel ...%s\n\n", fake ? |
38 | "(fake run for tracing)" : ""); | |
39 | bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel"); | |
40 | #ifdef CONFIG_BOOTSTAGE_FDT | |
41 | bootstage_fdt_add_report(); | |
42 | #endif | |
43 | #ifdef CONFIG_BOOTSTAGE_REPORT | |
44 | bootstage_report(); | |
45 | #endif | |
8bbb2909 | 46 | |
c3b1a990 LA |
47 | #ifdef CONFIG_USB_DEVICE |
48 | udc_disconnect(); | |
49 | #endif | |
8bbb2909 | 50 | |
c3b1a990 | 51 | board_quiesce_devices(); |
8bbb2909 | 52 | |
c3b1a990 LA |
53 | /* |
54 | * Call remove function of all devices with a removal flag set. | |
55 | * This may be useful for last-stage operations, like cancelling | |
56 | * of DMA operation or releasing device internal buffers. | |
57 | */ | |
58 | dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL); | |
8bbb2909 | 59 | |
c3b1a990 LA |
60 | cleanup_before_linux(); |
61 | } | |
8bbb2909 | 62 | |
c3b1a990 LA |
63 | static void boot_prep_linux(bootm_headers_t *images) |
64 | { | |
8bbb2909 RC |
65 | if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) { |
66 | #ifdef CONFIG_OF_LIBFDT | |
67 | debug("using: FDT\n"); | |
68 | if (image_setup_linux(images)) { | |
69 | printf("FDT creation failed! hanging..."); | |
70 | hang(); | |
71 | } | |
72 | #endif | |
c3b1a990 LA |
73 | } else { |
74 | printf("Device tree not found or missing FDT support\n"); | |
75 | hang(); | |
22b7e6fb | 76 | } |
c3b1a990 | 77 | } |
8bbb2909 | 78 | |
c3b1a990 LA |
79 | static void boot_jump_linux(bootm_headers_t *images, int flag) |
80 | { | |
81 | void (*kernel)(ulong hart, void *dtb); | |
82 | int fake = (flag & BOOTM_STATE_OS_FAKE_GO); | |
f28ad250 LA |
83 | #ifdef CONFIG_SMP |
84 | int ret; | |
85 | #endif | |
8bbb2909 | 86 | |
c3b1a990 | 87 | kernel = (void (*)(ulong, void *))images->ep; |
b1893a9e | 88 | |
c3b1a990 LA |
89 | bootstage_mark(BOOTSTAGE_ID_RUN_OS); |
90 | ||
08337cd6 | 91 | debug("## Transferring control to kernel (at address %08lx) ...\n", |
c3b1a990 | 92 | (ulong)kernel); |
ed49ba4d | 93 | |
c3b1a990 | 94 | announce_and_cleanup(fake); |
22b7e6fb | 95 | |
c3b1a990 | 96 | if (!fake) { |
f28ad250 LA |
97 | if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) { |
98 | #ifdef CONFIG_SMP | |
99 | ret = smp_call_function(images->ep, | |
90ae2814 | 100 | (ulong)images->ft_addr, 0, 0); |
f28ad250 LA |
101 | if (ret) |
102 | hang(); | |
103 | #endif | |
3c85099a | 104 | kernel(gd->arch.boot_hart, images->ft_addr); |
f28ad250 | 105 | } |
c3b1a990 LA |
106 | } |
107 | } | |
108 | ||
09140113 | 109 | int do_bootm_linux(int flag, int argc, char *const argv[], |
c3b1a990 LA |
110 | bootm_headers_t *images) |
111 | { | |
112 | /* No need for those on RISC-V */ | |
113 | if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE) | |
114 | return -1; | |
8bbb2909 | 115 | |
c3b1a990 LA |
116 | if (flag & BOOTM_STATE_OS_PREP) { |
117 | boot_prep_linux(images); | |
118 | return 0; | |
119 | } | |
120 | ||
121 | if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) { | |
122 | boot_jump_linux(images, flag); | |
123 | return 0; | |
124 | } | |
125 | ||
126 | boot_prep_linux(images); | |
127 | boot_jump_linux(images, flag); | |
128 | return 0; | |
8bbb2909 | 129 | } |
08337cd6 | 130 | |
09140113 | 131 | int do_bootm_vxworks(int flag, int argc, char *const argv[], |
08337cd6 BM |
132 | bootm_headers_t *images) |
133 | { | |
134 | return do_bootm_linux(flag, argc, argv, images); | |
135 | } |