1
2
3
4
5
6
7#include <common.h>
8#include <bootstage.h>
9#include <command.h>
10#include <env.h>
11#include <image.h>
12#include <lmb.h>
13#include <log.h>
14#include <asm/global_data.h>
15#include <u-boot/zlib.h>
16#include <bzlib.h>
17#include <watchdog.h>
18#include <asm/byteorder.h>
19#ifdef CONFIG_SHOW_BOOT_PROGRESS
20# include <status_led.h>
21#endif
22
23DECLARE_GLOBAL_DATA_PTR;
24
25#define PHYSADDR(x) x
26
27#define LINUX_MAX_ENVS 256
28#define LINUX_MAX_ARGS 256
29
30static ulong get_sp (void);
31static void set_clocks_in_mhz (struct bd_info *kbd);
32
33void arch_lmb_reserve(struct lmb *lmb)
34{
35 ulong sp;
36
37
38
39
40
41
42
43
44
45
46 sp = get_sp();
47 debug ("## Current stack ends at 0x%08lx ", sp);
48
49
50 sp -= 1024;
51 lmb_reserve(lmb, sp, (CONFIG_SYS_SDRAM_BASE + gd->ram_size - sp));
52}
53
54int do_bootm_linux(int flag, int argc, char *const argv[],
55 bootm_headers_t *images)
56{
57 int ret;
58 struct bd_info *kbd;
59 void (*kernel) (struct bd_info *, ulong, ulong, ulong, ulong);
60 struct lmb *lmb = &images->lmb;
61
62
63
64
65 if (flag & BOOTM_STATE_OS_PREP)
66 return 0;
67
68 if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
69 return 1;
70
71
72 ret = boot_get_kbd (lmb, &kbd);
73 if (ret) {
74 puts("ERROR with allocation of kernel bd\n");
75 goto error;
76 }
77 set_clocks_in_mhz(kbd);
78
79 ret = image_setup_linux(images);
80 if (ret)
81 goto error;
82
83 kernel = (void (*)(struct bd_info *, ulong, ulong, ulong, ulong))images->ep;
84
85 debug("## Transferring control to Linux (at address %08lx) ...\n",
86 (ulong) kernel);
87
88 bootstage_mark(BOOTSTAGE_ID_RUN_OS);
89
90
91
92
93
94
95
96
97
98
99 (*kernel)(kbd, images->initrd_start, images->initrd_end,
100 images->cmdline_start, images->cmdline_end);
101
102error:
103 return 1;
104}
105
106static ulong get_sp (void)
107{
108 ulong sp;
109
110 asm("movel %%a7, %%d0\n"
111 "movel %%d0, %0\n": "=d"(sp): :"%d0");
112
113 return sp;
114}
115
116static void set_clocks_in_mhz (struct bd_info *kbd)
117{
118 char *s;
119
120 s = env_get("clocks_in_mhz");
121 if (s) {
122
123 kbd->bi_intfreq /= 1000000L;
124 kbd->bi_busfreq /= 1000000L;
125 }
126}
127