1
2
3
4
5
6#include <common.h>
7#include <bootstage.h>
8#include <env.h>
9#include <image.h>
10#include <irq_func.h>
11#include <log.h>
12#include <asm/cache.h>
13#include <asm/global_data.h>
14
15DECLARE_GLOBAL_DATA_PTR;
16
17static int cleanup_before_linux(void)
18{
19 disable_interrupts();
20 sync_n_cleanup_cache_all();
21
22 return 0;
23}
24
25__weak int board_prep_linux(bootm_headers_t *images) { return 0; }
26
27
28static int boot_prep_linux(bootm_headers_t *images)
29{
30 int ret;
31
32 ret = image_setup_linux(images);
33 if (ret)
34 return ret;
35
36 return board_prep_linux(images);
37}
38
39
40__weak void board_jump_and_run(ulong entry, int zero, int arch, uint params)
41{
42 void (*kernel_entry)(int zero, int arch, uint params);
43
44 kernel_entry = (void (*)(int, int, uint))entry;
45
46 kernel_entry(zero, arch, params);
47}
48
49
50static void boot_jump_linux(bootm_headers_t *images, int flag)
51{
52 ulong kernel_entry;
53 unsigned int r0, r2;
54 int fake = (flag & BOOTM_STATE_OS_FAKE_GO);
55
56 kernel_entry = images->ep;
57
58 debug("## Transferring control to Linux (at address %08lx)...\n",
59 kernel_entry);
60 bootstage_mark(BOOTSTAGE_ID_RUN_OS);
61
62 printf("\nStarting kernel ...%s\n\n", fake ?
63 "(fake run for tracing)" : "");
64 bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
65
66 if (CONFIG_IS_ENABLED(OF_LIBFDT) && images->ft_len) {
67 r0 = 2;
68 r2 = (unsigned int)images->ft_addr;
69 } else {
70 r0 = 1;
71 r2 = (unsigned int)env_get("bootargs");
72 }
73
74 cleanup_before_linux();
75
76 if (!fake)
77 board_jump_and_run(kernel_entry, r0, 0, r2);
78}
79
80int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
81{
82
83 if ((flag & BOOTM_STATE_OS_BD_T) || (flag & BOOTM_STATE_OS_CMDLINE))
84 return -1;
85
86 if (flag & BOOTM_STATE_OS_PREP)
87 return boot_prep_linux(images);
88
89 if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) {
90 boot_jump_linux(images, flag);
91 return 0;
92 }
93
94 return -1;
95}
96